Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: verlip80 06. 11. 2013, 14:19:55

Název: Řetězení volání metod v PHP
Přispěvatel: verlip80 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/ (http://programujte.com/clanek/2009113001-oop-v-php/)
Děkuji za pomoc. V.L.
Název: Re:Problém s řetězením volání metod v PHP
Přispěvatel: jb 06. 11. 2013, 14:23:31
Verzi PHP mas spravnou?
Název: Re:Řetězení volání metod v PHP
Přispěvatel: Marek 06. 11. 2013, 14:30:56
Každá taková metoda musí vracet daný objekt:

Kód: [Vybrat]
return $this;
Název: Re:Řetězení volání metod v PHP
Přispěvatel: verlip80 06. 11. 2013, 14:31:36
Mám: PHP Version 5.4.4-14+deb7u5
Název: Re:Řetězení volání metod v PHP
Přispěvatel: verlip80 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
Název: Re:Problém s řetězením volání metod v PHP
Přispěvatel: Filip Jirsák 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();
Název: Re:Řetězení volání metod v PHP
Přispěvatel: eMko 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á.
Název: Re:Řetězení volání metod v PHP
Přispěvatel: eMko 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á.
Název: Re:Řetězení volání metod v PHP
Přispěvatel: moloch-vpravo 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");
Název: Re:Řetězení volání metod v PHP
Přispěvatel: Natix 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? :)
Název: Re:Řetězení volání metod v PHP
Přispěvatel: Marek 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 .