ツイート
シェア
LINEで送る
B! はてぶでブックマーク
Pocketでブックマーク
RSSフィード

PHP8.1, $GLOBALSの丸ごと書き換えはエラーになる

php
イラストダウンロードサイト【イラストAC】
の画像をもとに加工しています。

PHP8.1.0からグローバル変数の連想配列 $GLOBALS の丸ごと書き換えはエラーになります。変数への代入だけでなく、丸ごと書き換えになりそうなものはすべて。

というか、そんなことする人いたんだ。

$GLOBALSには $_GET や $_POST などの情報もあるので、クラッシャー的行為だと思うんだけど。

まずはサンプルコードを見てもらいましょう。

<?php

echo 'before: ';
var_dump($GLOBALS);

$GLOBALS = array();

echo 'after:: ';
var_dump($GLOBALS);

かんたんなプログラムです。$GLOBALSを空配列で初期化しました。その前後に結果を出力するようにダンプを入れてます。

まずは、PHP8.0 での実行結果から。

PHP8.0の結果
before: array(8) {
  ["_GET"]=>
  array(0) {
  }
  ・
  省略
  ・
  ["GLOBALS"]=>
  *RECURSION*
}
after:: array(0) {
}

次に、PHP8.1での実行結果です。

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;
PHP8.1の実行結果
PHP Fatal error:  Cannot acquire reference to $GLOBALS in /home/vagrant/php8-test/variables-globals.php on line 3

その他のエラー

リファレンス以外ではこのようなものがエラーになります。

PHP8.1でエラーになるもの
<?php

$GLOBALS += [];

$GLOBALS =& $x;

unset($GLOBALS);

array_pop($GLOBALS);

エラー内容はすべて『PHP Fatal error: $GLOBALS can only be modified using the $GLOBALS[$name] = $value syntax』。

これらはあくまで例で、エラーになるものは他にもあります。

(全部列挙してたらきりがない。)

PHP公式ドキュメント

Variables - GLOBALS

前の投稿
PHP8, パラメータやリターン値が変わる関数。リターン値の判定は注意が必要。
PHP8.1, '=' での $GLOBALS の代入は参照渡しでなくなる。読込専用のコピー。
次の投稿

コメントを残す