Autor Zpráva
IDKWIT
Profil *
Dobrý den,

naučil jsem se něco z objektového programování, ovšem netuším vůbec, kdy použít $this. Ať už v třídě, nebo když volám nějakou funkci($this->neco();) Mohl by mi to někdo vysvětlit, aby to pochopil i úplný laik? :D
Děkuji moc.
pcmanik
Profil
V dokumentácii je to myslím dobre vysvetlené. Ale v skratke this odkazuje na aktuálnu inštanciu triedy.
Taktiež keď ti metóda vráti $this tak môžeš použiť reťazenie - $instancia->metoda1()->metoda2();
Kubo2
Profil
IDKWIT:
Kdy a proč použít $this?
$this odkazuje vždy na kontext aktuálneho objektu. Pokiaľ je volaná mimo kontextu objektu, tvári sa ako neexistujúca, ale pokus o jej inicializáciu od PHP 5.0 vyššie skončí fatálnou chybou.


Trochu rozoberiem pcmanikov nástin o reťazení. Máš napríklad triedu na vypisovanie HTML značiek:

<?php

class Tag {
    private $name;
    private $attrs = array();
    private $content = null;

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

    function __toString() {
        $code = "<" . $this->name;
        foreach($this->attrs as $name => $val) {
            $code .= " " . $name . "=\"$val\"";
        }
        $code .= ">" . (!is_null($this->content) ? $this->content : '') . "</" . $this->name. ">";
        return $code;
    }

    function addClass($className) {
        $this->attrs["class"] .= $className." ";
        return $this;
    }

    function addTitle($title) {
        $this->attrs["title"] = $title;
        return $this;
    }

    function addContent($content) {
        $this->content = $content;
        return $this;
    }

    function stringify() {
        return $this;
    }
}

Všimni si, že každá metóda okrem __toString() vracia odkaz na tento objekt, teda $this (vracia ho aj konštruktor, ale deje sa to implicitne). Vďaka tomu môžeš volanie jednotlivých metód tohoto objektu zjednotiť – to sa nazýva reťazenie.

$paragraph = new Tag('p');
echo $paragraph
        ->addClass("test")
        ->addTitle("Kubo2's testing paragraph")
        ->addContent(
        "This is Kubo2's testing paragraph. (...)"
        )
        ->stringify();

Takže ako keby si každú metódu volal na tej predošlej, ale voláš ju vlastne na objekte, ktorý vráti, teda na tvojej inštancii triedy tag $paragraph. Môže to celkom sprehľadniť kód a ušetriť pár znakov*, avšak sú občas aj situácie, kedy je takéto chovanie nežiaduce, napríklad ak metóda vracia pri chybe hodnotu false alebo nejakú defaultnú — no v OOP sa pre chybové situácie používa vyvolávanie výnimiek, takže ak nechceš robiť v OOP iba na oko, používaj výnimky, ktorých účelom je práve toto a nie návratovú hodnota funkcie/metódy, tá má za úlohu vrátiť relevantnú hodnotu.

Celý príklad som spracoval ako živú ukážku.

* V mojom príklade si v podstate protirečím, pretože volanie metódy stringify() (a vlastne aj jej samotná existencia) je nadbytočné, keďže iba vráti odkaz na $this, na ktorom sa kvôli pretypovaniu ešte implicitne zavolá __toString(), generujúce reťazcovú reprezentáciu HTML tagu.

Dôrazne však nedoporučujem používať túto triedu v praxi!
Lamicz
Profil
Ještě bych pro úplnost doplnil, že anglicky je to "fluent (interface)"
Monkeys
Profil *
Kubo2:

Pekny priklad:

Ja sa chcem opytat na tuto metodu:
Spajanie retazcov vacsinou vyuzivam pri neakom cykle ale tuto tomu celkom nerozumiem

 function addClass($className) {
        $this->attrs["class"] .= $className." ";
        return $this;
    }

ak volam tuto metodu z instancie a triedy pre ten tag napisem priamo ako retazec tak by sa aj ako retazec mali vsetky vlozit.

echo $paragraph
        ->addClass("test test1 test2 test3")
        ->addTitle("Kubo2's testing paragraph")
        ->addContent(
        "This is Kubo2's testing paragraph. (...)"
        )
        ->stringify();

tak vystup by mal byt
<p class="test test1 test2 test3"> .... </p>

Ak to chapem zle oprav ma prosim

dik
M.
Kubo2
Profil
Monkeys:
Spajanie retazcov vacsinou vyuzivam pri neakom cykle ale tuto tomu celkom nerozumiem
Implementáciu tejto metódy som pre zjednodušenie schválne nechal takto. Taktiež som vypol vypisovanie chybových hlášok, pretože v opačnom prípade by prvé volanie tejto metódy volalo E_NOTICE (operátor pripojenia reťazcov totiž funguje tak, že najprv číta hodnotu z premennej, až potom reťazce spojí a zapíše naspäť; ja ho prvýkrát volám na zatiaľ nedefinovanom indexe poľa Tag::$attrs — v realite by sa to muselo viac opodmienkovať).

ak volam tuto metodu z instancie a triedy pre ten tag napisem priamo ako retazec tak by sa aj ako retazec mali vsetky vlozit.
Áno, vložia sa.
Teda pri každom volaní priradí na koniec reťazca obsahujúceho hodnotu HTML atribútu class ďaľšiu triedu/triedy a medzeru (ak by na konci nemala byť prebytočná medzera, tiež by sa to muselo nejak doplniť alebo pri generovaní reťazcovej reprezentácie použiť trim().

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: