PHP8.1.0からグローバル変数の連想配列 $GLOBALS の丸ごと書き換えはエラーになります。変数への代入だけでなく、丸ごと書き換えになりそうなものはすべて。
というか、そんなことする人いたんだ。
$GLOBALSには $_GET や $_POST などの情報もあるので、クラッシャー的行為だと思うんだけど。
まずはサンプルコードを見てもらいましょう。
<?php
echo 'before: ';
var_dump($GLOBALS);
$GLOBALS = array();
echo 'after:: ';
var_dump($GLOBALS);
かんたんなプログラムです。$GLOBALSを空配列で初期化しました。その前後に結果を出力するようにダンプを入れてます。
まずは、PHP8.0 での実行結果から。
before: array(8) {
["_GET"]=>
array(0) {
}
・
省略
・
["GLOBALS"]=>
*RECURSION*
}
after:: array(0) {
}
次に、PHP8.1での実行結果です。
PHP Fatal error: $GLOBALS can only be modified using the $GLOBALS[$name] = $value syntax in /home/vagrant/php8-test/variables-globals.php on line 6
グローバル変数の値を変えるなら、ちゃんと変数($GLOBALS配列の要素名)を指定しなさいというシンタックスエラーが出るようになります。
というか、それまでできちゃってたんだという印象。
そもそも、$GLOBALS を直接編集することはよくありませんし、グローバルならその変数を使うべきだし、ローカルなら globalキーワードを使うべき。
よっぽど使わないといけない場面がないかぎり、$GLOBALSを直接変更するのは止めようというのがボク個人の意見。
(使う場面は絶対ないとは言わないが、経験上使う必要になったことはない。)
そういうコーディング規約を設けてるところも結構あると思います。
グローバル変数は極力作らないというのがボクの考え。できるならゼロにしたいくらい。
グローバルな共通データを持たせたければ、それ用にクラスを作ってその中にデータを隠蔽させたほうがセキュリティ上いい。
そのグローバル用クラスをグローバル変数にする必要もない。
シングルトンクラスや static なものにすればいいから。
(理想は。)
$GLOBALS のリファレンス作成の禁止
$GLOBALS 全体を書き換える代入だけではありません。全体を書き換える可能性のある作業はすべてエラーになります。
たとえばリファレンス作成の禁止。
<?php
$globals =& $GLOBALS;
PHP Fatal error: Cannot acquire reference to $GLOBALS in /home/vagrant/php8-test/variables-globals.php on line 3
その他のエラー
リファレンス以外ではこのようなものがエラーになります。
<?php
$GLOBALS += [];
$GLOBALS =& $x;
unset($GLOBALS);
array_pop($GLOBALS);
エラー内容はすべて『PHP Fatal error: $GLOBALS can only be modified using the $GLOBALS[$name] = $value syntax』。
これらはあくまで例で、エラーになるものは他にもあります。
(全部列挙してたらきりがない。)
PHP公式ドキュメント