В тему объединения PHP-классов в Zend Framework'е (и других, следующих таким же соглашениям наименования и размещения) публикую свое решение, реализующее __autoload с накопительной сборкой автозагружаемых классов.
В нем учтены две известные проблемы:
Решение базируется на примере реализации __autoload из книги Дмитрия Котерова по PHP5 и идее описанной тут.
Применяется все это таким образом:
1. Где-то в начале работы скрипта, но после инициализации путей к библиотекам (set_include_path(...)) добавляем:
2. Где-то при завершении работы скрипта (можно и в register_shutdown_function поместить, но я так не пробовал) добавляем:
Конечно же, чтобы все это заработало нужно предварительно в Zend Framework'е вырезать все require|include
Я использую для этого такой прием:
Для сброса кеша нужно просто удалить All.php, создастся новый и он будет расти пока пользователи не обойдут все «закоулки» сайта. Однако, тут я иногда встречаю одну проблему: из-за частого изменения (в процессе роста) All.php FastCGI-процессы начинают сильно грузить систему, поэтому после удаления иногда приходится перегружать FastCGI-процессы вручную.
В случае, если были автозагружены какие-либо новые файлы алгоритм работы метода compileTo заключается в следующем:
autoload.zip (6 Кб)
В нем учтены две известные проблемы:
- В файлах содержащих переменную __FILE__ осуществляется подстановка этой переменной.
- Обрабатывается случай параллельного выполнения скриптов.
Решение базируется на примере реализации __autoload из книги Дмитрия Котерова по PHP5 и идее описанной тут.
Применение
Применяется все это таким образом:
1. Где-то в начале работы скрипта, но после инициализации путей к библиотекам (set_include_path(...)) добавляем:
require_once "My/NameScheme/Autoload.php";
if (@fopen('All.php', 'r', true)) {
include_once('All.php');
}
2. Где-то при завершении работы скрипта (можно и в register_shutdown_function поместить, но я так не пробовал) добавляем:
My_NameScheme_Autoload::compileTo(APP_ROOT . '/includes/All.php'); //где путь к файлу должен быть актуальным для вашего случая
Конечно же, чтобы все это заработало нужно предварительно в Zend Framework'е вырезать все require|include
Я использую для этого такой прием:
$file = preg_replace('/((?:require|include)_once\s*\(?[\'"]Zend\/(.*)[\'"]\)?\s*;)/smiU', '//*** $1', $file);
Для сброса кеша нужно просто удалить All.php, создастся новый и он будет расти пока пользователи не обойдут все «закоулки» сайта. Однако, тут я иногда встречаю одну проблему: из-за частого изменения (в процессе роста) All.php FastCGI-процессы начинают сильно грузить систему, поэтому после удаления иногда приходится перегружать FastCGI-процессы вручную.
Алгоритм
В случае, если были автозагружены какие-либо новые файлы алгоритм работы метода compileTo заключается в следующем:
- Блокируем All.php
- Проверяем нет ли уже в All.php классов, которые были также и автозагружены (например, пока отрабатывал данный скрипт, в параллели другой скрипт успешно отбработал и что-то дозаписал в All.php). Если такое произошло, то во избежание проблем с зависимостями работа метода будет прервана.
- Дописываем в All.php новые классы.
- Разблокируем All.php.
Скачать
autoload.zip (6 Кб)