Название может показаться немного глупым, но я абсолютно серьезно отношусь к этому. Сегодня на работе я натолкнулся на странное поведение PHP, которое я не мог объяснить. К счастью, это поведение исправлено в PHP 7.4, поэтому кажется, что кто-то тоже наткнулся на это.
Я сделал небольшой пример, чтобы проиллюстрировать, что пошло не так:
<?php
class A {
private $a = 'This is $a from A';
public $b = 'This is $b from A';
public function __sleep(): array
{
var_dump(array_keys(get_object_vars($this)));
return [];
}
}
class B extends A
{
public $a = 'This is $a from B';
}
$b = new B;
serialize($b);
Запустите этот код здесь: https://3v4l.org/DBt3o
Вот небольшое объяснение того, что здесь происходит. У нас есть классы A и B, которые оба имеют свойство $a
. Внимательные читатели заметили, что свойство $a
имеет две разные видимости (публичная, частная). Пока ничего особенного. Магия происходит в методе __sleep
, который волшебным образом вызывается, когда мы serialize
делаем наш экземпляр. Мы хотим, чтобы все переменные объекта, которые мы получаем с помощью get_object_vars
, уменьшили это значение до ключей с array_keys
и вывели все с помощью var_dump
.
Я ожидал бы что-то подобное (это происходит с PHP 7.4). и это мой ожидаемый результат):
array(2) {
[0]=>
string(1) "b"
[1]=>
string(1) "a"
}
Но что я получаю, это:
array(3) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
string(1) "a"
}
Как может быть, что PHP предоставляет массив с двумя полностью идентичными ключами? Кто может объяснить, что здесь происходит внутри, потому что в простом PHP я не могу создать массив с двумя полностью идентичными ключами? Или я что-то упускаю здесь очевидное?
Мои коллеги сначала не хотели мне верить, но ни у кого из них не было хорошего объяснения этому после того, как они поняли, что здесь происходит.
Я действительнохотел бы увидеть хорошее объяснение.