Autor Zpráva
WanTo
Profil
Nechápu a nemám rád PHP.

Takto vypadá jedna část mé aplikace:


$currentElement = null;

function set_element(&$element) {
global $currentElement;
$currentElement =& $element;
}
function & get_element() {
global $currentElement;
return $currentElement;
}


Není v tom žádná věda - tyto dvě funkce jen poskytují přístup ke globální proměnné $currentElement. Teďka k problému:

Uložím do globální proměnné $currentElement pomocí funkce set_element objekt typu Element. Pak tenhle objekt získám pomocí metody get_element() a pokusím se na něm volat metodu insert(). Ovšem PHP skončí s hláškou, že třída stdClass nemá žádnou metodu insert() definovanou. (!?) Proboha, jak je možné, že PHP zapomnělo typ proměnné? Vždyť já jsem tam ukládal objekt typu Element, ne nějaký stdClass.

Nemáte někdo tušení, kde je chyba? Jestli mezi židlí a klávesnicí nebo v PHP (verze 5)?
MiSHAK
Profil
Proč je před get_element ampersand(&)?
WanTo
Profil
MiSHAK
Vrací odkaz na $currentElement. V tom by problém být neměl.
ronnie
Profil
http://us2.php.net/variables.scope#language.variables.scope.references

Pro klonování na PHP 5 se používá clone. Třída stdClass je defaultní třídou v php...
WanTo
Profil
ronnie
Jakou to má souvislost s mým problémem? Nikde nic neklonuji.

(že je stdClass defaultní třídou v PHP, vím)
ronnie
Profil
To, co používáš, je zbytečnost. Jinak podívej se na ten odkaz, nebo použij Google.
WanTo
Profil
ronnie
Já vím, že to jde řešit jen přes vložení global $currentElement do každé funkce, co $currentElement používá - tohle jsi měl na mysli?

Každopádně i když to tak udělám, zůstává tu pořád stejný problém.
ronnie
Profil
Pro globální proměnné bych používal návrhový vzor Registry, pak není nutné používat globální proměnné přes global nebo $GLOBALS, viz třeba http://www.patternsforphp.com/wiki/Registry.
WanTo
Profil
ronnie
Proboha, já se nepotřebuju zabývat žádnými návrhovými vzory. Já chci uložit objekt do globální proměnné. Přidávat kvůli jedné globální proměnné v programu, co má 100 řádků, další složitou třídu? Děkuji, nechci.

Omluv můj rozladěný tón; jsem sice rád, že se mi snažíš pomoct, ale zatím pomáháš úplně s něčím jiným.
ronnie
Profil
Tak, jak jsem psal, se řeší ukádání globálních proměnných v objektech, aby se dalo vyhnout podobným problémům.

Já nechápu, k čemu potřebuješ ty funkce a proč vůbec kombinuješ funkce a objekty, když je to program na 100 řádků. Jediné, co ty funkce dělají je, že vytvářejí kopie, ne? A k tomu snad není potřeba vytvářet funkce...anebo jsem už přepracovaný a vidím něco jiného...snad ti někdo jiný poradí;)

Edit: ne kopii, ale odkaz.
WanTo
Profil
ronnie
Funkce get_element vrátí odkaz na objekt a set_element ten objekt nastaví. Je to vlastně stejné, jako přímý přístup ke globální proměnné. Nicméně nefunguje ani jedno - pořád PHP hlásí stejnou chybu o tom, že ve třídě stdClass nebyla definována metoda insert().

Jestli tu není jiná možnost, než použít Registry, tak se bez něj asi opravdu neobejdu. Použiju Registry a budu si myslet o PHP něco hodně ošklivého.
WanTo
Profil
Co se týče té kombinace funkcí a objektů, tak ten program pracuje nad stromem prvků a použití objektů je nejjednodušší způsob, jak tuhle datovou strukturu implementovat.
ronnie
Profil
Ráno moudřejší večera:)

Místo global použij $GLOBALS a bude to fungovat.


$currentElement = null;

function set_element(&$element) {

$GLOBALS['currentElement'] =& $element;

}

function & get_element() {

return $GLOBALS['currentElement'];

}

class Element
{
public function insert() { return 1;}
}

set_element(new Element);
$hodnota = get_element();

echo $hodnota->insert(); //vypíše 1
WanTo
Profil
ronnie
Díky za nakopnutí správným směrem. Chyba byla sice ještě trochu jinde, ale PHP teďka aspoň napsalo inteligentní chybovou hlášku, ze které se dalo poznat, co není v pořádku. Ale chování PHP, když se nepoužívá $GLOBALS[], mi pořád zůstává záhadou.
Toto téma je uzamčeno. Odpověď nelze zaslat.