#1 před 3 lety

Wosonj
Člen
Registrovaný: 22. 12. 2008
Příspěvky: 65

Vytvoření instance objektu potomka pomocí statické metody

Mám několik problémů způsobených absencí late static binding v PHP a potřebuju najít nějaký workaround. Nejhorší z nich je asi toto:

class A {
  public static function get() {
    return new self;
  }

  public function className() {
    return __CLASS__.' '.get_class($this).' '.get_class();
  }
}

class B extends A {}

$a=A::get();
echo $a->className(); //A A A
$b=B::get();
echo $b->className(); //A A A

Tzn. imho v PHP 5.2.x nejde statickou metodou vytvořit instance odvozeného objektu, přes který jsme ji volali.
Od PHP 5.3.0 by na to snad měl fungovat keyword static, ale PHP 5.3 není stable, takže do produkce nesmí.

Existuje nějaký workaround takový, který by se týkal jen třídy A? (abychom po vyjití PHP 5.3 nemuseli měnit kód odvozených tříd)


hledáme zkušené programátory v PHP / Nette: http://www.twobits.cz/volna-mista/

 

#2 před 3 lety

David Grudl
Administrator
Registrovaný: 8. 2. 2005
Příspěvky: 5548

Re: Vytvoření instance objektu potomka pomocí statické metody

Kdysi jsem s nečím takovým experimentoval http://www.sitepoint.com/…owthread.php?…. Ale žádný „čistý“ workaround neexistuje.

 

#3 před 3 lety

Wosonj
Člen
Registrovaný: 22. 12. 2008
Příspěvky: 65

Re: Vytvoření instance objektu potomka pomocí statické metody

Je mi trapné si odpovídat sám, ale po svačině mně jedno pro můj případ relativně elegantní řešení napadlo:

abstract class A {
  var $a;

  protected function __construct($arr) {
    $this->a=$arr;
  }

  protected static function get($arr,$class=NULL) {
    if (!class_exists($class)) throw new Exception('Given class name not found');
    return new $class($arr);
  }
}

class B extends A {
  public static function get($arr) {
    return parent::get($arr,__CLASS__);
  }
}

$b=B::get('foo');

Nevýhodou je, že třída B musí implementovat metodu get(), ale je to vyváženo tím, že po nasazení PHP5.3 by mělo stačit předělat metodu A::get() a nastavit ji public, přičemž jinde se nic měnit nemusí, jen příležitostně se postupně smáznou metody get() u odvozených tříd.

Editoval Wosonj (7. 1. 2009 15:58)


hledáme zkušené programátory v PHP / Nette: http://www.twobits.cz/volna-mista/

 

#4 před 3 lety

Villem
Člen
Registrovaný: 6. 1. 2009
Příspěvky: 24

Re: Vytvoření instance objektu potomka pomocí statické metody

No když už budeš v každém potomku přepisovat jednu metodu, tak proč ne tu statickou tovární?

 

#5 před 3 lety

Wosonj
Člen
Registrovaný: 22. 12. 2008
Příspěvky: 65

Re: Vytvoření instance objektu potomka pomocí statické metody

Villem napsal(a):

No když už budeš v každém potomku přepisovat jednu metodu, tak proč ne tu statickou tovární?

Snažím se implementovat něco jako Active Record, tudíž v originální třídě A obsahuje metoda get() poměrně dost kódu. Jestli jsem to nachystal správně, tak po nasazení 5.3 se jen přepíše A::get() a dál se nikde nic měnit nemusí a nově odvozené třídy se už pak obejdou bez vlastní get().


hledáme zkušené programátory v PHP / Nette: http://www.twobits.cz/volna-mista/

 

Zápatí