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

  • 2020年12月7日
  • 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 を書き換えるどころか参照することは滅多にないでしょうが、こういう挙動があると覚えておくとフレームワーク中で問題が起きた時に役に立つかもしれません。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG