To ograniczenie kompilator PHP i jest opisane w documentation:
Tak jak wszelkie inne zmienne PHP statyczne właściwości elektrostatyczne mogą być inicjowane tylko przy dosłownym lub stałe przed PHP 5,6; wyrażenia są niedozwolone. W PHP 5.6 i nowszych obowiązują te same reguły, co wyrażenia const: możliwe są niektóre ograniczone wyrażenia, pod warunkiem, że mogą być oceniane podczas kompilacji.
Kluczem jest tu stwierdzenie: „pod warunkiem że mogą być oceniane w czasie kompilacji”.
Z otrzymanego komunikatu o błędzie mogę stwierdzić, że korzystasz z PHP 5. W PHP 7 komunikat o błędzie został przeredagowany w celu wyraźnego określenia problemu. Jest napisane: "Wyrażenie stałe zawiera nieprawidłowe operacje".
Deklaracja pierwszej zmiennej statycznej ($one
) kompiluje się, ponieważ zainicjowano ją ciągłym wyrażeniem. ['a','b']
to tablica łańcuchów, która może być oceniona podczas kompilacji, wszystko jest w porządku.
Druga zmienna statyczna ($two
) jest inicjalizowana przy użyciu wyrażenia niestałego (Test::$one
). Test::$one
jest zmienną. Możesz powiedzieć, że jego wartość początkowa jest znana w czasie kompilacji (patrz akapit powyżej), a wyrażenie może zostać ocenione w czasie kompilacji.
Tego rodzaju zachowanie wymaga głębszej analizy kodu w czasie kompilacji. Prawdopodobnie jest on zaimplementowany w kompilatorach C++ lub Java, ale są to języki, które są kompilowane tylko raz, a generowany przez nie kod jest przechowywany w pliku i wykonywany lub interpretowany później. Kompilator PHP nie działa w ten sposób z jakiegoś powodu. Kompiluje skrypt przed każdym wykonaniem, dlatego ma na celu ukończenie kompilacji tak szybko, jak to możliwe i nie wkłada dużego wysiłku w analizę kodu i optymalizacje.
Aktualizacja:
Jak @deceze określa w comment wyrażenie Test::$one
nie może być oceniana w deklaracji $two
ponieważ wykorzystuje klasę Test
, które nie są całkowicie określone w tym punkcie. Nawet kompilatory innych języków, które zezwalają na ten rodzaj odniesienia, nie mogą obliczyć wartości Test::$one
po osiągnięciu deklaracji $two
. Muszą użyć drugiej przepustki do kompilacji, aby móc ją ocenić.
Poza tym, 'Test :: $ one' jest po prostu niedostępny w tym miejscu, ponieważ parsowanie definicji klasy" Test "jeszcze się nie zakończyło. – deceze