2010-02-04 12 views
0

J'ai une fabrique singleton et je voudrais qu'elle renvoie une référence à l'instance d'objet afin que je puisse utiliser l'usine singleton pour détruire l'instance et ne pas avoir d'instances ailleurs dans mon code pour survivre.Renvoyer une référence à une instance d'un objet dans PHP

Exemple de ce que je voudrais être en mesure de le faire:

$cat = CatFactory::getInstance(); 
$cat->talk(); //echos 'meow' 
CatFactory::destructInstance(); 
$cat->talk(); //Error: Instance no longer exists 

Répondre

2

Cela pourrait fonctionner:

<?php 
class FooFactory 
{ 
    private static $foo; 

    private function __construct() 
    { 
    } 

    public static function getInstance() 
    { 
    return self::$foo ? self::$foo : (self::$foo = new FooFactory()); 
    } 

    public static function destroyInstance() 
    { 
    self::$foo = null; 
    } 

    public function __call($fn, $args) 
    { 
    if (!method_exists(self::$foo, $fn) || $fn[0] == "_") 
     throw new BadMethodCallException("not callable"); 

    call_user_func_array(array(self::$foo, $fn), $args); 
    } 

    # function hidden since it starts with an underscore 
    private function _listen() 
    { 
    } 

    # private function turned public by __call 
    private function speak($who, $what) 
    { 
    echo "$who said, '$what'\n"; 
    } 

} 

$foo = FooFactory::getInstance(); 
$foo->speak("cat", "meow"); 
$foo->_listen();     # won't work, private function 
FooFactory::destroyInstance(); 
$foo->speak("cow", "moo");  # won't work, instance destroyed 
?> 

De toute évidence, il est un hack.

+0

J'ai du mal à comprendre comment cela fonctionne. Pourriez-vous élaborer pour moi s'il vous plaît? –

+0

En marquant les méthodes privées, il déclenche la méthode magique '__call'. Cette fonction transfère essentiellement l'appel à la fonction privée si l'instance $ private static n'a pas été détruite. C'est en quelque sorte la même chose que d'ajouter 'if (! Self :: $ instance) throw new Exception();' en haut de chaque fonction publique. – Matthew

2

Sur la base de la documentation unset, je ne pense pas que cela soit possible. Vous ne pouvez pas réellement détruire un objet, seulement un handle à lui. Si d'autres variables sont présentes et contiennent toujours une référence, l'objet continuera à vivre.

0

Vous pouvez accomplir ce que vous voulez en demandant à votre objet Cat d'appliquer une propriété $ détruite. PHP 5 passe les objets par référence par défaut, donc vous n'avez pas à vous soucier de cette partie.

0

Un travail autour serait de créer une classe de chat

class cat 
{ 
    public $cat; 

    public function __construct() 
    { 
    $this->cat = CatFactory::getInstance(); 
    } 

    public function __destruct() 
    { 
    CatFactory::destructInstance(); 
    } 

} 

$cat = new cat(); 
$cat->cat->talk(); 
$cat->cat->talk(); 
+0

... Je ne comprends pas. – Aistina