Opcode (APC/XCache), Zend, Doctrine, and Autoloade

2020-02-09 12:04发布

I am trying to use either APC or XCache as an opcode to cache my php pages. I am using it with Zend and Doctrine and it's having a problem with the autoloader.

If I try with APC, I get the following:

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

If I try with XCache I get the following:

PHP Fatal error: Cannot redeclare class Zend_Registry in 
  C:\\[mydir]\\library\\zendframework\\Zend\\Registry.php on line 0

I'm running Zend 1.9.1, Doctrine 1.1 on a windows box.

My bootstrap is as follows:

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);

From what I've read, using APC or xcache is almost a must for performance, but I can't seem to get it working. Any ideas?

4条回答
趁早两清
2楼-- · 2020-02-09 12:23

It is probably similar to the problem with custom session handling and APC-cache. If you have assigned a custom session handler it is registered with RSHUTDOWN in PHP. It is the same routine that APC uses and will therefor create an internal conflict in PHP and your custom session handler will not close in all situations.

So you will have to make sure you manually close the custom session handler at shutdown

Putting a "Zend_Session::writeClose(true);" at the end of your index.php is not the best way to do that in case you have any exit; calls in your scripts anywhere.

It is better to register a shutdown handler in this way:

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

register_shutdown_function('shutdown');

Put that in top of your index.php file to make sure that the shutdown procedure is registered before any other scripts are run.

查看更多
Evening l夕情丶
3楼-- · 2020-02-09 12:23

Is there something else mucking the include path? Maybe try to log out the include path right before that line in your first APC example.

The XCache one is really weird. That project is pretty dead though, and I'd not trust it on PHP 5.2+. Try eaccelerator instead? We've had the best luck with it.

查看更多
狗以群分
4楼-- · 2020-02-09 12:26

Benjamin Cremer, you're a life saver. While the above (original) problem is a special case of autoloading with sessions, closing the session seems to be a general solution for such cases. A note though:

Placing Zend_Session::writeClose(true); at the end of your scripts may not always cut it, since you may have exit;'s, die();'s, etc in your code. In this case, you can use

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

or, simply

register_shutdown_function('session_write_close');

if you do not use Zend for sessions.

查看更多
甜甜的少女心
5楼-- · 2020-02-09 12:30

You could put a "Zend_Session::writeClose(true);" at the end of your index.php.
This will write the session into a persistent state before necessary Objects (Zend_Loader etc.) get destructed.

Better: Register it as shutdown function.
So it will be executed even if you use exit(), die() or a fatal error occures:

register_shutdown_function(array('Zend_Session', 'writeClose'), true);
查看更多
登录 后发表回答