2009-10-19 2 views
27

PHP руководство suggests к классам автозагрузки, какПреобразовать CamelCase для under_score_case в PHP __autoload()

function __autoload($class_name){ 
require_once("some_dir/".$class_name.".php"); 
} 

и этот подход работает отлично, чтобы загрузить класс FooClass сохраненный в файле my_dir/FooClass.php как

class FooClass{ 
    //some implementation 
} 

Вопрос

Как я могу использовать _autoload() функция и доступ FooClass сохранены в файле my_dir/foo_class.php?

ответ

68

Вы можете преобразовать имя класса, как это ...

function __autoload($class_name){ 
    $name = strtolower(preg_replace('/([a-z])([A-Z])/', '$1_$2', $class_name)); 
    require_once("some_dir/".$name.".php"); 
} 
+0

У этого не было проблем с именем класса, например * myClassName *? –

+0

Спасибо за ответ rikh, твоя магия работает! @cballou, код работает и в вашем случае. Я тестировал его на следующих именах классов: FooClass, fooClass, myFooClass и MyFooClass. –

+0

@cballou, nope, каждый раз, когда есть строчная буква, за которой следует буква верхнего регистра, между ними вставлен символ подчеркивания. Наконец, вызов strtolower сделан для обеспечения того, чтобы окончательное имя было в нижнем регистре. –

2

Это непроверенное, но я использовал нечто подобное раньше, чтобы преобразовать имя класса. Я могу добавить, что моя функция также работает в O (n) и не полагается на медленное обратное обращение.

// lowercase first letter 
$class_name[0] = strtolower($class_name[0]); 

$len = strlen($class_name); 
for ($i = 0; $i < $len; ++$i) { 
    // see if we have an uppercase character and replace 
    if (ord($class_name[$i]) > 64 && ord($class_name[$i]) < 91) { 
     $class_name[$i] = '_' . strtolower($class_name[$i]); 
     // increase length of class and position 
     ++$len; 
     ++$i; 
    } 
} 

return $class_name; 
+1

Было бы чище, если бы вы избавились от магических чисел и использовали что-то ближе: if (ord ($ class_name [$ i])> = ord ('A ') && ord ($ class_name [$ i]) <= ord (' Z ')) { –

+1

Это правда, однако я пошел на оптимизацию, так как еще два вызова ** ord() ** в цикле были бы немного чрезмерная ИМО. –

+0

$ class_name [$ i] = '_'. strtolower ($ имя_класса [$ я]); // КАКИЕ ? –