Аз сте инсталирали PHP 5.2 в един от моите тестване компютри днес и няколко бита на код, който преди това работеше добре във версия 5.1.6 хвърли фатално грешки в новата версия. Съобщението за грешка е "Разполагане ниво твърде дълбоко - рекурсивна зависимост?"И го взеха малко време
В PHP има два Оператори за сравнение, == И ===. Това е общоизвестно, че първият не е строго за тип, но втората е. Така, например
ехо ( фалшиви == 0 ); // вярно
ехо ( фалшиви === 0 ); // лъжлив
- 0 е цяло число и фалшивите е булева
Моят проблем произтича от използването на не-строги пишете с обекти.
$a = new MyObj();
$b = new MyObj();
ако( $a == $b )
…
Аз не смятам това, което правя с този код. При сравняване на два обекта да използвам строг сравнение оператор (==) PHP сравнява всички свойства на обекти и ако те отговарят на обекти, се считат за равни. Ако те не съвпадат те не са равни. В сила, В момента има рекурсивен сравнението на всички свойства на всеки обект, и всичките им свойства, др. докато не достигнем основните типове данни, като низове и числа.
If, обаче, използва строги сравнение (===), PHP ще проверява дали два обекта са едни и същи обект, не само обекти със същите свойства.
клас MyObj
{
обществени $ P;
}$a = new MyObj();
$b = new MyObj();
$c = new MyObj();
$a->P = 1;
$b->P = 1;
$c->P = 2;
ехо ( $a == $c ); // лъжлив
ехо ( $a == $b ); // вярно
ехо ( $a === $b ); // лъжлив
Проблемът възниква, ако имате кръгови препратки в обекти имоти. Така, например
клас MyObj
{
обществени $ P;
}
клас OtherObj
{
обществени $ р;
}$a = new MyObj();
$b = new OtherObj();
$a->P = $ б;
$b->Q = $ едно; // на кръгова препратка: $a->p->=== Р $ милион$c = new MyObj();
$d = new OtherObj();
$c->P = $ г;
$d->Q = $ в;// друга кръгова препратка: $c->p->р $ в ===ехо ( $a == $c ); // Фатална грешка:
Nesting level too deep – рекурсивна зависимост?
За да се сравни $ милион долара в, PHP трябва да сравнят своите свойства. Така че логиката в PHP е нещо подобно: $a == $c if $a->p == $c->p if $a->p->q == $c->p->q if $a->p->q->p == $c->p->q->п и т.н.. за неопределено време.
PHP 5.1 изглежда гладко над проблема по някакъв начин (Вероятно след определено ниво на рекурсия тя просто връща фалшиви) – и обикновено то работник се оправи. PHP 5.2 правилно произвежда фатална грешка по-горе.
След като разберете на проблема, решението е лесно – използване строго сравнение.
ехо ( $a === $c ); // лъжлив (и не е допуснал грешка)
Стриктният сравнение просто ще проверява дали два обекта са по едно и също място в паметта и по този начин дори не погледнете стойностите на имотите.
NB. Същият проблем може да възникне при използване на обект на отрицание оператори сравнение (употреба !== Вместо !=) и при използване на in_array (трети параметър употреба in_array да посочи строго сравнение).
