PHPの分割代入について

採用はこちら

PHPの分割代入とは、配列の値を複数の変数にまとめて代入できる構文です。

通常、配列の値を個別の変数に入れる場合は、次のように書きます。

$user = ['佐藤', 25, 'Tokyo'];

$name = $user[0];
$age = $user[1];
$city = $user[2];

これを分割代入で書くと、次のように簡潔にできます。

$user = ['佐藤', 25, 'Tokyo'];

[$name, $age, $city] = $user;

echo $name; // 佐藤
echo $age;  // 25
echo $city; // Tokyo

配列の中身を、左側に書いた変数へ順番に代入しているイメージです。

PHPでは、以前から list() を使った分割代入がありました。

PHP 7.1以降では、より短く書ける [] 構文も使えます。

list($a, $b) = [1, 2];

[$a, $b] = [1, 2];

現在のPHPで新しくコードを書く場合は、チームの規約に問題がなければ [] 構文を使うと読みやすいです。

目次

PHPで分割代入を使う基本構文

list() を使う書き方

list() は、PHPで昔から使われている分割代入の書き方です。

list($a, $b, $c) = [10, 20, 30];

echo $a; // 10
echo $b; // 20
echo $c; // 30

配列の 0番目 の値が $a1番目 の値が $b2番目 の値が $c に入ります。

[] を使う書き方

PHP 7.1以降では、list() の代わりに [] を使って分割代入できます。

[$a, $b, $c] = [10, 20, 30];

echo $a; // 10
echo $b; // 20
echo $c; // 30

list() よりも記述量が少なく、配列リテラルとも見た目がそろうため、現在はこちらの書き方がよく使われます。

[$id, $name] = [1, '田中'];

インデックス配列を分割代入する

配列の値を順番に変数へ入れる

数値インデックスの配列では、左側に書いた変数へ順番に値が入ります。

$data = ['apple', 'banana', 'orange'];

[$first, $second, $third] = $data;

echo $first;  // apple
echo $second; // banana
echo $third;  // orange

これは、次のように書くのとほぼ同じ意味です。

$first = $data[0];
$second = $data[1];
$third = $data[2];

複数の値をまとめて受け取りたいときに、分割代入を使うとコードがすっきりします。

不要な値をスキップする

配列の一部の値だけ使いたい場合は、不要な場所を空けてスキップできます。

$data = ['山田', 30, 'Osaka'];

[$name, , $city] = $data;

echo $name; // 山田
echo $city; // Osaka

この例では、2番目の 30 は使っていません。

list() でも同じように書けます。

list($name, , $city) = $data;

ただし、空欄が多くなりすぎると読みづらくなります。

[, , , $value] = $data;

このようなコードは、何番目の値を取り出しているのか分かりにくくなるため、場合によっては通常の配列アクセスで書いた方がよいです。

$value = $data[3] ?? null;

連想配列を分割代入する

キーを指定して値を取り出す

PHP 7.1以降では、連想配列に対しても分割代入ができます。

$user = [
    'name' => '佐藤',
    'age' => 28,
    'city' => 'Tokyo',
];

['name' => $name, 'age' => $age] = $user;

echo $name; // 佐藤
echo $age;  // 28

連想配列の場合は、配列の順番ではなくキー名で値を取り出します。

$user = [
    'id' => 10,
    'name' => '鈴木',
];

['name' => $name, 'id' => $id] = $user;

echo $name; // 鈴木
echo $id;   // 10

左側では 'name' を先に書いていますが、問題ありません。

'name' キーの値が $name に入り、'id' キーの値が $id に入ります。

キー名と変数名は同じでなくてもよい

連想配列のキー名と、代入先の変数名は同じである必要はありません。

$user = [
    'name' => '高橋',
    'email' => 'takahashi@example.com',
];

['name' => $userName, 'email' => $mailAddress] = $user;

echo $userName;    // 高橋
echo $mailAddress; // takahashi@example.com

'name' => $userName は、「name キーの値を $userName に入れる」という意味です。

存在しないキーには注意する

連想配列で存在しないキーを指定すると、警告が出る可能性があります。

$user = [
    'name' => '佐藤',
];

['name' => $name, 'age' => $age] = $user;

この場合、age キーが存在しないため、未定義キーに関する警告が出ます。

構造が保証されていないデータでは、次のように ?? を使った方が安全です。

$name = $user['name'] ?? null;
$age = $user['age'] ?? null;

