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 для сеансов.