Archive for the ‘Modulecategory

PHP Ошибка вложенности слишком глубоко рекурсивных зависимостей уровня

12 марта, 2010

Я установил PHP 5.2 в одном из моих тестирования компьютеров сегодня и пара битов кода, который ранее работал штрафа в версии 5.1.6 бросил фатальных ошибок в новой версии. Сообщение об ошибке было «уровень вложенности слишком глубоко – рекурсивных зависимостей?«и она занимает немного времени

чтобы отслеживать вниз корень проблемы. Вот что я сделал неправильно.

В PHP есть два оператора сравнения, == и ===. Общеизвестно, что первый не является строгой о типе но второй. Так, Например

Эхо ( значение false == 0 ); // значение true

Эхо ( ложных === 0 ); // значение false

– 0 представляет собой целое число и ложное логическое

Моя проблема возникла с использованием не строгой типизации с объектами.

$= Новая MyObj();
$b = новый MyObj();
Если( $== $b )

Я не рассматривал, что я делал с этим кодом. При сравнении двух объектов с помощью оператора сравнения-строгое (==) PHP сравнивает все свойства объектов и если они совпадают объекты считаются равными. Если они не совпадают они не равны. В силу, у нас есть рекурсивное сравнение всех свойств каждого объекта, и все их свойства, и т.д.. пока мы не достигнем базовые типы данных как целые числа и строки.

Если, Однако, Мы используем строгие сравнение (===), PHP будет проверять, являются ли два объекта один и тот же объект, не только объекты с одинаковыми свойствами.

класс MyObj
{
общественность $p;
}

$= Новая MyObj();
$b = новый MyObj();
$c = новый MyObj();
$->p = 1;
$b->p = 1;
$c->p = 2;
Эхо ( $== $c ); // значение false
Эхо ( $== $b ); // значение true
Эхо ( $=== $b ); // значение false

Проблема возникает, если у вас есть циклических ссылок в свойствах объектов. Так, Например

класс MyObj
{
общественность $p;
}
класс OtherObj
{
общественность $q;
}

$= Новая MyObj();
$b = новый OtherObj();
$->p = $b;
$b->q = $a; // циклические ссылки: $->p->q === $a

$c = новый MyObj();
$d = новый OtherObj();
$c->p = $d;
$d->q = $c;// еще одна циклическая ссылка: $c->p->q === $c

Эхо ( $== $c ); // Неустранимая ошибка:
Слишком глубокий уровень вложенности – рекурсивных зависимостей?

Для того чтобы сравнить $a $c, PHP необходимо сравнить их свойства. Таким образом, логика в PHP идет что-то вроде этого: $== $c если $a ->p == $c ->p если $a ->p->q == $c ->p->q если $a ->p->q->p == $c ->p->q->p и т.д.. бессрочно.

PHP 5.1 казалось, как-то сгладить проблемы (Наверное после определенного уровня рекурсии он просто вернулся ложных) – и обычно он работал штрафа. PHP 5.2 правильно производит Неустранимая ошибка выше.

После того, как вы знаете, проблема, решение легко – использование строгого сравнения.

Эхо ( $=== $c ); // значение false (и ошибка не)

Строгого сравнения просто проверить, являются ли два объекта в том же месте в памяти и поэтому даже не смотреть на значения свойств.

N.B. Такая же проблема может возникнуть при использовании операторов сравнения Инвертированное (Использование !== Вместо !=) и при использовании in_array (in_array в третий параметр используется для указания строгого сравнения).