操作码(APC / XCache),Zend,Doctrine和自动加载程序

7
我将尝试使用APC或XCache作为我的php页面的opcode缓存。我正在与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在Windows系统上。

我的引导程序如下:

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几乎是必须的,但我似乎无法使其运行。有什么建议吗?

4个回答

10
你可以在index.php的结尾处添加"Zend_Session::writeClose(true);"。 这样会在必要的对象(如Zend_Loader等)被销毁之前,将会话写入持久状态。
更好的做法是:将其注册为shutdown function。 这样即使使用exit()die()或发生fatal error也会执行它。
register_shutdown_function(array('Zend_Session', 'writeClose'), true);

register_shutdown_function 的功劳归于 hogberg 和 battal。 - Benjamin Cremer

3

这个问题可能与自定义会话处理和APC缓存有关。如果您分配了自定义会话处理程序,则它将在PHP中使用RSHUTDOWN进行注册。这是APC使用的相同例程,因此会在PHP中创建内部冲突,并且您的自定义会话处理程序在所有情况下都无法关闭。

因此,您必须确保在关闭时手动关闭自定义会话处理程序。

在您的index.php末尾放置"Zend_Session::writeClose(true);"并不是最好的解决方法,因为您的脚本中可能有任何exit;调用。

更好的方法是以以下方式注册一个关闭处理程序:

function shutdown()
{
 Zend_Session::writeClose(true);
}

register_shutdown_function('shutdown');

把这段代码放在你的index.php文件顶部,以确保在运行任何其他脚本之前注册关闭过程。

0

Benjamin Cremer,你真是个救星。虽然上述(原始)问题是会话自动加载的特殊情况,但关闭会话似乎是这种情况的一般解决方案。不过需要注意的是:

Zend_Session::writeClose(true);放置在脚本末尾可能并不总是奏效,因为您的代码中可能有exit;die();等。在这种情况下,您可以使用

register_shutdown_function(array('Zend_Session', 'writeClose'), true);

或者,简单地使用

register_shutdown_function('session_write_close');

如果您不使用Zend进行会话。


0

是否还有其他东西干扰了包含路径?也许在您的第一个APC示例中,在该行之前尝试记录一下包含路径。

XCache真的很奇怪。虽然该项目已经相当死亡,但我不会信任它在PHP 5.2+上的使用。尝试使用eaccelerator代替?我们在其中运气最好。


在包含路径中还有其他Doctrine特定的内容(模型等)。我们正在寻找一个ZendCache后端(http://framework.zend.com/manual/en/zend.cache.backends.html),因此eaccelerator无法使用。 - Chris Williams
有一个关于eaccelerator后端的提案http://framework.zend.com/wiki/display/ZFPROP/Zend_Cache_Backend_Eaccelerator+-+Federico+Cargnelutti - 实现起来应该非常容易。不管怎样,我想知道的是,在抛出错误之前是否有任何东西从总体中删除了您预期的包含路径。 - Justin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接