PHPのグローバルスコープを使うときは明示的に指定する

最近になってPHPのスコープについて「グローバルなスコープと思っていても明示的に呼び出さないといけない」ということを初めて知った。
どういうことかというと、PHPではスクリプト全体で共有されているように見えても、ちゃんとglobalをつけて宣言しないといけないということ。

例えば次のようなコード。

<?php
$a = 1;

function call_global() {
    global $a;
    $a = 2;
    echo "In call_global a: ".$a."\n";
}

function not_call_global() {
    $a = 3;
    echo "In not_call_global a: ".$a."\n";
}

echo $a."\n";
call_global();
echo $a."\n";
not_call_global();
echo $a."\n";

スクリプトの先頭とcall_globalnot_call_globalでそれぞれ同じ名前の変数が使用されている。
直感的には、最初の宣言が関数の外にあるので、このスクリプト内ではグローバルな変数として使いまわされそうな気がする。

これの実行結果はこちら。

$ php global.php
1
In call_global a: 2
2
In call_global a: 3
2

call_globalの呼び出しによってaの値が書き換わっている。
ところが、not_call_globalが呼ばれてもaには影響がない。
globalと宣言されることによってグローバル変数を参照するようになるが、そうでなければローカル変数として定義されるということです。

このぐらいの簡単なコードならまだ大丈夫。
ところが、大きなプロジェクトになるとglobalの宣言がいたるところにあったり、同じ変数名がローカルだったりグローバルだったりするようになる。
そうならないように、きちんとリファクタしたりきれいなコードを書くように心がけましょう、ということです。