Frage

Ich arbeite an einer abstrakten Klasse auf einigem Code für ein paar Klassen zu speichern. Diese Klassen sind alle Fabriken, die sich durch unterschiedliche statische Anrufe instanziiert. Ich könnte einen Code speichern, indem Sie in einer abstrakten Klasse all diese Methoden setzen.

Allerdings lief ich in eine Späte statische Bindung Problem ... da unsere Web-Host nicht 5.3 verwenden oder später, ich habe keinen Zugriff auf get_called_class. Wenn ich

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

in der abstrakten Klasse ist __CLASS__ der Name der abstrakten Klasse, wenn ich will es tatsächlich die genannte Klasse verwenden.

Ich habe Beispiele von abstrakten Fabriken im Web zu sehen, wo das Kind Klasse ihre eigene Instanziierung Methoden haben, und verlassen Sie sich nicht auf den abstrakt Eltern für sie. Doch in dieser Situation ist der einzige Grund für die abstrakte Klasse Code zu speichern, so dass, wenn ich es nicht dort tun kann, ist der Wert davon stark vermindert.

Gibt es eine Abhilfe in PHP <5.3? debug_backtrace()?


Edit:

habe ich einen Test, und es scheint debug_backtrace() wird nicht funktionieren! Ich denke, das ist, warum wir brauchen Späte statische Bindung .

<?

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

class concreteFactory extends abstractFactory {}

$chimborazo = concreteFactory::create();

und das Ergebnis:

$ 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
War es hilfreich?

Lösung 3

Sobald Weg, es zu tun ist, um die verschiedenen Instanziierung Methoden außer Kraft zu setzen, und den Namen der Klasse übergeben direkt an:

<?

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

Andere Tipps

Die Umgehung nur habe ich gesehen, für diesen Aufruf beinhaltet debug_backtrace die Klassennamen des Anrufers (s) zu bestimmen. Das ist natürlich ein riesiger Hack. Ich habe einige Code, kombiniert ein Backtrace gesehen mit tatsächlich die anrufende Datei öffnen und Parsen es zu Figur Dinge aus. Bizarr, schrecklichen Sachen.

Der Mangel an LSB wird Sie später wieder kommen und beißen. Jetzt aktualisieren, selbst wenn es bedeutet Schalen Gastgeber. In der Tat, vor allem, wenn es bedeutet, Schalen Gastgeber. 5.3 seit einem Jahr gewesen.

Hier ist, was ich habe, bis bewegend auf 5,3 unter Verwendung von:

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];
   }
}

Auf diese Weise können Sie in einer statischen Funktion bestimmen, welche Klasse Name der Funktion mit aufgerufen wurde. Es ist eine Abhilfe, die einige Performance-Probleme hat, aber es ist die einzige, die ich gefunden habe. Wenn es andere gibt, würde ich daran interessiert zu wissen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top