PHP 連想配列の使い方|作成・取得・追加・削除からforeach・関数まで

基本文法・構文ガイド
  • カテゴリ: 配列操作(PHP標準構文)
  • 対象バージョン: PHP 7.4 〜 8.4(array_key_first()/array_key_last()はPHP 7.3以降、array_key_exists()foreachなど基本機能は長期間安定)
  • 主な関数/構文: $arr = ['key' => 値] / foreach ($arr as $key => $value) / array_key_exists() / isset() / array_keys() / array_values() / array_merge()
  • 関連: 配列への要素追加 / in_array / json_encode・json_decode / foreachループ
  • 変更履歴: 連想配列そのものの仕様は長期的に安定。PHP 7.3でarray_key_first()/array_key_last()、PHP 7.4でアロー関数fn()による短縮コールバック記法が追加された

要点(TL;DR)

  • 連想配列は文字列や整数をキーにして値を管理する配列。$arr = ['name' => 'Taro', 'age' => 20];のように定義する
  • 値の取得は$arr['name']、追加・更新はどちらも同じ$arr['key'] = 値;という書き方で行う(既存キーなら更新、無ければ追加)
  • キーの存在確認はarray_key_exists()(値がnullでも「ある」と判定)とisset()(値がnullだと「ない」扱いになる)で挙動が違う
  • 全要素を処理するにはforeach ($arr as $key => $value) {}を使う
  • データベースの1行やJSON(APIレスポンスなど)は、連想配列として受け取って扱うことが多い(PDO::FETCH_ASSOCjson_decode($json, true)

概要

PHPの配列には、要素の並び順であるインデックス(0, 1, 2…)で値にアクセスする「数値配列」と、任意の文字列や整数をキーとして値にアクセスする「連想配列(Associative Array)」があります。PHPでは実際には両者を区別する専用の型はなく、どちらも同じarray型の内部で「キーと値のペアを順序付けて保持したもの」として扱われます。連想配列は、名前付きのデータを直感的に扱いたいとき——ユーザー情報、設定値、データベースの1行、JSON形式のAPIレスポンスなど——に特に威力を発揮します。この記事では、連想配列の作成方法から値の取得・追加・削除、ループ処理、便利な組み込み関数、よくある落とし穴までをコード例つきでまとめて解説します。

連想配列の作り方(構文比較)

書き方備考
array()構文array('name' => 'Taro', 'age' => 20)PHP 4以降で使える古い書き方。今も動くが冗長
[]短縮構文['name' => 'Taro', 'age' => 20]PHP 5.4以降で利用可能。現在はこちらが標準的な書き方
キーの型'key'(文字列)または0(整数)数値だけの文字列キー('8'など、先頭が0でないもの)は自動的に整数キーへ変換される

キーを省略して値だけを並べた場合は、0から始まる連番の数値キーが自動的に振られます(通常の数値配列と同じ挙動)。連想配列と数値配列を1つの配列の中で混在させることもできますが、可読性が下がるため用途を分けて使うのが基本です。

使用例

連想配列を作成する

<?php

$user_info = [
    'name' => 'John Doe',
    'email' => 'john@example.com',
    'age' => 30,
];

print_r($user_info);
// 出力: Array ( [name] => John Doe [email] => john@example.com 日付未入力 => 30 )

値を取得する

<?php

$name = $user_info['name'];
echo $name; // 出力: John Doe

// 存在しないキーにアクセスすると、PHP 8では E_WARNING(Undefined array key)が発生し null が返る
$nickname = $user_info['nickname'] ?? '未設定';
echo $nickname; // 出力: 未設定

存在しないキーに直接アクセスすると、PHP 7系ではNotice: Undefined index、PHP 8.0以降ではWarning: Undefined array keyが発生します。値が存在しない可能性があるキーには、??(Null合体演算子)でデフォルト値を用意しておくと警告を避けられます。

値を追加・更新する

<?php

// 新しいキーを追加
$user_info['city'] = 'New York';

// 既存のキーに代入すると「更新」になる
$user_info['email'] = 'john.doe@example.com';

print_r($user_info);
// 出力: Array ( [name] => John Doe [email] => john.doe@example.com 日付未入力 => 30 [city] => New York )

連想配列では$arr['key'] = 値;という同じ書き方が「追加」と「更新」を兼ねます。指定したキーが存在しなければ新規追加、既に存在すればその値を上書きします。数値配列の末尾・先頭・途中への要素追加は書き方が異なるため、PHPで配列に要素を追加する方法で目的別にまとめています。

値を削除する

<?php

unset($user_info['age']);

print_r($user_info);
// 出力: Array ( [name] => John Doe [email] => john.doe@example.com [city] => New York )

配列から要素を削除するにはunset($arr['key'])を使います。数値配列と違い、連想配列では削除してもキーが詰め直されることはありません。

キーの存在を確認する(isset と array_key_exists の違い)

<?php

$data = ['name' => 'Taro', 'nickname' => null];

var_dump(array_key_exists('nickname', $data)); // 出力: bool(true) ← キー自体は存在する
var_dump(isset($data['nickname']));            // 出力: bool(false) ← 値が null なので false

var_dump(array_key_exists('age', $data)); // 出力: bool(false)
var_dump(isset($data['age']));            // 出力: bool(false)

isset()は「キーが存在し、かつ値がnullでない」ときにだけtrueを返します。値がnullで入っているキーを「存在する」と正しく判定したい場合はarray_key_exists()を使う必要があります。単に「値が使える状態か」を確認したいだけならisset()で十分です。

foreachで全要素をループする

<?php

foreach ($user_info as $key => $value) {
    echo "{$key}: {$value}\n";
}
// 出力:
// name: John Doe
// email: john.doe@example.com
// city: New York

連想配列のすべての要素をキーと値のペアで処理するにはforeach ($arr as $key => $value)を使います。キーが不要であればforeach ($arr as $value)と書くこともできます。foreachのより詳しい使い方や参照渡し・多次元配列での注意点はPHP foreachの使い方で解説しています。

ネストした連想配列(多次元)

<?php

$users = [
    'user1' => ['name' => 'Alice', 'email' => 'alice@example.com'],
    'user2' => ['name' => 'Bob', 'email' => 'bob@example.com'],
];

foreach ($users as $user_id => $user_details) {
    echo "User ID: {$user_id}\n";
    foreach ($user_details as $key => $value) {
        echo "  {$key}: {$value}\n";
    }
}

連想配列の値として別の連想配列を持たせることで、階層構造を持つデータを表現できます。ネストが深くなる場合は、存在しないキーへのアクセスで警告が出ないよう$users['user3']['name'] ?? nullのように??を併用すると安全です。

連想配列と数値配列を相互変換する

<?php

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

$keys = array_keys($user);     // 出力: Array ( [0] => name [1] => age )
$values = array_values($user); // 出力: Array ( [0] => Taro [1] => 20 )

// キーと値を入れ替える
$flipped = array_flip($user);
print_r($flipped); // 出力: Array ( [Taro] => name [20] => age )

// キーの配列と値の配列から連想配列を作る
$combined = array_combine(['name', 'age'], ['Jiro', 25]);
print_r($combined); // 出力: Array ( [name] => Jiro 日付未入力 => 25 )

array_keys()array_values()はそれぞれキー・値だけを数値配列として取り出します。array_flip()はキーと値を入れ替えます(値が重複していると後の要素で上書きされる点に注意)。array_combine()はキー用配列と値用配列から連想配列を組み立てます。PHP 8.0以降、2つの配列の要素数が一致しない場合はValueErrorが発生します。

連想配列をソートする

<?php

$scores = ['Taro' => 80, 'Jiro' => 95, 'Hanako' => 70];

// 値でソート(キーとの対応を保持)
asort($scores);
print_r($scores); // 出力: Array ( [Hanako] => 70 [Taro] => 80 [Jiro] => 95 )

// キーでソート
ksort($scores);
print_r($scores); // 出力: Array ( [Hanako] => 70 [Jiro] => 95 [Taro] => 80 )

連想配列をsort()でソートすると、値の並び替えと同時にキーが0から振り直されてしまい、キーと値の対応が崩れます。キーとの対応を保ったまま並び替えたい場合は、値基準のasort()arsort()、キー基準のksort()krsort()、独自ロジックのuasort()uksort()を使います。

JSONとの相互変換

<?php

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

// 連想配列 → JSON文字列
$json = json_encode($user);
echo $json; // 出力: {"name":"Taro","age":20}

// JSON文字列 → 連想配列(第2引数に true を渡す)
$decoded = json_decode($json, true);
print_r($decoded); // 出力: Array ( [name] => Taro 日付未入力 => 20 )

APIレスポンスや設定ファイルなど、JSON形式のデータを扱う場面では連想配列との相互変換が頻出します。json_decode()は第2引数を省略する(またはfalseを渡す)とstdClassオブジェクトを返すため、連想配列として扱いたい場合は必ずtrueを指定します。詳細な変換ルールやエラー処理はjson_encodeの使い方json_decodeの使い方で解説しています。

データベースの結果を連想配列として扱う

<?php

$stmt = $pdo->query('SELECT id, name, email FROM users WHERE id = 1');
$row = $stmt->fetch(PDO::FETCH_ASSOC);

// $row は列名をキーとした連想配列になる
echo $row['email']; // 出力: charlie@example.com

PDOでPDO::FETCH_ASSOCを指定すると、取得した1行が「列名 => 値」の連想配列として返されます。カラム名でアクセスできるため、インデックス番号で列を管理するより可読性が大きく向上します。

よくある落とし穴・注意

  • 存在しないキーへの直接アクセスで警告が出る:PHP 8.0以降はWarning: Undefined array keyが発生します。値が無い可能性があるキーには??(Null合体演算子)やisset()での事前チェックを使います。
  • isset()はnull値を「存在しない」と判定する:値としてnullを明示的に入れている場合、isset()falseを返します。キー自体の有無を正確に知りたいときはarray_key_exists()を使います。
  • 数値だけの文字列キーは自動的に整数へ変換される$arr['8']は内部的に$arr[8]として扱われます。ただし'08'のように先頭に0が付く場合は文字列キーのまま維持されます。
  • sort()を使うとキーが失われる:連想配列にsort()を使うと値だけが並び替えられ、キーは0からの数値キーに振り直されます。キーとの対応を保ちたい場合はasort()ksort()を使います。
  • array_merge()と+演算子はキーの優先順位が逆array_merge()は文字列キーが重複すると後ろの配列が勝ち、+演算子は前の配列が勝ちます。取り違えると意図しない値で上書きされます。

代替・関連関数との比較

関数/構文用途戻り値・特徴
isset($arr['key'])キーが存在し、値がnullでないか確認bool(null値はfalse扱い)
array_key_exists('key', $arr)キーが存在するか確認(値がnullでもtrue)bool
in_array()値そのものが配列に含まれるか確認bool(キーではなく値で判定)
array_keys() / array_values()キーだけ・値だけを数値配列で取得array
array_flip()キーと値を入れ替えるarray(値の重複に注意)
ksort() / asort()キー基準/値基準でソート(キー対応を維持)bool(元の配列を直接書き換える)

トラブルシュート(症状別)

症状原因対処
「Undefined array key」の警告が出る存在しないキーに直接アクセスしている??でデフォルト値を用意するか、事前にisset()/array_key_exists()で確認する
値がnullのはずのキーでisset()がfalseになるisset()は値がnullだと「存在しない」と判定する仕様キーの有無だけを知りたい場合はarray_key_exists()を使う
ソート後にキーと値の対応がおかしくなったsort()rsort()を使い、キーが振り直されたキー対応を保つasort()arsort()ksort()を使う
json_decode()の結果が配列として扱えない(->でしかアクセスできない)json_decode()の第2引数を省略しているためstdClassオブジェクトになっているjson_decode($json, true)のように第2引数にtrueを渡す
array_combine()でエラーになるキー用配列と値用配列の要素数が一致していない(PHP 8以降はValueError)両方の配列の要素数を揃えてから渡す

よくある質問(FAQ)

Q. 連想配列と数値配列(通常の配列)の違いは何ですか?

A. PHPの配列型はどちらも同じarrayです。違いはキーの種類で、数値配列は0から始まる連番の数値キーを使うのに対し、連想配列は文字列や任意の整数をキーとして使います。名前付きでデータにアクセスしたいときは連想配列、順序だけが意味を持つリストには数値配列が向いています。

Q. キーの存在確認は isset() と array_key_exists() のどちらを使うべきですか?

A. 「値が使える状態かどうか」を確認したいだけならisset()で十分です。値としてnullが明示的に入っている場合でも「キー自体はある」と正確に判定したい場合はarray_key_exists()を使います。isset()のほうがわずかに高速ですが、両者の挙動の違いを理解した上で使い分けることが重要です。

Q. 連想配列をキーの昇順や値の昇順で並び替えるにはどうすればいいですか?

A. キーの対応を保ったまま並び替える場合、値基準ならasort()(降順はarsort())、キー基準ならksort()(降順はkrsort())を使います。独自の比較ロジックが必要な場合はuasort()uksort()にコールバック関数を渡します。

Q. 連想配列をJSON文字列に変換・復元するにはどうすればいいですか?

A. 変換にはjson_encode($arr)、復元にはjson_decode($json, true)を使います。json_decode()は第2引数にtrueを渡さないとstdClassオブジェクトになる点に注意してください。

Q. 連想配列のキーに数値の文字列を使うとどうなりますか?

A. '8'のように先頭が0でない数字だけの文字列キーは、PHPが自動的に整数キー8へ変換します。一方'08''8.5'のように数値として単純でない文字列は、文字列キーのまま保持されます。意図せずキーの型が変わることがあるため、キーの型に依存した比較を行う場合は注意が必要です。

関連記事

参考リンク

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする

コメント