タイトル: 変数
SEOタイトル: PHP 変数完全ガイド (スコープ/参照/型変換)
| この記事の要点 |
|
変数の基本
// 宣言と代入が同時 (var キーワード等は不要)
$name = '太郎';
$age = 30;
$flag = true;
$arr = [1, 2, 3];
// 大文字小文字を区別
$name = '太郎';
$Name = '次郎'; // 別変数
echo $name; // 太郎
echo $Name; // 次郎
// 命名規則
$valid = 1;
$_valid = 1;
$valid_1 = 1;
$1invalid = 1; // ❌ Parse error
$invalid- = 1; // ❌ Parse error (ハイフン不可)
// 日本語変数も使えるが PSR-12 非推奨
$名前 = '太郎'; // 動くが避ける
PSR-12 命名規則
| 対象 | 規則 | 例 |
|---|---|---|
| 変数 | camelCase | $userName |
| 定数 | UPPER_SNAKE_CASE | const MAX_RETRY = 3; |
| クラス名 | PascalCase | class UserService |
| メソッド名 | camelCase | public function getName() |
| プロパティ | camelCase | public string $userName; |
| ファイル名 | クラスと同じ (PSR-4) | UserService.php |
スコープ: グローバル / ローカル / static
$g = 10;
function f1() {
echo $g ?? 'undefined'; // undefined: 関数内からは見えない
}
function f2() {
global $g; // ★ global 宣言で参照
echo $g; // 10
}
function f3() {
echo $GLOBALS['g']; // ★ スーパーグローバル経由
}
// static 変数 (関数呼び出しをまたいで保持)
function counter() {
static $count = 0;
$count++;
return $count;
}
echo counter(); // 1
echo counter(); // 2
echo counter(); // 3
参照渡し (&)
// 値渡し (デフォルト)
$a = 10;
$b = $a; // コピー
$b = 20;
echo $a; // 10 (影響なし)
// 参照渡し
$a = 10;
$b = &$a; // ★ エイリアス
$b = 20;
echo $a; // 20 (連動)
// 関数引数
function modify(&$x) {
$x *= 2;
}
$n = 5;
modify($n); // n が直接書き換わる
echo $n; // 10
// foreach での参照
$arr = [1, 2, 3];
foreach ($arr as &$v) {
$v *= 10;
}
unset($v); // ★ 参照は明示的に解放推奨
print_r($arr); // [10, 20, 30]
foreach 参照の罠: ループ後の $v は最後の要素への参照が残り、後続の代入で配列が壊れます。必ず unset($v) しましょう。
可変変数 ($$var)
$name = 'hoge';
$$name = 'value'; // ★ $hoge = 'value' と同じ
echo $hoge; // value
// 動的にプロパティアクセス
$obj = new stdClass();
$prop = 'foo';
$obj->$prop = 1; // $obj->foo = 1
echo $obj->foo; // 1
// ループでの利用 (非推奨パターン)
foreach (['name' => '太郎', 'age' => 30] as $k => $v) {
$$k = $v; // ❌ コードリーディング困難に
}
echo $name; // 太郎
echo $age; // 30
可変変数は基本的に避けるのが PSR-12 / PHPStan の推奨。連想配列 ($data['name']) で代替できます。
型: 動的型付けと Type Juggling
$x = '10'; // string
$x = 10; // int (再代入で型変更 OK)
$x = 10.5; // float
$x = true; // bool
$x = null; // null
$x = [1,2,3]; // array
$x = new stdClass(); // object
// 緩い比較 (Type Juggling)
'0' == false; // true ❌ 罠
'10abc' == 10; // PHP 7: true, PHP 8: false (仕様変更)
[] == null; // false (false != null)
0 == 'foo'; // PHP 7: true ❌ 罠, PHP 8: false
// ★ 厳密比較 === を使うのが鉄則
'10' === 10; // false
0 === false; // false
PHP 7.4+ Typed Properties
class User {
public int $id;
public string $name;
public ?string $email = null; // nullable
public array $roles = [];
public readonly string $createdAt; // ★ PHP 8.1 readonly
// コンストラクタプロモーション (PHP 8.0)
public function __construct(
public string $username,
public int $age = 0,
) {
$this->createdAt = date('c');
}
}
$u = new User('taro', 25);
$u->name = 123; // ❌ TypeError (int を string に代入)
$u->createdAt = '...'; // ❌ Error (readonly)
Null Coalescing (??) と unset
// Null Coalescing (PHP 7+)
$name = $input['name'] ?? 'default';
// = isset($input['name']) ? $input['name'] : 'default'
// Null Coalescing Assignment (PHP 7.4+)
$config['timeout'] ??= 30;
// 変数の破棄
$x = 10;
unset($x);
echo $x ?? 'gone'; // gone
// 配列要素の削除
$arr = ['a' => 1, 'b' => 2];
unset($arr['a']);
print_r($arr); // ['b' => 2]
変数のスコープまとめ
| 場所 | スコープ | 備考 |
|---|---|---|
| 関数外 | ファイルスコープ (グローバル) | require/include したファイル間でも共有 |
| 関数内 | ローカル | global 宣言で外を参照 |
クラス内 ($this->) | インスタンス | オブジェクト単位 |
クラス内 (self::$x) | クラス | static |
クロージャ (function () use ($x)) | キャプチャ | 明示的に取り込み |
アロー関数 (fn() => $x) | 自動キャプチャ | PHP 7.4+ |
FAQ
Q: $x = null と unset($x) の違いは?
A: 前者は変数が存在し値が null。後者は変数自体が消える。isset($x) の結果が異なります。
Q: 変数の型を調べたい
A: var_dump($x) / gettype($x) / is_int() 等の is_* 関数。デバッガなら xdebug。
Q: $_POST や $_SESSION は何?
A: スーパーグローバル変数。どこからでも見える特別な配列で global 宣言不要。