または、デフォルト値を足してから分割代入する方法もあります。

[
    'name' => $name,
    'age' => $age,
] = $user + [
    'name' => null,
    'age' => null,
];

フォーム入力、APIレスポンス、CSVなど、外部から受け取るデータではキーが必ず存在するとは限りません。

そのため、分割代入を使う前に、データ構造が安定しているか確認することが大切です。

ネストした配列を分割代入する

配列の中の配列も展開できる

分割代入は、ネストした配列にも使えます。

$data = [
    'user' => [
        'name' => '田中',
        'age' => 32,
    ],
    'status' => 'active',
];

[
    'user' => [
        'name' => $name,
        'age' => $age,
    ],
    'status' => $status,
] = $data;

echo $name;   // 田中
echo $age;    // 32
echo $status; // active

配列の構造が分かっている場合は、深い階層の値もまとめて取り出せます。

ネストが深い場合は読みやすさに注意する

ネストした分割代入は便利ですが、深くなりすぎると読みづらくなります。

[
    'user' => [
        'profile' => [
            'name' => $name,
            'email' => $email,
        ],
    ],
] = $data;

この程度であれば読めますが、さらに階層が深くなると、どの値を取り出しているのか分かりにくくなります。

外部データを扱う場合は、次のように ?? を使って明示的に取り出した方が安全なケースもあります。

$name = $data['user']['profile']['name'] ?? null;
$email = $data['user']['profile']['email'] ?? null;

分割代入は短く書ける構文ですが、常に短いコードがよいとは限りません。

実務では、読みやすさと安全性を優先することが重要です。

foreachで分割代入を使う

インデックス配列をループ内で展開する

分割代入は、foreach と組み合わせると便利です。

$users = [
    ['佐藤', 25],
    ['鈴木', 30],
    ['田中', 28],
];

foreach ($users as [$name, $age]) {
    echo "{$name}さんは{$age}歳です。" . PHP_EOL;
}

出力結果は次のようになります。

佐藤さんは25歳です。
鈴木さんは30歳です。
田中さんは28歳です。

通常なら、ループ内で配列の要素を個別に取り出す必要があります。

foreach ($users as $user) {
    $name = $user[0];
    $age = $user[1];

    echo "{$name}さんは{$age}歳です。" . PHP_EOL;
}

分割代入を使うと、ループ内の処理をすっきり書けます。

連想配列をループ内で展開する

連想配列の配列でも、foreach 内で分割代入できます。

$users = [
    [
        'name' => '佐藤',
        'age' => 25,
    ],
    [
        'name' => '鈴木',
        'age' => 30,
    ],
];

foreach ($users as ['name' => $name, 'age' => $age]) {
    echo "{$name}さんは{$age}歳です。" . PHP_EOL;
}

DBから取得したデータや、APIレスポンスを配列として処理する場合に便利です。

ただし、各要素に nameage が必ず存在する前提になります。

キーが存在しない可能性がある場合は、次のようにループ内で安全に取り出す方がよいです。

foreach ($users as $user) {
    $name = $user['name'] ?? '';
    $age = $user['age'] ?? null;

    echo "{$name}さんは{$age}歳です。" . PHP_EOL;
}

関数の戻り値を分割代入する

配列で返した複数の値を受け取る

PHPの関数は、複数の値を直接返すわけではありません。

しかし、配列として返せば、複数の値を返しているように扱えます。

function getUserData(): array
{
    return ['佐藤', 25, 'Tokyo'];
}

[$name, $age, $city] = getUserData();

echo $name; // 佐藤
echo $age;  // 25
echo $city; // Tokyo

このように、関数の戻り値が固定形式の配列であれば、分割代入で受け取ると分かりやすくなります。

連想配列で返す場合

連想配列で返す場合は、キーを指定して受け取れます。

function getUserData(): array
{
    return [
        'name' => '佐藤',
        'age' => 25,
        'city' => 'Tokyo',
    ];
}

['name' => $name, 'age' => $age] = getUserData();

echo $name; // 佐藤
echo $age;  // 25

連想配列で返すと、値の意味がキー名から分かるため、インデックス配列より読みやすくなることがあります。

explodeと分割代入を組み合わせる

文字列を分割して複数の変数に入れる

実務でよく使うのが、explode() と分割代入の組み合わせです。

$date = '2026-06-02';

[$year, $month, $day] = explode('-', $date);

echo $year;  // 2026
echo $month; // 06
echo $day;   // 02

