Řetězení volání metod v PHP

Řetězení volání metod v PHP
« kdy: 06. 11. 2013, 14:19:55 »
Ahoj, proč mi nefunguje tento kód?

Kód: [Vybrat]
$obj = new Test();

$obj->vaha()
    ->cena()
    ->sklad()
    ->dph();

Píše mi to, že: Call to a member function cena() on a non-object. Takto to funguje normálně.

Kód: [Vybrat]
$obj = new Test();

$obj->vaha();
$obj->cena();
$obj->sklad();
$obj->dph();

Našla jsem to zde http://programujte.com/clanek/2009113001-oop-v-php/
Děkuji za pomoc. V.L.
« Poslední změna: 06. 11. 2013, 14:29:22 od Petr Krčmář »


jb

Re:Problém s řetězením volání metod v PHP
« Odpověď #1 kdy: 06. 11. 2013, 14:23:31 »
Verzi PHP mas spravnou?

Marek

Re:Řetězení volání metod v PHP
« Odpověď #2 kdy: 06. 11. 2013, 14:30:56 »
Každá taková metoda musí vracet daný objekt:

Kód: [Vybrat]
return $this;

Re:Řetězení volání metod v PHP
« Odpověď #3 kdy: 06. 11. 2013, 14:31:36 »
Mám: PHP Version 5.4.4-14+deb7u5

Re:Řetězení volání metod v PHP
« Odpověď #4 kdy: 06. 11. 2013, 14:32:50 »
Každá taková metoda musí vracet daný objekt:

Kód: [Vybrat]
return $this;

Ale jsou metody, které nic nevrací, jen třeba něco nastaví. V tom případě, to nejde použít? Děkuji


Re:Problém s řetězením volání metod v PHP
« Odpověď #5 kdy: 06. 11. 2013, 14:33:03 »
Ty metody musejí vracet nějaký objekt, na kterém zavoláte tu další metodu – ve vašem případě tedy $this. Ten váš kód totiž dělá jakoby následující (akorát ty návratové hodnoty nejsou přiřazeny do žádné pojmenované proměnné):

Kód: [Vybrat]
$obj = new Test();

$obj2 = $obj->vaha();
$obj3 = $obj2->cena();
$obj4 = $obj3->sklad();
$obj5 = $obj4->dph();

eMko

  • ****
  • 456
    • Zobrazit profil
    • E-mail
Re:Řetězení volání metod v PHP
« Odpověď #6 kdy: 06. 11. 2013, 14:38:34 »
Kód: [Vybrat]
$obj = new Test();

$obj->vaha()
    ->cena()
    ->sklad()
    ->dph();

Aby se toto dalo použít, musí to to být podporované ze strany té třídy.

Kód: [Vybrat]
function vaha(){
     //something is done here
     return $this;
}

v tomto případě to použít jde, protože další funkci (cena) voláš na návratové hodnotě funkce vaha atp. Bohužel málo tříd je takto napsaných. Pokud se jedná o Tvoji třídu, nic Ti nebrání ty vnitřní metody takto upravit - říká se tomu Fluent interface (http://en.wikipedia.org/wiki/Fluent_interface) - a tu a tam se to skutečně používá.

eMko

  • ****
  • 456
    • Zobrazit profil
    • E-mail
Re:Řetězení volání metod v PHP
« Odpověď #7 kdy: 06. 11. 2013, 14:46:42 »
Jo a už jsem to psal (tuším) předevčírem - vyprdni se na internetové tutorialy, zvlášť pokud začínáš. Pořádná knížka je mnohem lepší než internetové tutorialy - z toho se pořádně programovat nenaučíš. V dnešní době není problém se k literatuře dostat. Když nejsou finance, dá se to udělat "jakkoliv jinak". (Zvlášť, když Velká Británie zveřejnila (bohužel nekompletní) seznam zdrojů: http://www.root.cz/zpravicky/britove-blokuji-21-webu-odkazujicich-na-torrenty/.)

Samozřejmě kniha nedokáže nahradit ucelené vzdělání; bohužel míst, kde se dá informatika studovat na dobré úrovni i kombinovaně/distančně, ubývá.

moloch-vpravo

Re:Řetězení volání metod v PHP
« Odpověď #8 kdy: 06. 11. 2013, 15:21:07 »
tomu sa hovori fluent interface a hodi sa napriklad pre immutable typy:

Kód: [Vybrat]
class StringBuilder
{
    private $value;

    function __construct(array $value = array()) { $this->value = $value; }

    function append($str)
    {
        return new StringBuilder(array_merge($this->value, array($str)));
    }

    function __toString() { return implode('', $this->value); }
}

Kód: [Vybrat]
echo (new StringBuilder())
    ->append("Ja")
    ->append(" ")
    ->append("Ty");

Natix

Re:Řetězení volání metod v PHP
« Odpověď #9 kdy: 06. 11. 2013, 15:34:56 »
tomu sa hovori fluent interface a hodi sa napriklad pre immutable typy:

Kód: [Vybrat]
class StringBuilder
{
    private $value;

    function __construct(array $value = array()) { $this->value = $value; }

    function append($str)
    {
        return new StringBuilder(array_merge($this->value, array($str)));
    }

    function __toString() { return implode('', $this->value); }
}

Kód: [Vybrat]
echo (new StringBuilder())
    ->append("Ja")
    ->append(" ")
    ->append("Ty");

Já sice PHP neumím, ale k čemu je jako dobré mít StringBuilder immutable? :)

Marek

Re:Řetězení volání metod v PHP
« Odpověď #10 kdy: 06. 11. 2013, 15:39:41 »
Každá taková metoda musí vracet daný objekt:

Kód: [Vybrat]
return $this;

Ale jsou metody, které nic nevrací, jen třeba něco nastaví. V tom případě, to nejde použít? Děkuji

Naopak, toto lze použít jen u metod, které nic nevrací. Ty, které mají vracet něco jiného nemůžou zároveň vracet vlastní objekt. K těm ostatním, které pouze něco provádějí ale nic nevrací, pouze přilepte return $this .