2012-08-26 4 views
1

je suit dilemme:PHP __autoload ne fonctionne pas au sein de la fonction de traitement de tampon de sortie

ob_start('processBuffer'); 

function processBuffer($buffer){ 

    $betterBuffer = SomeClass::doSomething($buffer); 
    return $betterBuffer; 

} 

function __autoload($className){ 

    if($className == 'SomeClass'){ include_once 'some_class.php'; } 

} 

Si la SomeClass de classe doit être chargée dans processBuffer pour la première fois, il ne fonctionne pas, mais il ne fonctionne que si elle a dû être chargé avant l'exécution de la fonction processBuffer. Pourquoi donc? Actuellement, pour contourner ce problème, je dois faire ce qui suit:

__autoload('SomeClass'); 
ob_start('processBuffer'); 

Comment puis-je résoudre ce problème?

+4

Vous ne devriez pas avoir besoin d'appeler directement la fonction '__autoload()'; le simple fait de le définir devrait suffire à PHP pour l'appeler. Cependant, PHP recommande de ne plus utiliser '__autoload'; à la place, vous devriez écrire des fonctions et les passer dans 'spl_autoload_register()'. C'est mieux pour un certain nombre de façons, y compris en vous permettant d'avoir plusieurs fonctions de chargement automatique qui n'étaient pas possibles avec l'ancien mécanisme '__autoload()'. – Spudley

+0

Il vaut même la peine de mentionner qu'une fois _anything_ appelle 'spl_autoload_register()' '-_autoload()' est complètement désactivé. – KingCrunch

Répondre

2

Ceci est probablement dû à la manière dont PHP est en couches en interne. Votre fonction de traitement de tampon est appelée à la fin de la pile d'exécution, pendant l'étape de sortie. Il en va de même pour les fonctions de gestion des erreurs, qui sont mieux documentées en ce qui concerne ce qu'elles peuvent et ne peuvent pas faire. Par exemple (bien que je ne l'ai pas testé), je m'attends à ce que la fonction de traitement du tampon ne puisse pas non plus faire écho (bien, mais la sortie ne va probablement nulle part).

+0

Vous avez parfaitement raison sur le dernier bit, toute sortie dans un gestionnaire de sortie provoquera une erreur fatale: "Impossible d'utiliser la mise en mémoire tampon de sortie dans les gestionnaires d'affichage de tampons de sortie." – Niko

+0

Oui, bien que pour ce dernier bit, le texte à renvoyer puisse simplement être ajouté au tampon. – arik

0

Option 1 - "Entièrement orienté objet".

Dans ce cas, toutes les procédures de mise en mémoire tampon sont contrôlées depuis l'intérieur de la classe.

class SomeClass{ 
    public function __construct(){ 
     ob_start(); 
     //. . . 
     return (0); 
    } 

    public function __destruct(){ 
     // . . . 
     ob_end_flush(); 
     return (0); 
    } 
} 

Option 2 - "__autoload()".

La mise en mémoire tampon est en dehors de la classe, mais commence à l'intérieur de la fonction magique __autoload().

function __autoload($class){ 
    ob_start(); 
    if($class == 'SomeClass'){ 
     include_once 'some_class.php'; 
    } 
} 

$c = new SomeClass(); 
// . . . 
ob_end_flush(); 

Comme vous pouvez le voir dans http://php.net/manual/en/function.ob-start.php, la ob_start() fonction appelable sera appelée à ob_end_flush().

+0

Je crains que l'option 2 ne génère une énorme pile ob (une couche ob pour chaque classe chargée via '__autoload()'). L'option 1 est cohérente, et cela pourrait ou non fonctionner, selon les besoins du PO - mais avez-vous réellement testé le rinçage depuis un destructeur? Cela semble tordant (bien que cela puisse fonctionner). – Gutza

+0

J'utilise la mise en mémoire tampon dans mes projets de manière 'Option 1' avec seulement une différence, j'appelle flush dans une méthode publique différente de __destruct. J'utilise l'annulation de tampon et les implémentations de mesures de taille de sortie. Tout fonctionne très bien. –

Questions connexes