メールアドレスを @ で分ける例もあります。

$email = 'user@example.com';

[$localPart, $domain] = explode('@', $email);

echo $localPart; // user
echo $domain;    // example.com

分割結果の数が足りない場合に注意する

explode() の結果数が想定と違う場合は注意が必要です。

$email = 'invalid-email';

[$localPart, $domain] = explode('@', $email);

この場合、@ がないため、explode() の結果は1要素だけになります。

そのため、$domain に対応する値が存在せず、警告が出る可能性があります。

安全に処理するなら、分割結果の数を確認します。

$email = 'invalid-email';

$parts = explode('@', $email);

if (count($parts) === 2) {
    [$localPart, $domain] = $parts;
} else {
    // 不正なメールアドレスとして処理する
}

外部から受け取った文字列を処理する場合は、分割代入だけに頼らず、事前チェックを入れるのが安全です。

preg_matchと分割代入を組み合わせる

正規表現の結果を受け取る

preg_match() のマッチ結果を受け取るときにも、分割代入を使えます。

$text = '商品ID: 12345';

if (preg_match('/商品ID: (\d+)/', $text, $matches)) {
    [, $productId] = $matches;

    echo $productId; // 12345
}

$matches[0] にはマッチ全体が入ります。

$matches[1] には、1つ目のキャプチャグループが入ります。

そのため、次のように先頭をスキップしています。

[, $productId] = $matches;

マッチ全体は不要で、キャプチャした値だけ使いたい場合に便利です。

parse_urlと分割代入を組み合わせる

URL解析結果を連想配列として受け取る

parse_url() は、URLを解析して連想配列を返します。

$url = 'https://example.com/path?name=sato';

$parts = parse_url($url);

['scheme' => $scheme, 'host' => $host, 'path' => $path] = $parts;

echo $scheme; // https
echo $host;   // example.com
echo $path;   // /path

URLの構造が決まっている場合は、必要な値をまとめて取り出せます。

URLによって存在しないキーがある

parse_url() の戻り値には、URLによって存在しないキーがあります。

たとえば、クエリ文字列がないURLでは、query キーは存在しません。

$url = 'https://example.com/path';

$parts = parse_url($url);

$query = $parts['query'] ?? null;

存在しない可能性があるキーを分割代入で取り出そうとすると、警告が出る可能性があります。

そのため、parse_url() の結果を扱うときは、必要に応じて ?? を使う方が安全です。

str_getcsvと分割代入を組み合わせる

CSV文字列を分解して受け取る

CSV形式の文字列を扱う場合は、str_getcsv() と分割代入を組み合わせると便利です。

$line = '佐藤,25,Tokyo';

[$name, $age, $city] = str_getcsv($line);

echo $name; // 佐藤
echo $age;  // 25
echo $city; // Tokyo

単純なカンマ区切りなら explode(',', $line) でも分割できます。

しかし、CSVとして扱うなら str_getcsv() の方が安全です。

カンマを含む値にも対応できる

CSVでは、値の中にカンマが含まれることがあります。

$line = '"Sato, Taro",25,Tokyo';

[$name, $age, $city] = str_getcsv($line);

echo $name; // Sato, Taro

explode(',', $line) では、このような値を正しく扱えません。

CSVデータを処理する場合は、str_getcsv() を使う方が適しています。

分割代入で値が余る場合と足りない場合

値が余る場合は無視される

右側の配列に値が多い場合、左側に対応する変数がない値は無視されます。

[$a, $b] = [10, 20, 30, 40];

echo $a; // 10
echo $b; // 20

3040 は使われません。

これは便利ですが、必要な値を受け取り忘れていてもエラーにならないため注意が必要です。

値が足りない場合は警告に注意する

右側の配列に値が足りない場合、存在しないキーを取り出そうとするため、警告が出る可能性があります。

[$a, $b, $c] = [10, 20];

echo $a; // 10
echo $b; // 20
echo $c; // null

結果として $cnull になることがありますが、警告が出るため安全な書き方とはいえません。

デフォルト値を用意するなら、次のように書けます。

$data = [10, 20];

[$a, $b, $c] = $data + [null, null, null];

echo $a; // 10
echo $b; // 20
echo $c; // null

または、より明示的に書くなら次のようにします。

$a = $data[0] ?? null;
$b = $data[1] ?? null;
$c = $data[2] ?? null;

