Mirin webspace

Nejbohatší život má ten, kdo žije s minimem nároků

22. 6. 2008 - Komentáře (1) PHP

Objektové proměnné nejsou reference

Možná je to zbytečný článek, ale přece jen mě to trochu nedalo. Je zažitá představa, že s příchodem PHP5 se instance objektů chovají jako reference na objekty, kdežto v PHP4 se chovaly jako primitivní typy a téměř všude se proto musely reference ošetřovat ručně. Nicméně není tomu tak úplně.

Se zavedením PHP5 přišel i nový objektový model, ve kterém PHP v mnohém převzalo chování objektů podle jazyka Java. Nedá se však říci, že je toto chování totožné s chováním instancí (objektových proměnných) jako referencí tak, jak reference chápe PHP. Spíše je vhodné se o objektových proměnných vyjadřovat jako o "handle", než jako o referencích. Reference je proti tomu jen jiné označení pro tutéž proměnnou. S tím souvisí jiné chování při přiřazování objektových proměnných a referencí.

Class Object{
   public $foo="bar";
};
 
//vytvoření objektové proměnné - handle na objekt
$objectVar = new Object();
//vytvoření reference na proměnnou $objectVar
$refObjVar =& $objectVar;
//kopie objektové proměnné
$copyObjVar = $objectVar;

Vnitřně to v jádře PHP bude vypadat nějak takto

 $objectVar --->+---------+
                |(handle1)----+
 $refObjVar --->+---------+   |
                              |
                +---------+   |
 $copyObjVar -->|(handle1)----+
                +---------+   |
                              |
                              v
                  Object(1):foo="bar"

Zde je vidět, že přiřazením vzikla kopie handle na původní objekt, která se od reference liší, při nakládáním s objektem se však chová jako reference. Po tomto

$objectVar->foo = "qux";

bude v $refObjVar->foo i $copyObjVar->foo řetězec qux.

Ale pozor, pokud nyní provedeme přiřazení hodnoty null do původní objektové proměnné

$objectVar = null;

tak null bude i reference ($refObjVar), ale nikoli kopie objektové proměnné ($copyObjVar).

 $objectVar --->+---------+
                |(NULL)----+
 $refObjVar --->+---------+   
                              
                +---------+   
 $copyObjVar -->|(handle1)----+
                +---------+   |
                              |
                              v
                  Object(1):foo="bar"

Nedojde tedy k uvolnění paměti pro objekt. Takové chování je v pořádku, nicméně v PHP vznikají problémy z toho, že v PHP4 se všude při práci s objekty uváděly reference a uživatelé mají vžitou představu v tom, že v PHP5 je to to samé, jen už tam ty reference psát nemusí a když je tam náhodou napíší, bude se to chovat stejně, což může být zdrojem chyb. Doporučuji tedy na použití referencí (znaku &) ve spojitosti s objekty v PHP5 zapomenout.


Komentáře (1)

  1. dafodil - 23. 6. 2008 12:00

    Jsem rad ze to nekdo osvetlil - konecne detailni popis chovani, dik.

Komentáře jsou uzavřeny.