業務アプリ開発講座

PHPの基本のキと変数スコープ

スタッフ編集画面HTMLができました。ここからサーバープログラム(PHP)ソースを書き加えていくのですが、その前に、PHPの基本的な構造を押さえておきましょう。

コードブロック

phpは下記のブロックに囲まれた中に書かれたソースをPHPとして解釈・実行されますので、必ずこのブロック内にPHPソースを書きます。

<?php
    //何かPHPのソース
?>

ちなみに、ASP.NETですと、下記ブロック内に書かれたソースがASP.NETとして解釈されます。

<script runat="server" language="C#">
    //何かASP.NETのソース
</script>

変数

変数のは必ず名前の前に$を付加します。そうすることで変数と解釈されます。例えば$nameのように記述します。そして、JavaやC#等に見られるような「変数の宣言」は必要ありません。

例えば、

C#
string name = "";
Java
String name = "";

のような変数の「型」を指定した宣言というものが必要ないのです。この型指定をする必要がないというのは一見柔軟性があって、面倒な宣言を省くことことができ、良さげに見えますが、思わぬ潜在的なバグを埋め込んでしまうことにもつながります。注意が必要です。

変数のスコープ

どの言語にも変数にはスコープというものがあります。変数のスコープとは「変数の影響範囲」「見える範囲」のことです。
例えばC#で下記のソースがあったとします。

string y = "";
bool IsA(string x){
	return (x == y);
}

変数defaultNameはメソッドIsMatchNameの外で宣言されていますね。このような場合、メソッドIsMatchName内で変数defaultNameを参照できるようになっています。変数が宣言された箇所より深い階層、子供の階層からは参照できるわけです。逆に言うと宣言された箇所より上の階層、親の階層からは参照できないのです。

例えばC#で以下のソースがあったとしましょう(こんな書き方をすることはありませんが)。

int numberA(string x){
	if(x == y){
		int a = 5;
	}
	else{
		int a = 2;
	}
	return a;	//C#では変数aは参照できないため、エラーになります。
}

変数aifブロックの中で宣言されています。つまり変数aのスコープはif, elseそれぞれの内側のみ有効となります。最後の行のreturn a;はスコープ外となり、参照することができない変数aを参照しようとしていますので、当然エラーになります。return a;でエラーにならないように書くには、return a;と同じか親の階層であらかじめ宣言しておけば、参照することができます。

例えばこのように。

int numberA(string x){
	int a = 0;
	if(x == y){
		a = 5;
	}
	else{
		a = 2;
	}
	return a;
}

ところがPHPですと参照できるのです。PHPの下記ソースでは、条件に一致すれば5を返し、一致しなければ2を返します。

function isA($x, $y){
	if($x == $y){
		$a = 5;
	}
	else{
		$a = 2;
	}
	return $a;
}

そもそもPHPには変数の宣言という概念がありません。PHPのスコープは関数の内か外かだけです。ですので関数内であれば、変数がどの階層で設定されようと、以降の行では、参照できてしまうのです。


とは言っても設定されていない変数は参照できません。
例えば、下記の場合、nullが返ってきます。変数$aは条件に合致したフローで設定さてれいますが、変数$bは条件に合致しないフローで設定されています。この条件式ですと必ず条件は合致しますので、変数$aは設定されますが、$bは設定されません。そして、この関数は設定されていない$bを返そうとしています。設定されていない、すなわち存在しない変数ということで「存在しない」を意味するnullを返すわけです。

function isA(){
	if(0 == 0){
		$a = 'A';
	}
	else{
		$b = 'B';
	}
	return $b;
}

ここまでは、PHPの関数内のスコープについて書きました。
PHPのもう一つの特徴である「関数外の変数」の参照方法を示します。
関数の外で設定された変数を関数の中から参照するには、2つの記述方法があります。

1つ目:

$a = 0;
function getName(){
	global $a;
}

関数外で設定された変数名を関数内でglobalキーワードを使って宣言しなおす方法です。WordPressなどはこの方法を取っています。

2つ目:

$a = 0;
function getName(){
	$b = $GLOBALS['a'];
}

スーパーグローバルとか自動グローバル変数と呼ばれる$GLOBALS[]を使用する方法です。これは関数外で設定された変数を連想配列としてアクセスする方法です。プロジェクトによってコーディングルールがありますが、個人的にはこちらの使用を勧めます。というのは、グローバル変数であることが一目瞭然だからです。1つ目の記述方法ですと、ソースが複雑になってきたり、長くなってきた場合の見通しの悪さから見間違い、勘違いを誘発する可能性が高く、そこから思わぬバグを作りこんでしまうからです。

PHPはrequireinclude機能で他のPHPファイルを読み込んでそこに書かれている機能を利用することができます。さらにそれらにファイルに書かれたグローバル変数も参照することができます。ですので、グローバル変数だということを明示する記述方法が良いのです。