Znáte stdClass v PHP? A jaké podivností s tím jdou dělat
Už nějaký ten pátek se věnuju programování v PHP. Jestli mě paměť neklame, tak prvně jsem přičichl k PHP 3 někdy v roce 1998/99. Za dobu co v něm dělám mě několikrát překvapil, a dnes opět, i když né zrovna mile.
Dnešní záhada byla asi takováto, nemohl jsem najít, kam se mi ztrácí či proč je jakoby podivně “prázdná” (bez metod které obvykle má) instance jednoho objektu a proč je instance odvozena od záhadné třídy stdClass.
Po asi půlhodinovém hledání jsem záhadě přišel na kloub. Problém byl ale úplně někde jinde a to v pokusu nastavit vlastnost objektu, aniž by tato instance skutečně existovala (jasně že se jedná o školáckou chybu , ale stalo se).
Výsledek byl velmi překvapující, níže je kus ukázkového kódu, který je funkční ve verzi PHP 5.2.12
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <?php // prazdna trida s vlastnosti id class myClass { public $id; } // funkce nastavi vlastnost id libovolne instanci function addPropertyId(&$instance, $id) { $instance->id = $id; } // bezne pouziti nad existujici instanci $normal = new myClass(); addPropertyId($normal,1); var_dump($normal); // jak clovek ceka instance tridy myClass /* object(myClass)#1 (1) { ["id"]=> int(1) } */ // no a ted trochu magie :o) ano $magie neni objektem $magie = NULL; // nastavime si id addPropertyId($magie,2); var_dump($magie); // POZOR vraci instanci stdClass ! /* object(stdClass)#2 (1) { ["id"]=> int(2) } */ ?> |
No a kde se nám tedy vzala ta třída stdClass, když $magie není přece objekt ale NULL ? Trochu to osvětlí příspěvek na php.net, kde je podstatná informace:
stdClass is the default PHP object. stdClass has no properties, methods or parent. It does not support magic methods, and implements no interfaces.
Tedy že strClass je defaultní objekt v PHP, který nejde navíc ani předefinovat v kódu.
Magie je totiž zdá se v objektovém operátoru -> a přetypování NULL na objekt (type casting) – kde jinde by se tedy vzal objekt, když jsme žádný nenastavovali ?
Takže je dobré si raději kontrolovat, dřív než začneme nastavovat nějakou vlastnost, zda jde o instanci objektu s kterým chceme pracovat. Samotná funkce is_object() nám totiž po nastavení jakékoli vlastnosti může již celkem kecat – vznikne nám objekt stdClass z neobjektu
PS: Na webu Jakuba Vrány je i pěkný příklad použití pole k přetypování na stdClass objekt
20. Červenec 2010 09:17
Vtip je v tom, že je-li $magic cokoliv jiného než NULL (string, integer atd.) zakřicí php alespoň warning “PHP Warning: Attempt to assign property of non-object in Command line code on line xxx” a o chybě se dozvíte z logu.
20. Červenec 2010 09:24
Tak kromě NULLu toto přetypování na stdClass ještě funguje pro proměnou nastavenou na false ale už nikoliv na true ) Fakt dobrý
28. Leden 2011 23:19
Predpokladam, ze funkce addPropertyId(&$instance, $id) tam neni jen tak obecne a vis kterej objekt do ni chces cpat, tak zkus:
function addPropertyId(myClass &$instance, $id) {
$instance->id = $id;
}
28. Leden 2011 23:40
Marku to byl jen modelovy pripad Na omezeni na instanci konkretni tridy jsem fakt nepomyslel, protoze v tomto pripade by ta funkce addPropertyId totalne ztracela smysl pro libovolnou instanci libovolne tridy. Uz z logiky veci by jinak byla metodou te classy myClass a nevisela by jen tak v prostoru