この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:5
ページ更新者:guest
更新日時:2026-06-11 07:12:00

タイトル: 代入演算子
SEOタイトル: PHP 代入演算子完全ガイド

この記事の要点
  • = は値の代入。複合代入 += -= *= /= %= .= **= ??=
  • 参照代入 $b = &$a で同じ実体を共有 (関数引数の & と同じ)
  • 分割代入 (PHP 7.1+) [$a, $b] = [1, 2] / ["name" => $n] = $arr
  • 配列は値コピー (Copy on Write)、オブジェクトは参照コピー
  • PHP 8+ で "5" + 3 等の文字列→数値暗黙変換に Deprecated 警告

基本代入と複合代入

$x = 10;
$x += 5;   // 15  (= $x = $x + 5)
$x -= 3;   // 12
$x *= 2;   // 24
$x /= 4;   // 6
$x %= 4;   // 2
$x **= 3;  // 8   (累乗)

// ビット演算 (整数のみ)
$f = 0b0101;
$f |= 0b1000;   // 0b1101
$f &= 0b1100;   // 0b1100
$f ^= 0b1010;   // 0b0110
$f <<= 2;       // 左シフト
$f >>= 1;       // 右シフト

// 文字列連結
$s = 'Hello';
$s .= ' World';   // 'Hello World'

// Null 合体代入 (PHP 7.4+)
$config['timeout'] ??= 30;
// = isset($config['timeout']) ? $config['timeout'] : $config['timeout'] = 30

複合代入演算子一覧

演算子等価導入
+=$a = $a + $bPHP 4
-=$a = $a - $bPHP 4
*=$a = $a * $bPHP 4
/=$a = $a / $bPHP 4
%=$a = $a % $bPHP 4
.=$a = $a . $bPHP 4
**=$a = $a ** $bPHP 5.6
&amp;= |= ^=ビット AND/OR/XORPHP 4
<<= >>=ビットシフトPHP 4
??=null のときだけ代入PHP 7.4

参照代入 (&)

$a = 1;
$b = $a;    // 値コピー
$b = 99;
echo $a;    // 1 (変わらない)

// 参照代入
$a = 1;
$b = &amp;$a;   // 同じ実体
$b = 99;
echo $a;    // 99 (両方変わる)

// 関数引数の参照
function increment(int &amp;$n): void {
    $n++;
}
$x = 5;
increment($x);
echo $x;    // 6

// foreach の参照 (要注意)
$arr = [1, 2, 3];
foreach ($arr as &amp;$v) { $v *= 2; }
unset($v);   // ★ 忘れると次の foreach でバグる
print_r($arr);   // [2, 4, 6]

分割代入 (Destructuring, PHP 7.1+)

// 配列から
[$a, $b, $c] = [1, 2, 3];
// または list($a, $b, $c) = [1, 2, 3];

// 連想配列から (キー指定)
['name' => $name, 'age' => $age] = ['name' => 'taro', 'age' => 20];

// スキップ
[, , $third] = [1, 2, 3];   // $third = 3

// ネスト
[[$a, $b], [$c, $d]] = [[1, 2], [3, 4]];

// foreach での利用
$users = [
    ['name' => 'taro', 'age' => 20],
    ['name' => 'jiro', 'age' => 25],
];
foreach ($users as ['name' => $name, 'age' => $age]) {
    echo "$name: $age\n";
}

// 関数戻り値の分割
function range2(): array {
    return [0, 100];
}
[$min, $max] = range2();

連鎖代入

// 右から左に評価される
$a = $b = $c = 0;
// = $a = ($b = ($c = 0));

// 全部 0 になる
echo $a, $b, $c;   // 000

// 連鎖はクリアな意図のときだけ。複雑なら避ける

値コピー vs 参照コピー

// 配列: 値コピー (Copy on Write)
$arr1 = [1, 2, 3];
$arr2 = $arr1;
$arr2[] = 4;
print_r($arr1);   // [1, 2, 3] (変わらない)
print_r($arr2);   // [1, 2, 3, 4]

// オブジェクト: 参照コピー (PHP の仕様)
class Box { public int $v = 0; }
$b1 = new Box();
$b2 = $b1;
$b2->v = 99;
echo $b1->v;   // 99 ! 両方同じ

// オブジェクトを「コピー」したいなら clone
$b3 = clone $b1;
$b3->v = 0;
echo $b1->v;   // 99 (変わらない)

Type Coercion (型変換) の罠

$x = '5' + 3;    // 8 (PHP 7) / 8 (PHP 8 だが Deprecated 警告)
$x = '5abc' + 3; // 8 (PHP 7 警告) / TypeError (PHP 8)
$x = 'abc' + 3;  // 3 + warning (PHP 7) / TypeError (PHP 8)

// 厳密に書く
$x = (int) '5' + 3;        // 8
$x = intval('5') + 3;      // 8

// 文字列連結との混同
$x = 1 + 2 . 3;
// PHP 7:  '33'  (1+2=3, '3'.'3'='33')
// PHP 8:  Deprecated (・ は + より弱い)。括弧推奨
$x = (1 + 2) . 3;   // '33' (明示)

null と false と 0 と "" の代入

$a = null;
$b = false;
$c = 0;
$d = '';

// 緩い比較なら全部等しい
var_dump($a == $b);   // true
var_dump($b == $c);   // true
var_dump($c == $d);   // PHP 7: true / PHP 8: false (仕様変更)

// 厳密比較なら全部別物
var_dump($a === $b);   // false
var_dump($b === $c);   // false
var_dump($c === $d);   // false

// 推奨: 「未入力」判定は厳密比較
if ($input === null || $input === '') {
    /* 未入力 */
}

FAQ

Q: $a = $b でオブジェクトをコピーしたい
A: clone を使います。$a = clone $b。深いコピーが必要なら __clone() を実装するか、シリアライズで丸ごとコピー。

Q: 参照渡しと値渡し、どちらを使うべき?
A: PHP は通常値渡しで十分速い (Copy on Write)。参照は意図的に呼び出し元を変更したいときだけ。

Q: 分割代入で「キーが存在しない」場合は?
A: 警告が出て null が代入されます。PHP 7.4+ なら ['name' => $n = 'default'] = ... のようなデフォルトは書けません (関数引数のみ)。