Opcode (APC/XCache), Zend, Doctrine и Autoloaders
Я пытаюсь использовать APC или XCache в качестве кода операции для кэширования моих php-страниц. Я использую его с Zend и Doctrine, и у него возникла проблема с автозагрузчиком.
Если я пытаюсь использовать APC, я получаю следующее:
Fatal error: spl_autoload() [<a href='function.spl-autoload'>function.spl-autoload</a>]:
Class Doctrine_Event could not be loaded in
C:\\[mydir]\\library\\doctrine\\Doctrine\\Record.php on line 777
Если я попробую с XCache, я получаю следующее:
PHP Fatal error: Cannot redeclare class Zend_Registry in
C:\\[mydir]\\library\\zendframework\\Zend\\Registry.php on line 0
Я запускаю Zend 1.9.1, Doctrine 1.1 в окне окна.
Мой загрузочный файл выглядит следующим образом:
set_include_path(dirname(__FILE__).'/../library/zendframework'
. PATH_SEPARATOR . dirname(__FILE__).'/../library/doctrine'.....
require 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->suppressNotFoundWarnings(false);
$loader->setFallbackAutoloader(true);
Из того, что я читал, использование APC или xcache почти обязательно для производительности, но я не могу заставить его работать. Любые идеи?
Ответы
Ответ 1
Вы можете положить "Zend_Session::writeClose(true);
" в конце вашего index.php.
Это запишет сессию в постоянное состояние, прежде чем необходимые объекты (Zend_Loader и т.д.) Будут разрушены.
Лучше: зарегистрируйте его как функция выключения.
Таким образом, он будет выполнен, даже если вы используете exit()
, die()
или fatal error
:
register_shutdown_function(array('Zend_Session', 'writeClose'), true);
Ответ 2
Вероятно, это похоже на проблему с пользовательской обработкой сеанса и APC-кешем. Если вы назначили собственный обработчик сеанса, он регистрируется с помощью RSHUTDOWN в PHP. Это та же самая процедура, которую использует APC, и создаст внутренний конфликт в PHP, и ваш пользовательский обработчик сеанса не будет закрыт во всех ситуациях.
Таким образом, вам придется убедиться, что вы вручную закрываете обработчик пользовательского сеанса при завершении работы
Ввод "Zend_Session::writeClose(true);"
в конец вашего index.php не лучший способ сделать это, если у вас есть выход; вызовы в ваших сценариях в любом месте.
Лучше зарегистрировать обработчик отключения таким образом:
function shutdown()
{
Zend_Session::writeClose(true);
}
register_shutdown_function('shutdown');
Поместите это в начало вашего файла index.php, чтобы убедиться, что процедура останова зарегистрирована до запуска любых других сценариев.
Ответ 3
Есть ли что-то еще, уклоняющееся от пути включения? Возможно, попробуйте выйти из пути include прямо перед этой строкой в вашем первом примере APC.
XCache один действительно странный. Однако этот проект довольно мертв, и я не доверяю ему на PHP 5.2+. Попробуйте вместо eaccelerator? Нам повезло с ним.
Ответ 4
Бенджамин Кремер, ты спасатель жизни. Хотя вышеупомянутая (оригинальная) проблема является особым случаем автозагрузки с сеансами, закрытие сеанса, по-видимому, является общим решением для таких случаев. Заметка:
Размещение Zend_Session::writeClose(true);
в конце ваших скриптов может не всегда прерывать его, поскольку в вашем коде могут быть exit;
's, die();
и т.д. В этом случае вы можете использовать
register_shutdown_function(array('Zend_Session', 'writeClose'), true);
или, просто
register_shutdown_function('session_write_close');
если вы не используете Zend для сеансов.