Unë e kam instaluar PHP 5.2 në një nga kompjuterat e mia testimi sot dhe nja dy copa të kodit që më parë ka punuar mirë në versionin 5.1.6 hodhi gabime fatale në versionin e ri. Mesazhi i gabimit është "niveli Folezojnë shumë të thellë - recursive varësisë?"Dhe u desh pak kohë
Në PHP ka dy operatorë krahasim, === == Dhe. Është e njohur se e para nuk është e rreptë në lidhje me llojin, por e dyta është. Kështu, për shembull
jehonë ( == false 0 ); // i vërtetë
jehonë ( === rreme 0 ); // rreme
- 0 është një numër i plotë dhe të rreme është një boolean
Problemi im u ngrit nga përdorimi i të shtypni jo të plotë me objekte.
$a = new MyObj();
$b = new MyObj();
nëse( $a == $b )
…
Unë nuk e kishte konsideruar se çfarë bëja me këtë kod. Kur krahasojmë dy objekteve duke përdorur operatorin e jo-strikte krahasim (==) PHP krahason të gjitha pronat e objekteve dhe nëse ata përputhen me objekte të cilat konsiderohen të jenë të barabartë. Nëse ata nuk përputhen me ato nuk janë të barabartë. Në fakt, ne kemi një krahasim recursive e të gjitha pronave të secilit objekt, dhe të gjitha pronat e tyre, etj. derisa të arrijmë të dhënat bazë lloje si vargjet dhe numra të plotë.
If, megjithatë, ne përdorim krahasim të rreptë (===), PHP do të kontrollojë nëse të dy objektet janë pikërisht të njëjtin objekt, jo vetëm objekte me pronat e njëjtë.
MyObj klasë
{
p publik $;
}$a = new MyObj();
$b = new MyObj();
$c = new MyObj();
$a->p = 1;
$b->p = 1;
$c->p = 2;
jehonë ( $a == $c ); // rreme
jehonë ( $a == $b ); // i vërtetë
jehonë ( $a === $b ); // rreme
Problemi lind në qoftë se ju keni referenca rrethore në objekte tuaj pronat. Kështu, për shembull
MyObj klasë
{
p publik $;
}
OtherObj klasë
{
publike $ q;
}$a = new MyObj();
$b = new OtherObj();
$a->p = $ b;
$b->q = $ a; // referencë rrethore: $a->p->=== Q $ a$c = new MyObj();
$d = new OtherObj();
$c->p = $ d;
$d->q = $ c;// një referencë rrethore: $c->p->q $ c ===jehonë ( $a == $c ); // Gabim fatal:
Nesting level too deep – varësisë recursive?
Në mënyrë për të krahasuar $ në të c $, PHP duhet të krahasoni pronat e tyre. Pra, logjika e në PHP shkon diçka si kjo: $a == $c if $a->p == $c->p if $a->p->q == $c->p->q if $a->p->q->p == $c->p->q->p etj. një kohë të pacaktuar.
PHP 5.1 dukeshin të qetë mbi këtë problem disi (ndoshta pas një nivel të caktuar të recursion ai thjesht u kthye të rreme) – dhe zakonisht ai ka punuar jashtë gjobë. PHP 5.2 korrekte prodhon gabim fatal lart.
Pasi ju e dini problemin, zgjidhja është e lehtë – përdorim krahasim rreptë.
jehonë ( $a === $c ); // rreme (dhe pa gabim)
Krahasimi i rreptë thjesht do të kontrollojë nëse të dy objektet janë në të njëjtin vend në kujtesën dhe kështu nuk i shoh edhe vlerat e pronave.
NB. Të njëjtin problem mund të lindin gjatë përdorimit të operatorëve mohuar krahasim (përdorim !== Në vend të !=) dhe kur përdoret in_array (parametër i tretë in_array përdorë për të treguar krahasim të rreptë).
