Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: Matěj 24. 01. 2018, 16:12:21
-
Ahoj, jak rozpoznat co objekt vrací
class A{
function __construct(){
..
}
}
class A{
function __toString(){
return ..
}
}
Když vytvořím třídu
$a = new A();
a dám testovat na objekt, tak je to pořád objekt
if ( is_object($a)){
//je to objekt
}
myslel jsem, že díky magické metodě __toString() se stane z objektu string. Ne, že se nestane z objektu string, ale dokonce stále můžu volat třeba jiné metody.
Tak že otázka, může to kód nějak zjistit/rozlišit? Napadlo mě pouze tohle, ale nevím no..
method_exists($a,'__toString');
-
Nevytvoříš dvě třídy se stejným jménem.
Objekty rozlišíš podle toho, jaký mají typ. Funkce get_class.
Metoda __toString() nijak neuprávuje svůj objekt. Tato metoda vrací textovou reprezentaci objektu. Slouží to k tomu, aby se dalo zapsat echo "Obsah objektu {$a}.". Nevrací jméno třídy, ale textovou reprezentaci instance, obsahu.
Můžeš lépe popsat, o co ti jde?
-
Když vytvořím třídu
$a = new A();
Takhle vytvaris objekt(instanci tridy) a nikoliv tridu.
Jak funguje metoda __toString() uz kolega popsal. Objekt bude vzdy objektem - neexistuje duvod, aby byl stringem. Avsak existuji obcas dobre duvody proc mit implementovanou metodu toString()
-
K rozlišení objektů slouží operátor instanceof, ovšem v dobrých skriptech se to nepoužívá. K čemu vlastně potřebuješ rozpoznávat, co obekt vrací? Prostě tu metodu implementuj v každém objektu, který může být tímto způsobem volán a tu metodu volej bez ptaní.
-
Můžeš lépe popsat, o co ti jde?
Když pominu můj původní dotaz, který stejně směřoval k tomuto problému, tak jde o to, že kámen úrazu je to, že
se nedají volat z metody __toString() jiné metody, teda dají ale změny se neprojeví v objektu..
Třeba tohle vrátí výsledek správně - nastaveno : 2
class A{
public $v=1;
public function nastav(){
$this->v=2;
return 'nastaveno : ';
}
}
class B{
public function __construct($a){
$this->a=$a;
$this->r=$this->a->nastav();
}
public function __toString(){
return $this->r;
}
}
class C{
public function __construct (){
$this->a=new A();
$this->b=new B($this->a);
}
public function __toString(){
return $this->b.$this->a->v;
}
}
$c=new C();
echo $c;
no a tohle vrátí výsledek špatně - nastaveno : 1, a to jenom proto, že jsem to volal z metody __toString()
class A{
public $v=1;
public function nastav(){
$this->v=2;
return 'nastaveno : ';
}
}
class B{
public function __construct($a){
$this->a=$a;
}
public function __toString(){
return $this->r=$this->a->nastav();
}
}
class C{
public function __construct (){
$this->a=new A();
$this->b=new B($this->a);
}
public function __toString(){
return $this->b.$this->a->v;
}
}
$c=new C();
echo $c;
-
Možná je to tak správně, neboť metoda __toString() by v žádném případě neměla nic nastavovat.
Přiznám se, že se i v tak krátkém kódu docela ztrácím. Možná proto, že mezi těmi třídami je příliš mnoho zbytečných vnitřních závislostí.
-
Možná je to tak správně, neboť metoda __toString() by v žádném případě neměla nic nastavovat.
Přiznám se, že se i v tak krátkém kódu docela ztrácím. Možná proto, že mezi těmi třídami je příliš mnoho zbytečných vnitřních závislostí.
Ano, je možný, že to není chyba ale vlastnost.
Taky to napsat bylo docela složitý, abych nasimuloval ten jev. ;)
-
mam pocit, ze vymyslis neco spatneho
-
Tak jsem si to zkopíroval a vyzkoušel. Ve třídě C máš chybu ve funkci __toString(). Vyzkoušej tohle:
class C {
public function __construct () {
$this->a = new A();
$this->b = new B($this->a);
}
public function __toString() {
return '' . $this->b . $this->a->v;
}
}
-
Žádnou chybu nevidím..
-
Takže vytvoříš objekt C, který vytvoří objekt A a tento předá do konstruktoru objektu B kvůli vypsání vlastnosti v objektu A. A jinak doma všichni zdrávi? Já myslím, že svět je jednoduchý a měli bychom ho tak udržovat. Nepředávej objekty do konstruktorů, vytvoř jim privátní a veřejné vlastnosti a předávej tyto. Používej dědičnost. Vytvoř si objekty, které něco řeší a mezi nimi předávej zprávy. Určitě to není předávání objektu do konstruktoru. Přečti si manuál - http://php.net/manual/en/language.oop5.magic.php#object.tostring . Metoda __toString řeší něco jiného než předání tvého vlastního stringu
-
Nepředávej objekty do konstruktorů, vytvoř jim privátní a veřejné vlastnosti a předávej tyto. Používej dědičnost.
Co ho to učíš?!
-
Takže vytvoříš objekt C, který vytvoří objekt A a tento předá do konstruktoru objektu B kvůli vypsání vlastnosti v objektu A. A jinak doma všichni zdrávi? Já myslím, že svět je jednoduchý a měli bychom ho tak udržovat. Nepředávej objekty do konstruktorů, vytvoř jim privátní a veřejné vlastnosti a předávej tyto. Používej dědičnost. Vytvoř si objekty, které něco řeší a mezi nimi předávej zprávy. Určitě to není předávání objektu do konstruktoru. Přečti si manuál - http://php.net/manual/en/language.oop5.magic.php#object.tostring . Metoda __toString řeší něco jiného než předání tvého vlastního stringu
Brzdi. Objekty se do konstruktorů běžně předávají - bez toho bys neudělal DI. Nadužívání dědičnosti tady řešíme stále, konkrétně v uvedeném případě dědičnost své místo nemá. Metoda __toString() může poskytovat jakýkoli řetězec, který uzná za vhodné.
-
Žádnou chybu nevidím..
Metoda _toString() má vracet řetězec. Místo toho jí dáváš objekt $this->b, což řetězec rozhodně není. Musíš ho přetypovat na string nebo zřetězit za ''.
-
... tak jde o to, že kámen úrazu je to, že
se nedají volat z metody __toString() jiné metody, teda dají ale změny se neprojeví v objektu.
Hehe, to je docela zajímavé gotchas, tuhle ještě neznám.
Podle všeho to vypadá, že se prostě jenom vyhodnocují volání těch dvou argumentů v opačném pořadí (tedy odzadu), než jak by si čekal. Stačí přidat přetypování:
class C{
public function __toString(){
return ((string)$this->b) . $this->a->v;
}
}
Každopádně taky mi to přijde na můj vkus dost překombinovaný.
-
Já pořád nechápu, proč tedy řešíte (string)? Není problém v tom, že by to nevracelo string, je problem v tom výsledku, stejná konstrukce a výsledek je 1 ale očekávaný výsledek je 2.
-
Já pořád nechápu, proč tedy řešíte (string)? Není problém v tom, že by to nevracelo string, je problem v tom výsledku, stejná konstrukce a výsledek je 1 ale očekávaný výsledek je 2.
No tak evidentně to tak úplně stejná konstrukce není, když se to chová jinak, že jo.
-
Já pořád nechápu, proč tedy řešíte (string)? Není problém v tom, že by to nevracelo string, je problem v tom výsledku, stejná konstrukce a výsledek je 1 ale očekávaný výsledek je 2.
Místo výpočtu a převodu na string je předán přímo ten objekt. Operace se tedy neprovede, protože to jsi po tom objektu nechtěl.
Porušuješ základní pravidlo: Metoda má něco dělat (procedura) nebo vracet stav (funkce). Nikdy obojí současně.