Question

Je travaillais sur une classe abstraite pour économiser sur un code pour deux classes. Ces classes sont toutes les usines qui s'instancient à travers différents appels statiques. Je pouvais sauver un peu de code en mettant toutes ces méthodes dans une classe abstraite.

Cependant, je suis tombé sur une liaison statique fin problème ... puisque notre hébergeur est de ne pas utiliser 5.3 ou plus tard, je n'ai pas accès à get_called_class. Si j'ai

$class = __CLASS__;
return new $class();

dans la classe abstraite, __CLASS__ est le nom de la classe abstraite, quand je veux réellement utiliser la classe appelée.

J'ai vu des exemples d'usines abstraites sur le web où les classes d'enfants ont leurs propres méthodes d'instanciation et ne reposent pas sur le parent abstrait pour elle. Cependant, dans cette situation, la seule raison de la classe abstraite est de sauver le code, donc si je ne peux pas le faire là-bas, la valeur de celui-ci diminue considérablement.

Y at-il une solution de contournement en php <5.3? debug_backtrace()?


Modifier

je l'ai fait un test et il semble debug_backtrace() ne fonctionnera pas! Je suppose que cela est la raison pour laquelle nous avons besoin de liaison statique fin .

<?

abstract class abstractFactory {
    public function create() {
            print_r(debug_backtrace());
            $class = __CLASS__;
            return new $class();
    }
}

class concreteFactory extends abstractFactory {}

$chimborazo = concreteFactory::create();

et le résultat:

$ php test.php
Array
(
    [0] => Array
        (
            [file] => /var/www/test.php
            [line] => 13
            [function] => create
            [class] => abstractFactory
            [type] => ::
            [args] => Array
                (
                )

        )

)

Fatal error: Cannot instantiate abstract class abstractFactory in /var/www/test.php on line 7
Était-ce utile?

La solution 3

Une fois façon de le faire est de passer outre les différentes méthodes d'instanciation, et de transmettre le nom de la classe directement:

<?

abstract class abstractFactory {

    public function create($class) {
        return new $class();
    }

    public function instantiate($class) {
        return new $class();
    }

}

class concreteFactory extends abstractFactory {

    public function create() {
        parent::create(__CLASS__);
    }

    public function instantiate() {
        parent::instantiate(__CLASS__);
    }
}


$chimborazo = concreteFactory::create();
$chimborazo = concreteFactory::instantiate();

Autres conseils

La seule solution que je l'ai vu pour cela implique d'appeler debug_backtrace pour déterminer le nom de la classe de l'appelant (s). Ceci est bien sûr un hack géant. Je l'ai vu un code qui combine un backtrace avec en fait l'ouverture du it fichier appelant et à l'analyse syntaxique des choses à comprendre. des trucs bizarres, horrible.

Le manque de LSB va revenir et vous mordre plus tard. Mettre à jour maintenant, même si cela signifie des hôtes de commutation. En fait, surtout si cela signifie des hôtes de commutation. 5.3 a été pendant un an.

Voici ce que je l'ai utilisé jusqu'à passer à 5.3:

if (!function_exists('get_called_class')) {

   /**
    * Implementation of get_called_class() for pre-5.3 PHP
    *
    * @return string
    */
   function get_called_class()
   {
      $bt = debug_backtrace();
      $lines = file($bt[1]['file']);
      preg_match('/([a-zA-Z0-9\_]+)::'.$bt[1]['function'].'/',
               $lines[$bt[1]['line']-1],
               $matches);
      return $matches[1];
   }
}

Cela vous permet de déterminer dans une fonction statique quel nom de classe la fonction a été invoquée avec. Il est une solution qui a des problèmes de performance, mais il est le seul que j'ai trouvé. S'il y a d'autres je serais intéressé de savoir.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top