7.

PHP 連想配列 (Map) 完全ガイド (作成/マージ/順序/性能)

編集
この記事の要点
  • PHP の連想配列は 文字列・数値キーを持てる Hash Map。Java HashMap や JS Map に相当
  • 作成: ['key' => 'value'] または array('k' => 'v')
  • 挿入順を保持するハッシュテーブル。検索は平均 O(1)
  • マージは array_merge / + / Spread ...$arr で挙動が違うので注意
  • Laravel Collection を使えば map / filter / reduce が流暢に書ける

連想配列の作成と基本操作

// 作成
$user = [
    'name'  => 'Taro',
    'age'   => 30,
    'roles' => ['admin', 'editor'],
];

// 旧式の書き方 (PHP 5.3 以前)
$user = array('name' => 'Taro', 'age' => 30);

// アクセス
echo $user['name'];              // Taro

// 追加・更新
$user['email'] = 'taro@example.com';
$user['age']   = 31;

// 削除
unset($user['roles']);

// 存在チェック
isset($user['name']);            // true (null だと false)
array_key_exists('age', $user);  // true (null でも true)

// サイズ
count($user);                    // 要素数

// 全削除
$user = [];

各言語の Map 表記比較

言語表記
PHP['name' => 'Taro', 'age' => 30]
JavaMap.of("name", "Taro", "age", 30)
JavaScript (Object){ name: 'Taro', age: 30 }
JavaScript (Map)new Map([['name','Taro'],['age',30]])
Python (dict){'name': 'Taro', 'age': 30}
KotlinmapOf("name" to "Taro", "age" to 30)

順序の保持

PHP の連想配列は挿入順を保持します(PHP 7 以降は実装レベルでも安定):

$arr = [];
$arr['c'] = 3;
$arr['a'] = 1;
$arr['b'] = 2;

foreach ($arr as $k => $v) echo "$k=$v ";
// c=3 a=1 b=2  (挿入順)

// ソートしたい場合
ksort($arr);      // キーでソート
asort($arr);      // 値でソート (キー保持)
arsort($arr);     // 値降順
uksort($arr, fn($a, $b) => strcmp($a, $b));   // カスタム

マージ操作: array_merge / + / spread

$a = ['x' => 1, 'y' => 2];
$b = ['y' => 20, 'z' => 30];

// array_merge: 後勝ち (文字列キーで上書き)
array_merge($a, $b);
// ['x' => 1, 'y' => 20, 'z' => 30]

// + 演算子: 先勝ち (左側優先)
$a + $b;
// ['x' => 1, 'y' => 2, 'z' => 30]

// 数値キーは挙動が違う
$a = [10, 20, 30];
$b = [100, 200, 300];
array_merge($a, $b);
// [10, 20, 30, 100, 200, 300]  数値キーは振り直し

$a + $b;
// [10, 20, 30]  数値キーは先勝ち → b は破棄

// PHP 7.4+ Spread
$merged = [...$a, ...$b];      // array_merge 相当

// PHP 8.1+ 文字列キー Spread
$merged = ['x' => 1, ...$b];   // OK (PHP 8.1+)

ネストされた Map

$config = [
    'database' => [
        'host' => 'localhost',
        'port' => 3306,
        'options' => [
            'charset' => 'utf8mb4',
            'timezone' => '+09:00',
        ],
    ],
    'cache' => [
        'driver' => 'redis',
    ],
];

// ネストアクセス
echo $config['database']['options']['charset'];   // utf8mb4

// 存在チェック (ネスト深いと面倒)
isset($config['database']['options']['charset']);

// Null Coalescing でショートカット
$charset = $config['database']['options']['charset'] ?? 'utf8';

// Laravel data_get / Arr::get
data_get($config, 'database.options.charset', 'utf8');
\Illuminate\Support\Arr::get($config, 'database.options.charset', 'utf8');

検索性能とメモリ

操作計算量備考
$arr[$key]O(1)ハッシュ参照
isset($arr[$key])O(1)速い
array_key_exists()O(1)isset より若干遅い
in_array($v, $arr)O(n)★ 値検索は遅い
array_search($v, $arr)O(n)同上
count($arr)O(1)キャッシュされている

PHP 配列は1 要素あたり 100-150 byte 程度(zend_array のオーバーヘッド)を消費。大量データには SplFixedArray や generator を検討。

Laravel Collection との比較

use Illuminate\Support\Collection;

// 配列をコレクション化
$users = collect([
    ['name' => 'Taro', 'age' => 30],
    ['name' => 'Hanako', 'age' => 25],
    ['name' => 'Jiro', 'age' => 40],
]);

// チェーン操作
$result = $users
    ->filter(fn($u) => $u['age'] >= 30)
    ->sortByDesc('age')
    ->map(fn($u) => $u['name'])
    ->values()
    ->all();
// ['Jiro', 'Taro']

// reduce
$totalAge = $users->reduce(fn($sum, $u) => $sum + $u['age'], 0);   // 95

// groupBy / countBy
$byRole = $users->groupBy('role');

命名規則 (PSR-12 / 一般慣習)

  • キーは snake_case が PHP の慣習 (user_id)
  • JS と JSON 互換を意識する場合は camelCase (userId)
  • 定数キー (config) は SCREAMING_SNAKE_CASE (DB_HOST)
  • クラスのプロパティは camelCase / フィールドアクセスと統一

FAQ

Q: PHP に純粋な「リスト」と「Map」の区別はある?
A: 内部的には全部「順序付き連想配列」。array_is_list() (PHP 8.1+) で「0 始まり連番のキー」かを判定可能。

Q: SplObjectStorageWeakMap はいつ使う?
A: オブジェクトをキーにしたい場合。連想配列は文字列・数値キーしか持てません。WeakMap (PHP 8) は GC 対象に弱参照を持てます。

Q: 連想配列 vs オブジェクトの使い分け
A: 構造が決まっているなら class / readonly value object、汎用データなら連想配列。最近は DTO / Enum / record-like なクラスが推奨です。

編集
Post Share
子ページ
  1. キーと値の取得
同階層のページ
  1. 基本的なルール
  2. データ型
  3. 変数
  4. 定数
  5. 配列
  6. コレクション(List,Set,Queue)
  7. Map(連想配列)
  8. 演算子
  9. 条件分岐
  10. 繰り返し制御文
  11. クラス
  12. メソッド
  13. インスタンス化
  14. コンストラクタ
  15. staticキーワード
  16. オーバーロード
  17. 継承
  18. オーバーライド
  19. this
  20. super
  21. パッケージ
  22. アクセス修飾子
  23. 抽象クラス・メソッド
  24. インターフェース
  25. カプセル化
  26. データベース接続
  27. セッション
  28. ファイル入出力
  29. ラムダ式