どうもこんにちは
今回はPHPスコープの事について書きたいと思います
特別な事が書いているわけではないので上級PHPerの皆さんはスルーしましょう
今回の参照はもちろん公式です
変数のスコープ
#スコープの種類
PHPのスコープの種類は3種類しかありません
- ローカルスコープ
- グローバルスコープ
- スーパーグローバル
###ローカルスコープ
これは関数内スコープのことです
<?php
function func1()
{
$val = 'ローカルスコープ';
return $val;
}
echo $val;
echo func1();
これは以下のように出力されます
> // echo $val;
>ローカルスコープ // echo func1();
関数内で定義した変数$val
が出力されないのでローカル変数として扱われていることが分かります
基本的にアプリケーションを作成していくときはローカルスコープを意識してプログラミングしていきましょう
###グローバルスコープ
これは関数内で定義されていない変数のスコープになります
ただグローバルと付いていますが、関数内で直接使用する事は出来ません
<?php
$val = 'グローバルスコープ';
function func2()
{
return $val;
}
echo $val;
echo func2();
これを実行すると
echo $val;
はグローバルスコープ
という文字が出力されますが
echo func2();
はUndefined Variable: val
と言われて$val変数を認識出来ません
これを認識できるようにする場合は
function func2()
{
global $val; // globalキーワードを使用
return $val;
}
globalキーワードを使う事によって関数外の値を使用します
ただこのように外部の値を関数内で使用したい場合は、globalキーワードを使用するのではなく引数に追加しましょう
globalはプログラムを追うことを難しくしテストも書きにくくなってしまいます
###スーパーグローバル
全てのスコープで使用できる組み込みの変数と書いてあります
これらがそうです
$GLOBALS
$_SERVER
$_GET
$_POST
$_FILES
$_COOKIE
$_SESSION
$_REQUEST
$_ENV
よく使いますね
ただ、どこでも使いたい変数を$GLOBALSに無闇に突っ込むのはやめましょう
これもグローバル変数と同じく追いづらいコードの素になります
特にglobal変数の値をバンバン変更している場合かなり危険です
#関数以外の括弧でのスコープの検証
僕が長らくPHPを使っていながら気を遣っていなかったのがfor文を使う時に宣言する変数です
Scalaの場合
var num = 10
println(num)
for ( n <- (1 to 3) ) {
var num = n*3
println(num)
}
println(num)
出力結果
3
6
9
10
Scalaでvar使うんかいというのは置いておいて
for内で宣言した変数はその括弧内で完結します
最初に宣言したvar num = 10
は、括弧内で同じ変数名numを宣言していても最後のprintln(num)で10を出力します
これを基準だと思い込んでいると罠にはまります
$i = 10;
println($i);
for ($i=1; $i<=3; $i++)
{
println($i);
}
println($i);
※printlnは自作の改行echo
出力結果
10
1
2
3
4
最後の出力で僕は10を期待していたのですが4が出力されてしまいました
for文は括弧内で完結するだろうと思っていたら上書きされてしまうので注意が必要です
if式でもただの括弧内でもScalaはスコープがありますが、PHPは関数内かそれ以外という分け方になっています
何となく書けてしまったままPHPをやっていたので普段はまらないようなところで期待した動作にならないことがありました
なんという事でしょう…変数名を被らせないようたゆまぬ努力が必要です
#所感
Scala最高
関数をしっかり作ってスコープを意識すれば悲劇は起きずに済むとは思います、基本ですね
以上です