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

4 reakce na “Znáte stdClass v PHP? A jaké podivností s tím jdou dělat”

  1. bigbart napsal:

    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.

  2. bigbart napsal:

    Tak kromě NULLu toto přetypování na stdClass ještě funguje pro proměnou nastavenou na false ale už nikoliv na true :o ) Fakt dobrý

  3. MarekN napsal:

    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;
    }

  4. bigbart napsal:

    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 :)

Zanechte svůj komentář