Tiêu đề có vẻ hơi ngớ ngẩn nhưng tôi hoàn toàn nghiêm túc với điều này. Hôm nay tại nơi làm việc tôi đã bắt gặp một hành vi kỳ lạ của PHP mà tôi không thể giải thích. May mắn thay, hành vi này được sửa trong PHP 7.4, vì vậy dường như ai đó cũng vấp phải điều đó.
Tôi đã làm một ví dụ nhỏ để minh họa những gì đã sai:
<?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);
Chạy mã này tại đây: https://3v4l.org/DBt3o
Đây là một lời giải thích về những gì đang xảy ra ở đây. Chúng ta phải học lớp A và B, cả hai đều có chung một tài sản $a
. Độc giả cẩn thận nhận thấy rằng tài sản $a
có hai tầm nhìn khác nhau (công khai, riêng tư). Không có gì lạ mắt cho đến nay. Phép thuật xảy ra trong __sleep
phương thức được gọi một cách kỳ diệu khi chúng serialize
ta ví dụ. Chúng tôi muốn có tất cả các biến đối tượng mà chúng tôi nhận được với việc get_object_vars
giảm chỉ còn các khóa với array_keys
và xuất mọi thứ với var_dump
.
Tôi mong đợi một cái gì đó như thế này (điều này xảy ra kể từ PHP 7.4 và là đầu ra mong đợi của tôi):
array(2) {
[0]=>
string(1) "b"
[1]=>
string(1) "a"
}
Nhưng những gì tôi nhận được là đây:
array(3) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[2]=>
string(1) "a"
}
Làm thế nào có thể, PHP cung cấp một mảng với hai khóa hoàn toàn giống nhau? Ai có thể giải thích những gì xảy ra ở đây bởi vì trong PHP đơn giản, tôi không thể tạo ra một mảng với hai khóa hoàn toàn giống nhau? Hay tôi bỏ lỡ một cái gì đó rõ ràng ở đây?
Đồng nghiệp của tôi lúc đầu không muốn tin tôi nhưng không ai trong số họ có lời giải thích tốt về điều này sau khi họ hiểu chuyện gì đang xảy ra ở đây.
Tôi thực sự rất thích nhìn thấy một lời giải thích tốt.
var_dump(array_keys((array)$this));