PHPにおける変数のスコープとは、その変数を参照したり変更したりできる範囲のことです。
PHPでは、主に次のスコープを理解しておく必要があります。
- グローバルスコープ
- ローカルスコープ
globalキーワード$GLOBALS- 静的ローカル変数
- 無名関数とクロージャ
- アロー関数
- スーパーグローバル変数
include・requireのスコープ- クラス内の変数とプロパティ
PHPの変数スコープを理解するうえで、最も重要なのは、関数やメソッドの内外でスコープが分かれるという点です。
一方で、ifやforeachなどの制御構文は、通常、新しい変数スコープを作りません。
グローバルスコープ
関数やメソッドの外側で定義された変数は、グローバルスコープに属します。
<?php
$message = 'Hello';
echo $message;
この$messageは、同じグローバルスコープ内で参照できます。
<?php
$message = 'Hello';
if (true) {
echo $message;
}
foreach ([1, 2, 3] as $number) {
echo $message;
}
制御構文は新しいスコープを作らない
PHPでは、次のような制御構文は独立した変数スコープを作りません。
ifforforeachwhileswitch
そのため、ifの中で定義した変数を、条件分岐の外側で使用できます。
<?php
if (true) {
$result = 'success';
}
echo $result;
出力結果は次のとおりです。
success
JavaScriptのletやconstとは異なり、PHPの波括弧は一般的なブロックスコープを作りません。
ただし、条件が成立しなかった場合は、変数自体が定義されない点に注意が必要です。
<?php
if (false) {
$result = 'success';
}
echo $result;
この場合、$resultは未定義のため、警告が発生します。
必要に応じて、あらかじめ初期値を設定しておくと安全です。
<?php
$result = null;
if ($condition) {
$result = 'success';
}
if ($result !== null) {
echo $result;
}
ローカルスコープ
関数やメソッドの中で定義された変数は、ローカルスコープに属します。
<?php
function greet(): void
{
$message = 'Hello';
echo $message;
}
greet();
この$messageは、greet()関数の中だけで使用できます。
関数の外側から参照することはできません。
<?php
function greet(): void
{
$message = 'Hello';
}
greet();
echo $message;
このコードでは、関数外の$messageは未定義です。
同じ変数名でも別の変数になる
関数の内側と外側で同じ名前の変数を定義しても、それぞれ別の変数として扱われます。
<?php
$message = 'Global';
function greet(): void
{
$message = 'Local';
echo $message;
}
greet();
echo $message;
出力結果は次のようになります。
Local
Global
関数内の$messageと、関数外の$messageは異なるスコープに属しています。
関数の引数もローカル変数
関数の引数として受け取った変数も、その関数内だけで有効です。
<?php
function greet(string $name): string
{
return "こんにちは、{$name}さん";
}
echo greet('田中');
この$nameは、greet()関数のローカル変数です。
関数の外側では使用できません。
関数内からグローバル変数を参照する方法
PHPでは、関数外で定義した変数を、関数内からそのまま参照することはできません。
<?php
$message = 'Hello';
function showMessage(): void
{
echo $message;
}
showMessage();
関数内の$messageは、関数外の$messageとは別の変数として扱われるため、未定義になります。
関数内からグローバル変数を使用する方法として、主に次の2つがあります。
globalキーワードを使う$GLOBALSを使う
ただし、実務ではグローバル変数への依存が強くなるため、可能であれば引数として渡す方法が推奨されます。
globalキーワード
関数内でglobalを宣言すると、関数内の変数名をグローバルスコープの同名変数に結び付けられます。
<?php
$message = 'Hello';
function showMessage(): void
{
global $message;
echo $message;
}
showMessage();
出力結果は次のとおりです。
Hello
グローバル変数の値を変更することもできます。
<?php
$count = 0;
function increment(): void
{
global $count;
$count++;
}
increment();
increment();
echo $count;
出力結果は次のとおりです。
2
globalを多用しないほうがよい理由
globalを使うと、関数が外部の状態に依存します。
<?php
$taxRate = 0.1;
function calculatePrice(int $price): float
{
global $taxRate;
return $price * (1 + $taxRate);
}
この関数は、引数の$priceだけでなく、外部の$taxRateにも依存しています。
そのため、関数単体では処理内容を把握しにくくなります。
引数として明示的に渡すほうが、依存関係が分かりやすくなります。
<?php
function calculatePrice(int $price, float $taxRate): float
{
return $price * (1 + $taxRate);
}
echo calculatePrice(1000, 0.1);
この書き方には、次のような利点があります。
- 依存関係が明確になる
- テストしやすくなる
- 異なる値でも再利用できる
- 処理結果を予測しやすい
- グローバル状態の影響を受けにくい
$GLOBALS
$GLOBALSは、グローバルスコープの変数にアクセスするためのスーパーグローバル配列です。
<?php
$message = 'Hello';
function showMessage(): void
{
echo $GLOBALS['message'];
}
showMessage();
グローバル変数の値を変更することもできます。
<?php
$count = 0;
function increment(): void
{
$GLOBALS['count']++;
}
increment();
echo $count;
出力結果は次のとおりです。
1
globalと$GLOBALSは、次のように書き分けられます。
function increment(): void
{
global $count;
$count++;
}
function increment(): void
{
$GLOBALS['count']++;
}
どちらもグローバル状態への依存を作るため、必要性を検討したうえで使用することが重要です。
$GLOBALS全体は置き換えられない
PHP 8.1以降では、次のように$GLOBALS全体を置き換えることはできません。
$GLOBALS = [];
一方、個別の要素は変更できます。
$GLOBALS['count']++;
個別の要素を削除することも可能です。
unset($GLOBALS['message']);
静的ローカル変数
通常、関数内のローカル変数は、関数が呼び出されるたびに初期化されます。
<?php
function countUp(): void
{
$count = 0;
$count++;
echo $count;
}
countUp();
countUp();
countUp();
出力結果は次のとおりです。
111
毎回$count = 0から処理が始まるためです。
変数にstaticを付けると、関数の呼び出しが終了しても値が保持されます。
<?php
function countUp(): void
{
static $count = 0;
$count++;
echo $count;
}
countUp();
countUp();
countUp();
出力結果は次のようになります。
123
静的ローカル変数の特徴
静的ローカル変数には、次の特徴があります。
- 参照できるのは関数内だけ
- 関数の実行終了後も値を保持する
- グローバル変数ではない
- 関数ごとに状態を保持できる
例えば、関数の呼び出し回数を数える用途で使用できます。
<?php
function generateId(): int
{
static $id = 0;
return ++$id;
}
echo generateId();
echo generateId();
echo generateId();
出力結果は次のとおりです。
123
ただし、静的変数を使用すると関数が内部状態を持つため、同じ引数でも結果が変わることがあります。
値渡しと参照渡し
値渡しと参照渡しは、厳密には変数スコープとは別の概念です。
ただし、関数内で変数を変更したときに、関数外へ影響するかどうかを理解するうえで重要です。
値渡し
PHPの関数引数は、明示的に参照渡しを指定しない限り、基本的に値渡しです。
<?php
$count = 10;
function increment(int $number): void
{
$number++;
}
increment($count);
echo $count;
出力結果は次のとおりです。
10
関数内の$numberを変更しても、関数外の$countは変更されません。
参照渡し
引数名の前に&を付けると、呼び出し元の変数を直接変更できます。
<?php
$count = 10;
function increment(int &$number): void
{
$number++;
}
increment($count);
echo $count;
出力結果は次のとおりです。
11
ただし、参照渡しは呼び出し元の値を暗黙的に変更するため、処理を追いにくくなる場合があります。
返り値を使用するほうが分かりやすいケースもあります。
<?php
function increment(int $number): int
{
return $number + 1;
}
$count = 10;
$count = increment($count);
オブジェクトを引数として渡す場合
PHPでは、オブジェクトも関数引数としては値渡しです。
ただし、変数には同じオブジェクトを識別する値が格納されているため、関数内でプロパティを変更すると、呼び出し元からも変更が見えます。
<?php
class User
{
public string $name = '田中';
}
function rename(User $user): void
{
$user->name = '鈴木';
}
$user = new User();
rename($user);
echo $user->name;
出力結果は次のとおりです。
鈴木
一方、関数内で変数を別のオブジェクトに再代入しても、呼び出し元の変数自体は置き換わりません。
<?php
function replace(User $user): void
{
$user = new User();
$user->name = '佐藤';
}
$user = new User();
$user->name = '田中';
replace($user);
echo $user->name;
出力結果は次のとおりです。
田中
無名関数のスコープ
通常の無名関数は、外側の一般的なローカル変数を自動的には取り込みません。
<?php
$message = 'Hello';
$showMessage = function (): void {
echo $message;
};
$showMessage();
このコードでは、無名関数内の$messageは未定義です。
外側の変数を利用するには、useを指定します。
<?php
$message = 'Hello';
$showMessage = function () use ($message): void {
echo $message;
};
$showMessage();
useは値として変数を取り込む
通常のuseでは、無名関数を作成した時点の値が取り込まれます。
<?php
$message = 'Hello';
$showMessage = function () use ($message): void {
echo $message;
};
$message = 'Goodbye';
$showMessage();
出力結果は次のとおりです。
Hello
無名関数を作成した時点で、Helloという値が取り込まれているためです。
参照として取り込む
外側の変数を参照として取り込むには、&を付けます。
<?php
$message = 'Hello';
$showMessage = function () use (&$message): void {
echo $message;
};
$message = 'Goodbye';
$showMessage();
出力結果は次のとおりです。
Goodbye
クロージャ内から外側の変数を変更することもできます。
<?php
$count = 0;
$increment = function () use (&$count): void {
$count++;
};
$increment();
$increment();
echo $count;
出力結果は次のとおりです。
2
オブジェクトを取り込む場合
オブジェクトを値として取り込んだ場合でも、同じオブジェクトのプロパティを変更できます。
<?php
$user = new stdClass();
$user->name = '田中';
$callback = function () use ($user): void {
$user->name = '鈴木';
};
$callback();
echo $user->name;
出力結果は次のとおりです。
鈴木
ただし、クロージャ内で変数を別のオブジェクトへ再代入しても、外側の変数自体は変わりません。
無名関数でも自動的に利用できる変数
通常の無名関数でも、スーパーグローバル変数はuseなしで利用できます。
<?php
$callback = function (): ?string {
return $_GET['keyword'] ?? null;
};
また、インスタンスメソッド内で作成した非staticな無名関数では、通常、$thisも利用できます。
アロー関数のスコープ
アロー関数は、外側で使用している変数を自動的に値として取り込みます。
<?php
$taxRate = 0.1;
$calculateTax = fn (int $price): float => $price * $taxRate;
echo $calculateTax(1000);
通常の無名関数では、次のようにuseが必要です。
<?php
$taxRate = 0.1;
$calculateTax = function (int $price) use ($taxRate): float {
return $price * $taxRate;
};
アロー関数では、useを明示する必要がありません。
<?php
$calculateTax = fn (int $price): float => $price * $taxRate;
アロー関数は値として取り込む
アロー関数は、作成時点の値を取り込みます。
<?php
$rate = 2;
$multiply = fn (int $number): int => $number * $rate;
$rate = 10;
echo $multiply(5);
出力結果は次のとおりです。
10
アロー関数作成時点の$rate = 2が取り込まれているためです。
外側の変数を参照として取り込めない
アロー関数では、通常のクロージャのように、外側の変数をuse (&$variable)で参照として取り込むことはできません。
<?php
$count = 0;
$increment = fn () => $count++;
$increment();
echo $count;
出力結果は次のとおりです。
0
アロー関数内での変更は、外側の$countには反映されません。
ただし、アロー関数の引数自体を参照渡しにすることは可能です。
<?php
$increment = fn (int &$number): int => ++$number;
$count = 0;
$increment($count);
echo $count;
出力結果は次のとおりです。
1
スーパーグローバル変数
PHPには、どのスコープからでも利用できる特別な変数があります。
代表的なスーパーグローバル変数は次のとおりです。
| 変数 | 主な内容 |
|---|---|
$_GET | URLのクエリパラメータ |
$_POST | POST送信されたデータ |
$_SERVER | サーバーやリクエスト情報 |
$_COOKIE | Cookie情報 |
$_SESSION | セッション情報 |
$_FILES | アップロードファイル |
$_ENV | 環境変数 |
$_REQUEST | GET、POST、Cookieなどの入力 |
$GLOBALS | グローバル変数 |
スーパーグローバル変数は、関数内でもglobalを宣言せずに使用できます。
<?php
function getUserId(): ?string
{
return $_GET['user_id'] ?? null;
}
$_REQUESTの注意点
$_REQUESTに含まれるデータや優先順位は、PHPの設定に影響される場合があります。
また、GET、POST、Cookieに同じキーが存在すると、どの入力元の値なのか分かりにくくなります。
実務では、次のように入力元を明示したほうが安全です。
<?php
$userId = $_GET['user_id'] ?? null;
$email = $_POST['email'] ?? null;
スーパーグローバルを処理の奥まで持ち込まない
関数内でスーパーグローバルを直接参照すると、依存関係が見えにくくなります。
function registerUser(): void
{
$email = $_POST['email'] ?? '';
}
外側で値を取得し、必要な値だけを引数として渡すほうが分かりやすくなります。
<?php
$email = $_POST['email'] ?? '';
registerUser($email);
function registerUser(string $email): void
{
// 登録処理
}
include・requireのスコープ
includeやrequireで読み込まれたファイルは、読み込みが実行された位置のスコープを引き継ぎます。
グローバルスコープで読み込む場合
次のファイルがあるとします。
<?php
// parts/message.php
echo $message;
グローバルスコープで読み込むと、読み込み先からグローバル変数を参照できます。
<?php
$message = 'Hello';
require 'parts/message.php';
関数内で読み込む場合
関数内で読み込むと、読み込み先はその関数のローカルスコープを引き継ぎます。
<?php
function renderMessage(): void
{
$message = 'Hello';
require 'parts/message.php';
}
renderMessage();
この場合、parts/message.phpから$messageを参照できます。
一方、関数外の変数は自動的には見えません。
<?php
$message = 'Global';
function renderMessage(): void
{
require 'parts/message.php';
}
renderMessage();
この場合、関数内に$messageが存在しないため、読み込み先でも参照できません。
読み込み先で定義した変数も引き継がれる
読み込み先のファイルで変数を定義した場合、その変数は読み込み元のスコープでも使用できます。
<?php
// parts/data.php
$result = 'loaded';
<?php
require 'parts/data.php';
echo $result;
出力結果は次のとおりです。
loaded
extract()を使う場合の注意点
テンプレートに変数を渡すために、extract()が使われることがあります。
<?php
function render(string $template, array $data = []): void
{
extract($data, EXTR_SKIP);
require $template;
}
ただし、extract()は配列のキーから変数を作成するため、変数の出所が分かりにくくなります。
また、既存の変数名と衝突する可能性もあります。
より明示的にするなら、テンプレート側で配列として参照します。
<h1>
<?= htmlspecialchars($data['name'], ENT_QUOTES, 'UTF-8') ?>
</h1>
foreachと変数スコープ
PHPでは、foreachも新しい変数スコープを作りません。
そのため、ループ変数は処理終了後も残ります。
<?php
$users = ['田中', '鈴木', '佐藤'];
foreach ($users as $user) {
echo $user;
}
echo $user;
最後のecho $user;では、最後の要素である佐藤が出力されます。
参照付きforeachの注意点
特に注意が必要なのは、参照付きforeachです。
<?php
$numbers = [1, 2, 3];
foreach ($numbers as &$number) {
$number *= 2;
}
ループ終了後も、$numberは配列の最後の要素への参照として残ります。
そのまま別の処理で同じ変数を使うと、意図しない変更が発生する可能性があります。
参照付きforeachの後では、unset()で参照を解除します。
<?php
foreach ($numbers as &$number) {
$number *= 2;
}
unset($number);
unset($number)は配列の要素を削除するのではなく、変数と最後の配列要素との参照関係を解除します。
unset()とスコープ
unset()を使うと、現在のスコープにある変数を破棄できます。
<?php
$message = 'Hello';
unset($message);
var_dump(isset($message));
出力結果は次のとおりです。
bool(false)
global変数に対してunset()した場合
関数内でglobal宣言した変数に対してunset()しても、グローバル変数本体は削除されません。
<?php
$message = 'Hello';
function removeLocalBinding(): void
{
global $message;
unset($message);
}
removeLocalBinding();
echo $message;
出力結果は次のとおりです。
Hello
関数内の変数名とグローバル変数との結び付きが解除されるだけです。
グローバル変数そのものを削除するには、次のようにします。
unset($GLOBALS['message']);
クラス内の変数とプロパティ
クラスでは、次の種類を区別する必要があります。
- メソッド内のローカル変数
- メソッドの引数
- インスタンスプロパティ
- 静的プロパティ
$this
<?php
class User
{
private string $name;
public function __construct(string $name)
{
$this->name = $name;
}
public function greet(): string
{
$message = 'こんにちは';
return "{$message}、{$this->name}さん";
}
}
このコードでは、次のように分類できます。
| 変数 | 種類 |
|---|---|
$name | コンストラクタの引数 |
$this->name | インスタンスプロパティ |
$message | greet()内のローカル変数 |
$this | 現在のオブジェクト |
プロパティとローカル変数は別物
次のコードでは、$nameと$this->nameは異なるものです。
public function setName(string $name): void
{
$this->name = $name;
}
右辺の$nameはメソッドの引数です。
左辺の$this->nameはオブジェクトのプロパティです。
$thisのスコープ
通常のインスタンスメソッドでは、$thisを使用できます。
<?php
class User
{
public function greet(): void
{
echo get_class($this);
}
}
一方、静的メソッドでは$thisを使用できません。
<?php
class User
{
public static function greet(): void
{
echo $this->name;
}
}
静的メソッドは、特定のインスタンスに結び付いていないためです。
静的プロパティを参照する場合は、self::やstatic::を使用します。
<?php
class Counter
{
private static int $count = 0;
public static function increment(): void
{
self::$count++;
}
public static function getCount(): int
{
return self::$count;
}
}
self::とstatic::の違い
self::は、そのコードが定義されているクラスを基準に解決されます。
一方、static::は、実際に呼び出されたクラスを基準に解決されます。
この違いは、継承を使用するときに重要です。
アクセス修飾子とスコープの違い
public、protected、privateは、変数スコープというよりも、プロパティやメソッドへのアクセス可能範囲を制御する仕組みです。
<?php
class User
{
public string $name;
protected string $email;
private string $password;
}
それぞれのアクセス範囲は次のとおりです。
| 修飾子 | アクセス可能な範囲 |
|---|---|
public | クラス内外のどこからでも |
protected | 自クラスと子クラス |
private | 宣言したクラス内のみ |
次の例では、$nameにはクラス外からアクセスできますが、$passwordにはアクセスできません。
<?php
class User
{
public string $name = '田中';
private string $password = 'secret';
}
$user = new User();
echo $user->name;
echo $user->password;
無名関数内の$this
インスタンスメソッド内で作成した通常の無名関数では、基本的に$thisを使用できます。
<?php
class User
{
private string $name = '田中';
public function createGreeter(): Closure
{
return function (): string {
return "こんにちは、{$this->name}さん";
};
}
}
$user = new User();
$greeter = $user->createGreeter();
echo $greeter();
アロー関数でも、$thisを使用できます。
<?php
class User
{
private string $name = '田中';
public function createGreeter(): Closure
{
return fn (): string => "こんにちは、{$this->name}さん";
}
}
一方、staticな無名関数では$thisを使用できません。
<?php
$callback = static function (): void {
echo $this->name;
};
アロー関数も、static fnとして定義できます。
<?php
$callback = static fn (): string => 'Hello';
関数内で定義した関数
PHPでは、関数の中で別の名前付き関数を定義できます。
<?php
function outer(): void
{
function inner(): void
{
echo 'inner';
}
}
outer();
inner();
inner()は、outer()が実行された時点で定義されます。
定義後は、outer()の外側からも呼び出せます。
ただし、outer()を複数回呼び出すと、inner()を再定義しようとしてエラーになります。
outer();
outer();
また、outer()が一度も実行されていない状態では、inner()は存在しません。
このような書き方は処理順序への依存が強いため、通常は無名関数を使用したほうが安全です。
<?php
function outer(): Closure
{
return function (): void {
echo 'inner';
};
}
$inner = outer();
$inner();
ループ変数とクロージャ
クロージャにループ変数を取り込む場合、値として取り込むか、参照として取り込むかで結果が変わります。
値として取り込む場合
<?php
$callbacks = [];
for ($i = 0; $i < 3; $i++) {
$callbacks[] = function () use ($i): int {
return $i;
};
}
foreach ($callbacks as $callback) {
echo $callback();
}
出力結果は次のとおりです。
012
各クロージャが、作成時点の$iを値として取り込んでいるためです。
参照として取り込む場合
<?php
$callbacks = [];
for ($i = 0; $i < 3; $i++) {
$callbacks[] = function () use (&$i): int {
return $i;
};
}
foreach ($callbacks as $callback) {
echo $callback();
}
出力結果は次のとおりです。
333
すべてのクロージャが同じ$iを参照しているため、ループ終了後の値である3が返されます。
PHPの変数スコープ早見表
PHPの主な構文とスコープの関係を整理すると、次のようになります。
| 構文 | 独立した関数スコープを作るか | 親スコープの一般変数 |
|---|---|---|
| 名前付き関数 | 作る | 自動的には取り込まない |
| メソッド | 作る | 自動的には取り込まない |
| 通常の無名関数 | 作る | useで明示的に取り込む |
| アロー関数 | 作る | 使用した変数を値として自動取得する |
if | 作らない | 同じスコープ |
for | 作らない | 同じスコープ |
foreach | 作らない | 同じスコープ |
while | 作らない | 同じスコープ |
switch | 作らない | 同じスコープ |
include・require | それ自体では作らない | 実行位置のスコープを引き継ぐ |
実務で意識したいポイント
グローバル変数をなるべく使わない
次のコードは、関数が外部状態に依存しています。
<?php
$discountRate = 0.2;
function calculateDiscount(int $price): float
{
global $discountRate;
return $price * $discountRate;
}
引数で渡すほうが、依存関係が明確になります。
<?php
function calculateDiscount(
int $price,
float $discountRate
): float {
return $price * $discountRate;
}
スーパーグローバルを直接参照しすぎない
次のような関数は、$_POSTに直接依存しています。
function registerUser(): void
{
$email = $_POST['email'] ?? '';
}
必要な値を外側で取得し、引数として渡すほうがテストしやすくなります。
<?php
$email = $_POST['email'] ?? '';
registerUser($email);
function registerUser(string $email): void
{
// 登録処理
}
参照渡しを必要以上に使わない
参照渡しは、呼び出し元の変数を直接変更します。
function applyDiscount(float &$price): void
{
$price *= 0.8;
}
返り値を使うと、変更が明示的になります。
function applyDiscount(float $price): float
{
return $price * 0.8;
}
$price = applyDiscount($price);
変数の使用範囲を小さくする
変数は、必要な場所に近い位置で定義すると理解しやすくなります。
<?php
function calculateTotal(array $prices): int
{
$total = array_sum($prices);
return $total;
}
よくある勘違い
ifの中で定義した変数は外で使えない
PHPでは、条件が成立して変数が定義されていれば、外側でも使用できます。
if (true) {
$value = 100;
}
echo $value;
ただし、条件が成立しなければ変数は未定義です。
関数外の変数は関数内からそのまま使える
関数外の一般変数は、関数内から自動的には見えません。
$name = '田中';
function greet(): void
{
echo $name;
}
引数として渡すか、global、$GLOBALS、クロージャのuseなどを使用する必要があります。
アロー関数は外側の変数を参照として取り込む
アロー関数は、外側の変数を値として自動取得します。
$rate = 2;
$fn = fn (int $value): int => $value * $rate;
$rate = 10;
echo $fn(5);
出力結果は次のとおりです。
10
foreachの変数はループ後に消える
PHPでは、foreachのループ変数はループ後も残ります。
foreach ($items as $item) {
// 処理
}
var_dump($item);
特に参照付きforeachの後は、unset($item)で参照を解除することが重要です。
まとめ
PHPの変数スコープで、特に重要なポイントは次のとおりです。
- 関数やメソッドの内外ではスコープが分かれる
ifやforeachは新しい変数スコープを作らない- 関数外の一般変数は関数内から自動的には見えない
globalや$GLOBALSでグローバル変数にアクセスできる- 実務ではグローバル変数より引数を使うほうがよい
- 静的ローカル変数は関数の呼び出し後も値を保持する
- 通常の無名関数は
useで外側の変数を取り込む - アロー関数は外側の変数を値として自動取得する
- スーパーグローバル変数はどのスコープからでも使用できる
include・requireは実行位置のスコープを引き継ぐ- 参照付き
foreachの後はunset()で参照を解除する - オブジェクトのプロパティ変更は、関数外からも見える場合がある
PHPでは、関数やメソッドの境界がスコープを分ける大きな境界です。
一方、ifやforeachなどの波括弧は、通常のブロックスコープを作りません。
まずはこの違いを押さえると、PHPの変数スコープを理解しやすくなります。
以上、PHPの変数のスコープについてでした。
最後までお読みいただき、ありがとうございました。










