Лучшее решение для __autoload - PullRequest
       24

Лучшее решение для __autoload

10 голосов
/ 11 декабря 2008

Поскольку наше приложение PHP5 OO росло (как по размеру, так и по трафику), мы решили пересмотреть стратегию __autoload ().

Мы всегда называем файл в соответствии с определением класса, которое он содержит, поэтому класс Customer будет содержаться в Customer.php. Мы использовали список каталогов, в которых файл может потенциально существовать, пока не был найден правильный файл .php.

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

Решения, которые приходят мне в голову ...

- использовать соглашение об именах, которое определяет имя каталога (аналогично PEAR). Недостатки: не слишком большой масштаб, приводящий к ужасным именам классов.

- получите какой-то заранее созданный массив локаций (propel делает это для своей __autoload). Недостаток: требуется пересборка перед любым развертыванием нового кода.

-создание массива "на лету" и его кеширование. Это, кажется, лучшее решение, так как оно учитывает любые имена классов и структуру каталогов, которые вы хотите, и является полностью гибким в том, что новые файлы просто добавляются в список. Проблемы заключаются в следующем: где его хранить и что делать с удаленными / перемещенными файлами. В качестве хранилища мы выбрали APC, так как он не требует дополнительных затрат ввода-вывода. Что касается удаления файлов, это не имеет значения, так как вы, вероятно, не хотите их нигде в любом случае. Что касается ходов ... это не решено (мы игнорируем это, поскольку исторически это случалось не очень часто для нас).

Есть ли другие решения?

Ответы [ 11 ]

0 голосов
/ 11 декабря 2008

CodeIgniter делает нечто подобное с функцией load_class. Если я правильно помню, это статическая функция, которая содержит массив объектов. Вызов функции:


 load_class($class_name, $instansiate);

так в вашем случае


 load_class('Customer', TRUE);

и это приведет к загрузке экземпляра класса Customer в массив объектов.

Функция была довольно простой. Извините, я не могу вспомнить название класса, в котором он был. Но я помню, что было загружено несколько классов, таких как, я думаю, класс Routing, класс Benchmark и URI.

...