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

PHP8.1, '=' での $GLOBALS の代入は参照渡しでなくなる。読込専用のコピー。

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

グローバル変数の連想配列変数($GLOBALS)を代入した変数の値を変更すると、$GLOBALS にまで反映されるんですが、PHP8.1.0 からできなくなりました。

え? そんなことできてたの? と思った人もいるでしょう。

むしろ、PHP8.1ではまともになったじゃんって思う。

普通の連想配列では、代入した変数値を変更すると元の変数配列には変更されません。代入する側の変数とされる側の変数は代入したときの値は同じでも全く別物だから。

(値のコピー。)

でも $GLOBALS ではちがいました。

<?php

$g_test = 'sample';

$globals = $GLOBALS;

$globals['g_test'] = 'change';

echo 'globals value: ' . $globals['g_test'] . PHP_EOL;
echo 'GLOBALS value: ' . $GLOBALS['g_test'] . PHP_EOL;
PHP8.0での実行結果
globals value: change
GLOBALS value: change
PHP8.1での実行結果
globals value: change
GLOBALS value: sample

普通、イコール(=)での代入は左辺変数へのコピーで左右は独立しています。むしろPHP8.1での変更は他の連想配列と同じ動きになるで分かりやすくなりました。

というか、なんで $GLOBALS はこうなってたんだろう。

PHP公式のリファレンスでも不思議な記述があります。

// PHP 8.1.0 より前の振る舞い
$a = 1;
$globals = $GLOBALS; // 建前上は値渡しのコピー
$globals['a'] = 2;
var_dump($a); // int(2)

(『建前上は』って...。意味深な内容。)

$GLOBALS はリファレンスではありません。動きとしてはクラスのオブジェクトに近い。(内部の仕組みはどうなってるか分からない。)

PHP8.1は2021年11月25日にリリースされたばかりなので、この不思議な動きをするバージョンを使ってる人は多いと思います。

気をつけましょう。

ちなみにPHP8.1で同じようなことはできません。$GLOBALS のリファレンス作成はPHP8.1からエラーになるから。

そもそも、$g_test で変更すればいいじゃんという話です。(ローカルスコープなら global $g_test)

PHP公式ドキュメント

Variables - GLOBALS

前の投稿
PHP8.1, $GLOBALSの丸ごと書き換えはエラーになる
PHP8.1, Enum(列挙型)の追加。定数専用のクラス。
次の投稿

コメントを残す