2009-09-01 18 views
7

J'essaie d'utiliser APC ou XCache comme opcode pour mettre en cache mes pages php. Je l'utilise avec Zend et Doctrine et il y a un problème avec l'autoloader.Opcode (APC/XCache), Zend, Doctrine et Autoloaders

Si j'essaie avec APC, je reçois le texte suivant:

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 

Si je tente avec XCache j'obtiens ce qui suit:

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

Je cours Zend 1.9.1, Doctrine 1.1 sur une boîte de windows.

Mon bootstrap est la suivante:

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

D'après ce que j'ai lu, en utilisant APC ou xcache est presque un must pour la performance, mais je ne peux pas sembler le faire fonctionner. Des idées?

Répondre

10

Vous pouvez mettre un "Zend_Session::writeClose(true);" à la fin de votre index.php.
Cela écrira la session dans un état persistant avant que les objets nécessaires (Zend_Loader etc.) ne soient détruits.

Mieux: Enregistrez-le en tant que shutdown function.
Il sera exécuté même si vous utilisez exit(), die() ou fatal error occures:

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

Cela l'a résolu pour moi, en utilisant APC. – smoove

+0

Le crédit pour register_shutdown_function est attribué à hogberg et à battal. –

0

Y a-t-il quelque chose d'autre dans le chemin d'inclusion? Essayez peut-être de déconnecter le chemin d'inclusion juste avant cette ligne dans votre premier exemple APC.

Le XCache est vraiment bizarre. Ce projet est plutôt mort, et je ne le ferais pas confiance sur PHP 5.2+. Essayez eaccelerator à la place? Nous avons eu la meilleure chance avec ça.

+0

Il existe d'autres éléments spécifiques à Doctrine dans le chemin d'inclusion (modèles, etc.). Nous cherchons un backend ZendCache (http://framework.zend.com/manual/fr/zend.cache.backends.html) donc eaccelerator ne fonctionnera pas. –

+0

Theres une proposition pour un backend eaccelerator http://framework.zend.com/wiki/display/ZFPROP/Zend_Cache_Backend_Eaccelerator+-+Federico+Cargnelutti - devrait être assez facile à mettre en œuvre vraiment. Quoi qu'il en soit, ce que je me demandais, c'est si quelque chose supprime les chemins d'inclusion prévus du total avant que l'erreur ne soit lancée. – Justin

3

Il est probablement similaire au problème avec la gestion des sessions personnalisées et APC-cache. Si vous avez affecté un gestionnaire de session personnalisé, il est enregistré avec RSHUTDOWN en PHP. C'est la même routine que APC utilise et créera donc un conflit interne en PHP et votre gestionnaire de session personnalisé ne se fermera pas dans toutes les situations.

Donc, vous devez vous assurer que vous fermez manuellement le gestionnaire de session personnalisée à l'arrêt

Mettre un "Zend_Session::writeClose(true);" à la fin de votre index.php est pas la meilleure façon de le faire que si vous avez une sortie; appelle dans vos scripts n'importe où.

Il est préférable d'enregistrer un gestionnaire d'arrêt de cette manière:

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

register_shutdown_function('shutdown'); 

Mettez ça dans le dessus de votre fichier index.php pour vous assurer que la procédure d'arrêt est enregistré avant que d'autres scripts sont exécutés. Benjamin Cremer, vous êtes un épargnant de vie.

0

Bien que le problème ci-dessus (original) soit un cas particulier d'auto-chargement avec des sessions, la fermeture de la session semble être une solution générale pour de tels cas.Une note cependant:

Mise Zend_Session::writeClose(true); à la fin de vos scripts peut couper pas toujours, puisque vous pouvez avoir exit; « s, die(); » s, etc dans votre code. Dans ce cas, vous pouvez utiliser

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

ou, tout simplement

register_shutdown_function('session_write_close');

si vous n'utilisez pas Zend pour les sessions.