浜松のWEBシステム開発・スマートフォンアプリ開発・RTK-GNSS関連の開発はお任せください
株式会社シーポイントラボ
TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:静岡県浜松市中区富塚町1933-1 佐鳴湖パークタウンサウス2F

【PHP】定義済み変数の$GLOBALSがPHPの配列なのに浅いコピーになる

 PHP には $GLOBALS という定義済み変数があります。この定義済み変数の中にはグローバルスコープで使用可能なすべての変数への参照が連想配列形式で含まれています。
PHP: $GLOBALS – Manual

 これを使うと次の様に独立したグローバルスコープの変数を書き換えられます。
Online PHP editor | output for mYtUR

<?php

$a = 'abc';
$GLOBALS['a'] = 123;
echo $a;// 123

 PHP の連想配列はどれだけネストしていようと常にディープコピーです。これは次の様に動作します。
Online PHP editor | output for qufjX

<?php

$arr=[
    'a' => [
        'b' => 3,
    ]
];
$arrCopy = $arr;
$arrCopy['a']['b'] = 12;
var_dump($arr);
var_dump($arrCopy);
/*
array(1) {
  ["a"]=>
  array(1) {
    ["b"]=>
    int(3) // コピー元は書き換わらない
  }
}
array(1) {
  ["a"]=>
  array(1) {
    ["b"]=>
    int(12) // こちらだけ書き換わる
  }
}
*/

 それぞれは全く妥当な挙動なのですが組み合わさると、連想配列であるのに浅いコピーの様な不思議な挙動をします。
この挙動は次の様に起きます。
Online PHP editor | output for lqYaR

<?php

$arr=[
    'a' => [
        'b' => 3,
    ]
];
$globalsCopy = $GLOBALS;
$globalsCopy['arr']['a']['b'] = 12;
var_dump($arr);
/*
array(1) {
  ["a"]=>
  array(1) {
    ["b"]=>
    int(12)
  }
}
 */

 $GLOBALS を書き換えるどころか参照することは滅多にないでしょうが、こういう挙動があると覚えておくとフレームワーク中で問題が起きた時に役に立つかもしれません。

  • この記事いいね! (0)