Problém s __call
- Vyki
- Člen | 388
Zdravím, narazil jsem na zvláštní chování magické metody
__call
tříd, které dědí od třídy Object
.
Pokud mám:
<?php
class MojeKomponenta extends Control
{
public function __call($name, $arguments)
{
if(preg_match(('/^catch(\w+)*$/'), $name, $match))
{
$name = strtolower($match[1]);
}
parent::__call($name, $arguments);
}
public function test()
{
echo 1;
}
}
?>
Pokud spustím s catchTest
laděnka se zastaví na řádku s
parent::__call($name, $arguments)
a vypíše
MemberAccessException Call to undefined method MojeKomponenta::test()
.
Neřešil bych tu k čemu to používám, spíše jsem to jenom zkoušel, ale
přijde mi divné, že mě to upozorňuje na neexistující metodu, která ve
skutečnosti existuje. Je to očekávané chování? Díky za radu.
Editoval Vyki (8. 3. 2010 23:16)
- Ondřej Mirtes
- Člen | 1536
A copak ta metoda v rodiči existuje? :) Podle mě je to naprosto správné chování, jaké jiné chování by sis představoval?
Ty ve své metodě __call definuješ, co se má stát, pokud někdo zavolá metodu catch*. Jak bys tam chtěl vyjádřit možnost, že někdo zavolá, kterou ani magicky nedefinuješ v __call? Kdybys tam nevolal toho parenta, tak se nestane nic, žádná chybová hláška a uživatel (tvojí třídy) se nic nedozví.
Pokud chceš docílit chování, že když někdo zavolá catchTest, tak se
má zavolat test(), tak pod to nastavení proměnné $name dej
$this->$name()
.
- norbe
- Backer | 405
Ty sice upravíš hodnotu $name
z catchTest
na
test
, ale to že zavoláš parent::__call
neznamená,
že se bude zkoušet volat metoda daného názvu.
Pokud chceš využít __call
k upravení názvu metod, musíš
pak požadovanou metodu sám zavolat, tj. něco jako
$this->$name()
.
Edit: Pozdě :-)
Editoval norbe (8. 3. 2010 23:30)
- Vyki
- Člen | 388
Ondřej Mirtes napsal(a):
A copak ta metoda v rodiči existuje? :) Podle mě je to naprosto správné chování, jaké jiné chování by sis představoval?
Jasně to beru a je to logické, ale nechápu pak tu chybovou hlášku, která mi neříká, že není definována ta metoda v rodiči. Ta hláška říká, že metoda není definována v potomkovi, kde ovšem definována ve skutečnosti je.
- Vyki
- Člen | 388
norbe napsal(a):
Pokud chceš využít__call
k upravení názvu metod, musíš pak požadovanou metodu sám zavolat, tj. něco jako$this->$name()
.
To $this->$name()
jsem také předtím zkoušel a to šlapalo
v pohodě, jenom jsem myslel, zda by to přece jenom nešlo s tím
__call
. Dost mě zmátla ta chybová hláška.