Неожиданный результат при сравнении объектов PHP
Когда я сравнивал два разных объекта, он сначала возвращает true
, а после print_r
(по объектам) возвращается false
.
Из руководства PHP:
Два экземпляра объекта равны, если они имеют одинаковые атрибуты и значения и являются экземплярами одного и того же класса.
Но здесь, в примере, я устанавливаю разные значения. Почему результат отличается от PHP 5.4.0 - 5.5.7?
abstract class first
{
protected $someArray = array();
}
class second extends first
{
protected $someArray = array();
protected $someValue = null;
public function __construct($someValue)
{
$this->someValue = $someValue;
}
}
$objFirst = new second('123');
$objSecond = new second('321');
var_dump ($objFirst == $objSecond);
print_r($objFirst);
var_dump ($objFirst == $objSecond);
Результат:
bool(true)
second Object ( [someArray:protected] =>
Array ( ) [someValue:protected] => 123 )
bool(false)
Но я ожидал:
bool(false)
second Object ( [someArray:protected] =>
Array ( ) [someValue:protected] => 123 )
bool(false)
Ответы
Ответ 1
Это была ошибка в PHP. Теперь он исправлен, см. commit. Короче говоря:
- Если вы расширяете класс и переопределяете одно и то же свойство,
properties_table
объекта заканчивается значением NULL.
- Сравнительный код неправильно прервал сравнение, когда два объекта имели значение NULL в
properties_table
в том же самом индексе, сообщая об объектах как равные. Разумеется, это не имеет никакого смысла, поскольку оно отбрасывает все различия в следующих свойствах. Теперь это исправлено.
- Причина, по которой
print_r
изменяет результат, заключается в том, что путем извлечения свойств объекта (get_properties
) свойства hashtable перестраиваются (rebuild_properties_table
), который использует совершенно другой (и правильный) код сравнения.
- Для контекста
properties_table
и properties
- два разных способа использования PHP для представления свойств - первый из них является более эффективным и используется для объявленных свойств, а последний используется для динамических свойств. Вызов print_r
эффективно делает свойства объекта динамическими.
Ответ 2
Хорошо, хорошо, Идентифицирован как ошибка в php https://bugs.php.net/bug.php?id=66286.
Также здесь: Неожиданный результат при сравнении объектов PHP