構造が不安定なデータでは、分割代入よりも ?? を使った方が読みやすく安全な場合があります。

数値キーが0から始まらない配列に注意する

分割代入は基本的に0番目から見る

数値インデックスの分割代入では、基本的に 012 のようなキーを見に行きます。

$array = [
    1 => 'one',
    2 => 'two',
];

[$a, $b] = $array;

この場合、$array[0] が存在しないため、期待どおりに $a = 'one'$b = 'two' とはなりません。

配列のキーが 0 から始まっていない場合は注意が必要です。

array_valuesでキーを振り直す

順番で取り出したい場合は、array_values() でキーを振り直す方法があります。

$array = [
    1 => 'one',
    2 => 'two',
];

[$a, $b] = array_values($array);

echo $a; // one
echo $b; // two

ただし、array_values() を使うと、配列の順番に依存するコードになります。

連想配列や意味のあるキーを持つ配列であれば、キーを明示した方が安全です。

$array = [
    1 => 'one',
    2 => 'two',
];

[1 => $a, 2 => $b] = $array;

echo $a; // one
echo $b; // two

文字列に分割代入を使う場合の注意点

文字列をそのまま分割代入するのは適切ではない

JavaScriptでは、文字列を分割代入できる場面があります。

しかし、PHPでは次のような書き方は適切ではありません。

[$a, $b] = 'ab';

PHPの分割代入は、主に配列を対象に使う構文です。

厳密には、ArrayAccess を実装したオブジェクトにも使えますが、通常の文字列をそのまま分割代入するものではありません。

文字列を1文字ずつ分けたい場合はstr_splitを使う

文字列を1文字ずつ分けたい場合は、str_split() を使います。

[$a, $b] = str_split('ab');

echo $a; // a
echo $b; // b

文字列を区切り文字で分けたい場合は、explode() を使います。

[$first, $second] = explode('-', 'A-B');

echo $first;  // A
echo $second; // B

変数の入れ替えに分割代入を使う

一時変数なしで値を入れ替えられる

分割代入は、変数の値を入れ替えるときにも使えます。

$a = 'apple';
$b = 'banana';

[$a, $b] = [$b, $a];

echo $a; // banana
echo $b; // apple

一時変数を使う場合は、次のように書きます。

$temp = $a;
$a = $b;
$b = $temp;

分割代入を使うと、一時変数を用意せずに値を入れ替えられます。

参照を使った分割代入

参照代入もできる

PHPでは、分割代入で参照を使うこともできます。

$array = [1, 2];

[$a, &$b] = $array;

$b = 99;

echo $array[1]; // 99

$b$array[1] への参照になるため、$b を変更すると元の配列の値も変わります。

右辺が参照可能でない場合はエラーになる

参照を使う場合、右辺が参照可能である必要があります。

次のように、リテラル配列から直接参照を取ろうとする書き方は避けるべきです。

[$a, &$b] = [1, 2];

参照は便利な一方で、コードの挙動を追いづらくします。

実務では、特別な理由がない限り、多用しない方がよいです。

ArrayAccessオブジェクトにも分割代入できる

配列以外にも使えるケースがある

PHPの分割代入は、主に配列に対して使います。

ただし、厳密には ArrayAccess を実装したオブジェクトにも使える場合があります。

class MyArrayLikeObject implements ArrayAccess
{
    private array $data = [
        0 => 'A',
        1 => 'B',
    ];

    public function offsetExists(mixed $offset): bool
    {
        return isset($this->data[$offset]);
    }

    public function offsetGet(mixed $offset): mixed
    {
        return $this->data[$offset];
    }

    public function offsetSet(mixed $offset, mixed $value): void
    {
        $this->data[$offset] = $value;
    }

    public function offsetUnset(mixed $offset): void
    {
        unset($this->data[$offset]);
    }
}

$obj = new MyArrayLikeObject();

[$a, $b] = $obj;

echo $a; // A
echo $b; // B

ただし、通常のWeb開発では、まず配列に対する分割代入を理解しておけば十分です。

ArrayAccess オブジェクトへの分割代入は、少し発展的な内容として押さえておくとよいでしょう。

PHPとJavaScriptの分割代入の違い

JavaScriptの分割代入

JavaScriptでは、配列やオブジェクトを次のように分割代入できます。

const [a, b] = [1, 2];

const user = {
  name: '佐藤',
  age: 25
};

const { name, age } = user;

オブジェクトの場合、キー名と同じ変数名であれば短く書けます。

