PHPの変数は$で始まる名前で、値を代入すると作られます:$name = "Ada";。値が型を決めるので、宣言用のキーワードも型の指定もありません。あとから別の型の値を代入することもできます。
変数の命名規則
変数名は$で始まり、次に英字かアンダースコア、そのあとは英字、数字、アンダースコアを自由に続けます。ASCII以外の文字も英字として扱われるので$名前も有効ですが、ASCIIの名前が普通です。名前は大文字と小文字を区別します。
| 名前 | 有効か |
|---|---|
$total, $userName, $user_name | 有効 |
$_count, $item2 | 有効 |
$2items | 無効、数字では始められない |
$user-name | 無効、$userからnameを引く式になる |
$this | 無効、現在のオブジェクト用に予約されている。代入すると致命的エラー |
つまり$city、$City、$CITYは3つの別々の変数です。snake_case($first_name)かcamelCase($firstName)を使い、プロジェクト内では1つのスタイルに統一しましょう。PSRのコーディング規約は変数の命名をあえて決めていません。LaravelやSymfonyのコードではおもにcamelCaseが使われています。
文字列の中で変数を使う
ダブルクォートの中では、PHPは変数をその値に置き換えます。シングルクォートの中では置き換えません。変数の直後に文字が続くときや、文字列キーで配列の要素にアクセスするときは、変数を波括弧で囲みます。
引用符、連結、変数展開については文字列のページで詳しく説明しています。
未定義の変数と既定値
一度も代入していない変数を読むとnullになり、PHPは警告を表示します。
Warning: Undefined variable $discount in /home/index.php on line 3
先にissetで確認するか、null合体演算子??で既定値を与えます。どちらも警告なしで動きます。
$x ??= 0;は$x = $x ?? 0;の短縮形です。フォームやURLの値がよくある使いどころです:$page = $_GET['page'] ?? 1;。
関数の中の変数スコープ
関数の外で定義した変数は関数の中からは見えず、関数の中で作った変数は関数が戻ると消えます。JavaScriptから来た人がいちばん驚くところです。
?? 0がなければ、最初の関数は未定義の$taxRateについて警告を出します。値を引数として渡すと、関数の動きが予測しやすくなりテストもしやすくなるので、まずはこの方法を選びましょう。引数と戻り値については関数のページで扱っています。
globalキーワードと$GLOBALS
関数がどうしてもグローバル変数を使う必要があるときは、globalで宣言するか、すべてのグローバル変数を名前で保持している$GLOBALS配列を使います。
グローバル変数はどの関数からでも変更できるので、コードを追いにくくします。古いコードやWordPressのプラグイン(global $wpdb;)には出てきますが、新しいコードでは値を渡すかクラスを使いましょう。
static変数は値を保持する
関数の中のstatic変数は1回だけ作られ、呼び出しの間で値を保持します。それでもローカル変数なので、関数の外のコードからは見えません。
可変変数($$name)
$$nameは、$nameの値を別の変数の名前として使います。動きはしますが、ほとんどの場合は配列のほうが同じことをわかりやすく書けます。
<?php
$field = "color";
$$field = "blue"; // creates $color
echo $color, "\n";
// The clearer way to have names chosen at runtime:
$settings = [];
$settings[$field] = "blue";
echo $settings["color"], "\n";
コピーと参照
変数を別の変数に代入すると、配列も含めて値がコピーされます。代わりに両方の名前が同じ値を指すようにするには、前に&を付けます。
オブジェクトは扱いが違います。オブジェクトを代入すると同じオブジェクトへのハンドルがコピーされるので、どちらの変数を通した変更も両方から見えます。本当のコピーにはcloneを使います。
よくあるミス:ifやループの中で代入した変数
PHPにはブロックスコープがないので、if、for、foreachの中で作った変数はそのあとも存在し続けます。便利ですが、バグも隠れます。ブロックが実行されなかった場合、変数は作られていないのです。
既定値の行がなければ、$ordersが空のとき$messageは未定義のままになり、警告が表示されます。値をセットするかもしれないブロックの前に、すべての変数に値を入れておきましょう。
よくある質問
PHPで変数を宣言するには?
$で始まる名前に値を代入します:$count = 10;。PHPにはvarやletのようなキーワードも、宣言時の型もありません。変数は最初の代入で作られ、その値の型になります。
関数の外で定義した変数が関数の中から見えないのはなぜですか?
PHPの関数は独自のローカルスコープを持ち、グローバル変数を自動では参照しません。値を引数で渡す(きれいな方法)、関数内でglobal $name;と宣言する、$GLOBALS['name']を読む、のいずれかです。クロージャはuse ($name)でキャプチャでき、アロー関数fn()は自動でキャプチャします。
PHPのstatic変数とは何ですか?
関数の中でstatic $calls = 0;のようにstatic付きで宣言するローカル変数です。初期化は1回だけで、その関数の呼び出しの間で値を保持するので、カウンターや簡単なキャッシュに便利です。
PHPの変数名は大文字と小文字を区別しますか?
区別します。$name、$Name、$NAMEは3つの別々の変数です。一方、関数名とクラス名はPHPでは大文字と小文字を区別しません。
PHPで変数を削除するには?
unset($name);を呼びます。そのあとisset($name)はfalseになり、読むと「Undefined variable」の警告が出ます。nullを代入すると、変数は残ったまま中身が空になります。