PHPの分割代入

PHPでは、配列の場合は次のように書きます。

[$a, $b] = [1, 2];

連想配列の場合は、キーと代入先の変数を明示します。

$user = [
    'name' => '佐藤',
    'age' => 25,
];

['name' => $name, 'age' => $age] = $user;

PHPには、JavaScriptのような次の省略記法はありません。

const { name, age } = user;

PHPでは、次のようにキー名と変数名を明示して書きます。

['name' => $name, 'age' => $age] = $user;

JavaScriptの分割代入に慣れている場合は、連想配列の書き方の違いに注意しましょう。

実務で分割代入を使いやすい場面

固定形式の配列を扱う場合

配列の構造が決まっている場合、分割代入は便利です。

[$year, $month, $day] = explode('-', '2026-06-02');

日付、コード値、固定フォーマットの文字列などを分解するときに使いやすいです。

foreachで表形式のデータを処理する場合

同じ構造の配列が並んでいる場合、foreach と分割代入の相性はよいです。

$items = [
    ['Apple', 100],
    ['Banana', 150],
];

foreach ($items as [$name, $price]) {
    echo "{$name}: {$price}円" . PHP_EOL;
}

ループの中で何を使っているのかが分かりやすくなります。

関数の戻り値を受け取る場合

関数が固定形式の配列を返す場合も、分割代入が使えます。

function splitFullName(string $fullName): array
{
    return explode(' ', $fullName);
}

[$firstName, $lastName] = splitFullName('Taro Yamada');

ただし、戻り値の数が不安定になる可能性がある関数では注意が必要です。

分割代入を使うときの注意点

外部データには慎重に使う

フォーム入力、APIレスポンス、CSV、スクレイピング結果など、外部から受け取るデータは構造が崩れる可能性があります。

['name' => $name, 'email' => $email] = $requestData;

この書き方は、nameemail が必ず存在する場合には便利です。

しかし、どちらかのキーが存在しない場合は警告が出る可能性があります。

安全に書くなら、次のようにします。

$name = $requestData['name'] ?? '';
$email = $requestData['email'] ?? '';

複雑にしすぎない

分割代入は便利ですが、複雑にしすぎると読みづらくなります。

[
    'user' => [
        'profile' => [
            'name' => $name,
            'email' => $email,
        ],
    ],
] = $data;

配列構造が複雑な場合は、無理に分割代入を使わず、明示的に取り出す方が分かりやすいことがあります。

$name = $data['user']['profile']['name'] ?? null;
$email = $data['user']['profile']['email'] ?? null;

配列の順番に依存しすぎない

インデックス配列では、分割代入は配列の順番に依存します。

[$name, $age, $city] = $user;

この場合、$user[0] が名前、$user[1] が年齢、$user[2] が都市であることが前提です。

データの意味を明確にしたい場合は、連想配列を使った方が安全です。

['name' => $name, 'age' => $age, 'city' => $city] = $user;

PHPの分割代入のまとめ

PHPの分割代入は、配列の値を複数の変数にまとめて代入できる便利な構文です。

[$a, $b] = [1, 2];

これは、次のように書くのと近い意味です。

$a = 1;
$b = 2;

連想配列では、キーを指定して値を取り出せます。

['name' => $name, 'age' => $age] = $user;

foreach と組み合わせると、配列の処理を簡潔に書けます。

foreach ($users as ['name' => $name, 'age' => $age]) {
    echo "{$name}: {$age}" . PHP_EOL;
}

ただし、存在しないキーや不足している値を取り出そうとすると、警告が出る可能性があります。

そのため、外部データや構造が不安定なデータでは、?? を使ったり、デフォルト値を用意したりすることが大切です。

PHPの分割代入は、次のように使い分けると実務で扱いやすくなります。

場面おすすめ
配列の構造が固定されている分割代入を使う
連想配列のキーが必ず存在するキー指定の分割代入を使う
外部データでキーが不確実?? で安全に取り出す
foreach で同じ構造の配列を処理する分割代入を使う
ネストが深い配列を扱う読みやすさを優先して判断する

分割代入は、うまく使うとコードを短く読みやすくできます。

一方で、データ構造が崩れたときに警告が出やすい構文でもあります。

そのため、構造が保証されている配列には分割代入、構造が不安定な外部データには ?? や事前チェックを使う、という使い分けを意識するとよいでしょう。

以上、PHPの分割代入についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次