array_column とは?PHPで多次元配列から列を抽出

はい、PHPの array_column 関数について、多次元配列からの列抽出に焦点を当て、約5000語の詳細な解説記事を作成します。


PHPのarray_column徹底解説:多次元配列から意図した「列」を自在に抽出する

多次元配列は、PHPを含む多くのプログラミング言語で頻繁に利用されるデータ構造です。特に、データベースから取得した結果セット、CSVファイルの内容をパースしたもの、あるいは外部APIから取得したJSONデータをデコードしたものなど、構造化されたデータを扱う際に欠かせません。

しかし、これらの多次元配列から特定の情報だけを取り出したい場合、例えば「すべてのユーザーのIDだけをリストアップしたい」「商品のリストから商品名だけを抽出したい」「注文履歴から各注文の合計金額を抽出したい」といったタスクに直面することがあります。

このようなとき、PHPには非常に便利で効率的な関数、array_column が用意されています。この関数を適切に使いこなすことで、多次元配列からのデータ抽出が驚くほど簡単になり、コードの可読性、保守性、さらにはパフォーマンスも向上させることができます。

本記事では、PHPの array_column 関数について、その基本的な使い方から、より高度な応用例、知っておくべき注意点、さらには他の関連関数との比較に至るまで、約5000語にわたって詳細に解説します。この記事を読み終える頃には、あなたは array_column を自在に操り、多次元配列からのデータ抽出タスクを効率的に解決できるようになっているでしょう。

1. 多次元配列とデータ抽出の課題

まず、なぜ array_column のような関数が必要なのか、多次元配列からのデータ抽出における典型的な課題について考えてみましょう。

例えば、以下のようなユーザー情報の多次元配列があるとします。

php
$users = [
['id' => 101, 'name' => '山田 太郎', 'email' => '[email protected]', 'age' => 30],
['id' => 102, 'name' => '佐藤 花子', 'email' => '[email protected]', 'age' => 25],
['id' => 103, 'name' => '田中 一郎', 'email' => '[email protected]', 'age' => 35],
// ... さらに多くのユーザーデータ
];

この配列から、「すべてのユーザーのメールアドレスだけをリスト形式で取得したい」という要件があったとします。array_column を知らない場合、あるいは使用できない古いPHPバージョンを使用している場合、おそらく以下のような方法でデータを抽出することになるでしょう。

手動でのループ処理(foreach

“`php
$emails = [];
foreach ($users as $user) {
// 各要素($user)が配列であることを前提とする
// また、各要素に ‘email’ キーが存在することを前提とする
if (isset($user[‘email’])) {
$emails[] = $user[‘email’];
}
}

print_r($emails);
/
出力例:
Array
(
[0] => [email protected]
[1] => [email protected]
[2] => [email protected]
// …
)
/
“`

このコードは目的を達成できますが、いくつか課題があります。

  • コードの冗長さ: 単に特定の列の値を取得したいだけなのに、初期化用の空配列を用意し、ループを回し、各要素にアクセスし、結果配列に追加するという手順が必要です。コードの行数が多くなり、意図が瞬時に理解しづらい場合があります。
  • エラーハンドリング: 各要素が期待通りの構造(この場合は連想配列で 'email' キーが存在すること)であることを保証する必要があります。上の例では isset() で簡単なチェックを入れていますが、より堅牢なコードを書くにはさらにチェックが必要になる場合もあります。
  • パフォーマンス: PHPレベルでのループ処理は、内部的にC言語で実装された専用関数に比べてオーバーヘッドが大きい場合があります。特に配列の要素数が非常に多い場合、この違いが顕著になることがあります。

array_map を使用した方法

array_map 関数も、配列の各要素に関数を適用するという点でデータ抽出に利用できます。

“`php
// 無名関数(クロージャ)を使用する場合
$emails_map = array_map(function($user) {
// ここでも ‘email’ キーの存在を前提とする
return $user[‘email’] ?? null; // キーが存在しない場合に備える
}, $users);

// アロー関数 (PHP 7.4+) を使用する場合
$emails_map_arrow = array_map(fn($user) => $user[‘email’] ?? null, $users);

print_r($emails_map);
/
出力例(キーが存在しない行がある場合、その位置に null が入る可能性がある):
Array
(
[0] => [email protected]
[1] => [email protected]
[2] => [email protected]
// …
)
/
“`

array_map を使うと foreach よりは簡潔に書ける場合がありますが、やはり無名関数やアロー関数を定義する必要があります。また、array_map は元の配列の構造(要素数やキー)を維持しようとする傾向があるため、キーが存在しない要素があった場合に null などが入る可能性があり、後続処理で予期しない結果を招くことがあります。

このような背景から、多次元配列から特定の列(またはインデックス)の値だけを効率的かつシンプルに抽出するための専用関数として、array_column が導入されました。

2. array_column とは? 基本的な使い方

array_column は、PHP 5.5.0 で導入された関数です。この関数は、入力された多次元配列の各要素から、指定されたキーに対応する値の配列を返します。オプションで、結果配列のキーとして使用する列を指定することもできます。

関数のシグネチャ(定義)は以下の通りです。

php
array_column(array $array, int|string|null $column_key, int|string|null $index_key = null): array

それぞれの引数について詳しく見ていきましょう。

  1. $array (必須):

    • 入力となる多次元配列です。通常、各要素が連想配列(文字列キー)または数値添字配列(数値キー)である配列を想定しています。array_column は、この $array の各要素(つまり、各行)を処理します。
  2. $column_key (必須):

    • 抽出したい「列」を指定します。これは、各要素(各行)内のキーに対応します。
    • 値は、そのキーの数値添字または文字列キーです。
    • 例えば、先の $users 配列から 'name' 列を抽出したい場合は 'name' を指定します。
    • もし null を指定した場合、array_column は各要素全体(各行全体)を結果配列の要素として返します。この使い方は、後述の $index_key と組み合わせて使うことが多いです。
  3. $index_key (オプション, デフォルト null):

    • 結果として返される配列のキーとして使用したい「列」を指定します。これは、各要素(各行)内のキーに対応します。
    • 値は、そのキーの数値添字または文字列キーです。
    • この引数を省略するか null を指定した場合、結果配列は0から始まる数値添字配列となります。
    • 特定の列の値(例えばユーザーID)を結果配列のキーとして使用したい場合に便利です。

返り値は、指定された $column_key の値を要素とする新しい配列です。

基本的な使い方 $column_key のみ指定

最も一般的な使い方は、特定の列の値だけを抽出することです。これは $column_key 引数のみを指定して行います。

先の $users 配列からメールアドレスのリストを取得する例を array_column で書き直してみましょう。

“`php
$users = [
[‘id’ => 101, ‘name’ => ‘山田 太郎’, ‘email’ => ‘[email protected]’, ‘age’ => 30],
[‘id’ => 102, ‘name’ => ‘佐藤 花子’, ‘email’ => ‘[email protected]’, ‘age’ => 25],
[‘id’ => 103, ‘name’ => ‘田中 一郎’, ‘email’ => ‘[email protected]’, ‘age’ => 35],
];

$emails = array_column($users, ‘email’);

print_r($emails);
/
出力:
Array
(
[0] => [email protected]
[1] => [email protected]
[2] => [email protected]
)
/
“`

このコードは、foreacharray_map を使用した例と比較して、驚くほど簡潔です。たった1行で目的の配列が得られました。

同様に、ユーザー名のリストを取得したい場合は 'name' を、IDのリストを取得したい場合は 'id'$column_key に指定します。

“`php
$names = array_column($users, ‘name’);
$ids = array_column($users, ‘id’);

print_r($names);
/
出力:
Array
(
[0] => 山田 太郎
[1] => 佐藤 花子
[2] => 田中 一郎
)
/

print_r($ids);
/
出力:
Array
(
[0] => 101
[1] => 102
[2] => 103
)
/
“`

$column_key が数値キーの場合

入力配列の各要素が数値添字配列である場合も、array_column は同様に使えます。この場合、$column_key には数値(0から始まるインデックス)を指定します。

“`php
$data = [
[10, ‘りんご’, 150],
[20, ‘バナナ’, 200],
[30, ‘みかん’, 100],
];

// 1列目(インデックス0)の値を抽出
$ids = array_column($data, 0); // [10, 20, 30]

// 2列目(インデックス1)の値を抽出
$names = array_column($data, 1); // [‘りんご’, ‘バナナ’, ‘みかん’]

// 3列目(インデックス2)の値を抽出
$prices = array_column($data, 2); // [150, 200, 100]

print_r($ids);
/
出力:
Array
(
[0] => 10
[1] => 20
[2] => 30
)
/

print_r($names);
/
出力:
Array
(
[0] => りんご
[1] => バナナ
[2] => みかん
)
/

print_r($prices);
/
出力:
Array
(
[0] => 150
[1] => 200
[2] => 100
)
/
“`

このように、$column_key は入力配列の各要素のキーの型(文字列か数値か)に合わせて指定します。

3. $index_key を活用する

array_column のもう一つの強力な機能は、結果配列のキーを、入力配列の別の列の値で指定できることです。これは $index_key 引数を使用します。

例えば、ユーザーIDをキーとして、ユーザー名を値とする連想配列を作成したい場合を考えます。

“`php
$users = [
[‘id’ => 101, ‘name’ => ‘山田 太郎’, ‘email’ => ‘[email protected]’, ‘age’ => 30],
[‘id’ => 102, ‘name’ => ‘佐藤 花子’, ‘email’ => ‘[email protected]’, ‘age’ => 25],
[‘id’ => 103, ‘name’ => ‘田中 一郎’, ‘email’ => ‘[email protected]’, ‘age’ => 35],
];

// ‘name’ 列の値を抽出し、そのキーとして ‘id’ 列の値を使用する
$idToName = array_column($users, ‘name’, ‘id’);

print_r($idToName);
/
出力:
Array
(
[101] => 山田 太郎
[102] => 佐藤 花子
[103] => 田中 一郎
)
/
“`

このように、$column_key には値として欲しい列のキーを、$index_key には結果配列のキーとして使いたい列のキーを指定します。

これも foreach ループで実現しようとすると、以下のようになります。

php
$idToName_manual = [];
foreach ($users as $user) {
// idとnameキーが存在することを前提
if (isset($user['id']) && isset($user['name'])) {
$idToName_manual[$user['id']] = $user['name'];
}
}
print_r($idToName_manual); // array_columnと同じ結果が得られる

やはり array_column を使用する方が、はるかに簡潔で意図が明確なコードになります。

$index_key に数値キーを指定する場合

入力配列の要素が数値添字配列の場合も、$index_key に数値インデックスを指定できます。

“`php
$data = [
[10, ‘りんご’, 150],
[20, ‘バナナ’, 200],
[30, ‘みかん’, 100],
];

// 値としてインデックス 1 の列 (‘りんご’など) を抽出し、
// キーとしてインデックス 0 の列 (10など) を使用する
$idToName_numeric = array_column($data, 1, 0);

print_r($idToName_numeric);
/
出力:
Array
(
[10] => りんご
[20] => バナナ
[30] => みかん
)
/
“`

$column_keynull を指定する場合

$column_keynull を指定すると、array_column は各要素全体(各行全体)を結果配列の要素として返します。この使い方は通常、$index_key と組み合わせて、特定の列をキーとした元の行データの連想配列を作成したい場合に利用します。

“`php
$users = [
[‘id’ => 101, ‘name’ => ‘山田 太郎’, ‘email’ => ‘[email protected]’, ‘age’ => 30],
[‘id’ => 102, ‘name’ => ‘佐藤 花子’, ‘email’ => ‘[email protected]’, ‘age’ => 25],
[‘id’ => 103, ‘name’ => ‘田中 一郎’, ‘email’ => ‘[email protected]’, ‘age’ => 35],
];

// 各行の配列を抽出し、そのキーとして ‘id’ 列の値を使用する
$usersById = array_column($users, null, ‘id’);

print_r($usersById);
/*
出力:
Array
(
[101] => Array
(
[id] => 101
[name] => 山田 太郎
[email] => [email protected]
[age] => 30
)

[102] => Array
    (
        [id] => 102
        [name] => 佐藤 花子
        [email] => [email protected]
        [age] => 25
    )

[103] => Array
    (
        [id] => 103
        [name] => 田中 一郎
        [email] => [email protected]
        [age] => 35
    )

)
*/
“`

これは、特定のIDを持つユーザーの情報を素早く参照したい場合などに非常に便利な形式です。例えば、$usersById[102] とすれば、ID 102 のユーザー情報(元の配列の要素)全体に直接アクセスできます。

foreach で同様の処理を行う場合は以下のようになります。

php
$usersById_manual = [];
foreach ($users as $user) {
if (isset($user['id'])) {
$usersById_manual[$user['id']] = $user;
}
}
print_r($usersById_manual); // array_columnと同じ結果が得られる

やはり array_column の方が簡潔です。

まとめ:array_column の引数の組み合わせ

array_column($array, $column_key, $index_key) の引数の組み合わせによる挙動をまとめると以下のようになります。

  • $column_key 指定, $index_key なし (null): 指定した列の値のリスト(数値添字配列)
  • $column_key 指定, $index_key 指定: 指定した列の値を要素とし、指定した別の列の値をキーとする連想配列
  • $column_keynull, $index_key 指定: 各行の配列全体を要素とし、指定した列の値をキーとする連想配列
  • $column_keynull, $index_key なし (null): 各行の配列全体を要素とするリスト(数値添字配列)。これは元の $array の要素の並びは保持されますが、キーは0から振り直されます。これは array_values($array) とは少し異なる場合があります(array_valuesは元のキーを捨てて値をリスト化する)。

これらの組み合わせを理解することで、array_column を様々なシーンで活用できるようになります。

4. キーが存在しない場合の挙動

array_column の重要な挙動の一つとして、入力配列 $array の各要素(各行)に、指定された $column_key または $index_key が存在しない場合、エラーや警告が発生しない点が挙げられます。

  • $column_key が存在しない場合: その行からは何も抽出されず、結果配列には含まれません。
  • $index_key が存在しない場合: その行は結果配列のキーとして値を設定できないため、結果配列には含まれません(ただし、$column_keynull の場合は少し複雑で、PHPのバージョンによって挙動が異なる可能性もありますが、基本的には $index_key が無い行はスキップされると理解しておくと良いでしょう)。
  • $column_key$index_key の両方が存在しない場合: その行は完全にスキップされます。

例を見てみましょう。

“`php
$data = [
[‘id’ => 101, ‘name’ => ‘山田’],
[‘id’ => 102, ‘name’ => ‘佐藤’, ‘email’ => ‘[email protected]’], // email キーがある
[‘id’ => 103, ‘age’ => 30], // name キーがない
[‘id’ => 104, ‘name’ => ‘田中’, ‘email’ => ‘[email protected]’],
[‘name’ => ‘鈴木’, ‘email’ => ‘[email protected]’], // id キーがない
];

// ‘name’ 列を抽出
$names = array_column($data, ‘name’);
print_r($names);
/
出力:
Array
(
[0] => 山田
[1] => 佐藤
[2] => 田中
[3] => 鈴木
)
// ID 103 の要素は ‘name’ キーがなかったため結果に含まれない
// ID 105 の要素は ‘id’ キーがなかったため結果に含まれない(ただしこの指定だと name は含まれる)
/

// ‘email’ 列を抽出
$emails = array_column($data, ‘email’);
print_r($emails);
/
出力:
Array
(
[0] => [email protected]
[1] => [email protected]
[2] => [email protected]
)
// ID 101, 103 の要素は ‘email’ キーがなかったため結果に含まれない
/

// ‘name’ 列を抽出し、キーに ‘id’ 列を使用
$idToName = array_column($data, ‘name’, ‘id’);
print_r($idToName);
/
出力:
Array
(
[101] => 山田
[102] => 佐藤
[104] => 田中
)
// ID 103 の要素は ‘name’ キーがなかったため含まれない
// ID 105 の要素は ‘id’ キーがなかったため含まれない
/

// 各行を抽出し、キーに ‘id’ 列を使用
$dataById = array_column($data, null, ‘id’);
print_r($dataById);
/*
出力:
Array
(
[101] => Array
(
[id] => 101
[name] => 山田
)

[102] => Array
    (
        [id] => 102
        [name] => 佐藤
        [email] => [email protected]
    )

[103] => Array // <-- id キーが存在するため含まれる
    (
        [id] => 103
        [age] => 30
    )

[104] => Array
    (
        [id] => 104
        [name] => 田中
        [email] => [email protected]
    )

)
// ID 105 の要素は ‘id’ キーがなかったため含まれない
*/
“`

この挙動は、入力データの一部に欠損がある場合でも、エラーで処理が中断することなく続行できるという利点があります。しかし、期待したデータが結果配列に含まれない可能性があるという点には注意が必要です。結果配列の要素数が元の配列の要素数より少なくなる可能性があることを理解しておく必要があります。

もし、キーが存在しない場合にデフォルト値を設定したい、あるいはエラーとしたい場合は、array_column 単体では難しく、前処理や後処理が必要になります。

5. パフォーマンスと内部実装

array_column が PHP 5.5.0 で導入された理由の一つに、パフォーマンスの向上が挙げられます。この関数は内部的にC言語で実装されており、PHPスクリプト内で foreach ループを使って同じ処理を行うよりも高速に動作することが期待できます。

特に、要素数が非常に多い配列に対して特定の列を抽出する場合、C言語レベルでの処理はPHPのスクリプトエンジンのオーバーヘッドを回避できるため、処理速度の面で有利に働きます。

メモリ使用量については、array_column は元の配列の各要素から指定された値を取り出し、新しい配列を構築します。これは元の配列とは別に新しい配列がメモリ上に作成されることを意味します。したがって、入力配列が非常に大きく、抽出する列の値もそれぞれが大きい(例えば長い文字列や大きなオブジェクト)場合、それなりのメモリを消費する可能性があります。しかし、手動でループを使って新しい配列を作成する場合でも同様にメモリを消費するため、この点は array_column 特有の大きな問題というよりは、大規模な配列処理全般に言えることです。

結論として、多次元配列から特定の列を抽出するというタスクにおいては、array_column は可読性の高さだけでなく、パフォーマンスの面でも推奨される方法です。

6. ユースケースと応用例

array_column は様々な開発シーンで活躍します。具体的なユースケースと応用例を見ていきましょう。

6.1. データベースからの結果セット処理

Webアプリケーション開発において、データベースからデータを取得することは非常に一般的です。多くのデータベースライブラリやORM(Object-Relational Mapper)は、クエリ結果を多次元配列(多くの場合、連想配列の配列)として返します。array_column は、この結果セットから必要な情報だけを取り出すのに最適です。

“`php
// データベースから取得した結果セットのイメージ
$users = [
[‘user_id’ => 101, ‘username’ => ‘taro’, ‘last_login’ => ‘2023-10-26 10:00:00’],
[‘user_id’ => 102, ‘username’ => ‘hanako’, ‘last_login’ => ‘2023-10-26 11:30:00’],
[‘user_id’ => 103, ‘username’ => ‘ichiro’, ‘last_login’ => ‘2023-10-25 15:00:00’],
];

// すべてのユーザーIDのリストを取得
$userIds = array_column($users, ‘user_id’); // [101, 102, 103]

// ユーザーIDをキーとしてユーザー名を値とする連想配列を取得
$userIdToUsername = array_column($users, ‘username’, ‘user_id’); // [101 => ‘taro’, 102 => ‘hanako’, 103 => ‘ichiro’]

// ユーザーIDをキーとして、各ユーザーのデータを取得
$usersDataById = array_column($users, null, ‘user_id’);
/
[
101 => [‘user_id’ => 101, ‘username’ => ‘taro’, ‘last_login’ => ‘2023-10-26 10:00:00’],
102 => [‘user_id’ => 102, ‘username’ => ‘hanako’, ‘last_login’ => ‘2023-10-26 11:30:00’],
103 => [‘user_id’ => 103, ‘username’ => ‘ichiro’, ‘last_login’ => ‘2023-10-25 15:00:00’],
]
/
“`

ORMを使用している場合でも、結果が配列形式で得られるなら array_column は有効です。例えば、LaravelのEloquentなどでコレクションとして結果が得られた場合、->toArray() メソッドなどで配列に変換してから array_column を適用できます。

6.2. CSVやAPIレスポンスの処理

CSVファイルをパースして得られた配列や、外部APIからJSON形式で取得し json_decode でPHPの配列に変換したデータも、多くの場合多次元配列の形式になります。これらのデータから特定の項目だけを抽出したい場合に array_column が役立ちます。

“`php
// CSVファイルをパースした配列のイメージ
$csvData = [
[‘商品ID’, ‘商品名’, ‘価格’, ‘在庫数’],
[‘A001’, ‘ノートPC’, ‘120000’, ’10’],
[‘A002’, ‘モニター’, ‘35000’, ‘5’],
[‘A003’, ‘キーボード’, ‘8000’, ’20’],
];

// ヘッダー行を除外し、数値添字配列であることを前提とする
$products = array_slice($csvData, 1);

// 商品名だけを抽出 (インデックス 1 の列)
$productNames = array_column($products, 1); // [‘ノートPC’, ‘モニター’, ‘キーボード’]

// 商品IDをキーとして価格を値とする連想配列を作成 (インデックス 0 をキー, インデックス 2 を値)
$productIdToPrice = array_column($products, 2, 0); // [‘A001’ => ‘120000’, ‘A002’ => ‘35000’, ‘A003’ => ‘8000’]
``
(注意:CSVのパース結果は通常文字列なので、必要に応じて数値変換などが必要になりますが、ここでは
array_column` の使い方に焦点を当てています。)

6.3. フォーム部品(ドロップダウンリストなど)のデータ準備

HTMLの <select> 要素など、フォーム部品の選択肢を動的に生成する場合、value 属性に設定する値と、ユーザーに見せる表示テキストのペアが必要です。多次元配列で選択肢データを持っている場合、array_column を使って効率的に value => label の形式の連想配列を作成できます。

“`php
$countries = [
[‘code’ => ‘jp’, ‘name’ => ‘日本’],
[‘code’ => ‘us’, ‘name’ => ‘アメリカ合衆国’],
[‘code’ => ‘cn’, ‘name’ => ‘中華人民共和国’],
];

// コードをvalue、国名をlabelとしてドロップダウンの選択肢データを準備
$countryOptions = array_column($countries, ‘name’, ‘code’);
/
[
‘jp’ => ‘日本’,
‘us’ => ‘アメリカ合衆国’,
‘cn’ => ‘中華人民共和国’,
]
/

// この結果を使ってHTMLを生成
//
“`

6.4. 他の配列関数との組み合わせ

array_column は、他の様々なPHP配列関数と組み合わせて使うことで、より複雑なデータ処理を簡潔に実現できます。

6.4.1. 重複した値を取り除く (array_unique)

特定の列の値のリストを取得した後、その中の重複を取り除きたい場合があります。

“`php
$products = [
[‘id’ => 1, ‘category’ => ‘Electronics’, ‘name’ => ‘Laptop’],
[‘id’ => 2, ‘category’ => ‘Books’, ‘name’ => ‘Novel’],
[‘id’ => 3, ‘category’ => ‘Electronics’, ‘name’ => ‘Monitor’],
[‘id’ => 4, ‘category’ => ‘Books’, ‘name’ => ‘Textbook’],
[‘id’ => 5, ‘category’ => ‘Electronics’, ‘name’ => ‘Mouse’],
];

// 製品カテゴリのリストを取得し、重複を排除
$categories = array_column($products, ‘category’); // [‘Electronics’, ‘Books’, ‘Electronics’, ‘Books’, ‘Electronics’]
$uniqueCategories = array_unique($categories); // [‘Electronics’, ‘Books’]

print_r($uniqueCategories);
/
出力:
Array
(
[0] => Electronics
[1] => Books
)
// 元の配列のキーが保持されることに注意
/

// キーを振り直したい場合は array_values をさらに適用
$uniqueCategories = array_values(array_unique(array_column($products, ‘category’))); // [‘Electronics’, ‘Books’]
print_r($uniqueCategories);
/
出力:
Array
(
[0] => Electronics
[1] => Books
)
/
“`

6.4.2. 条件に合う行の特定の列を抽出 (array_filter)

特定の条件を満たす行だけを抽出し、そこからさらに列を抽出したい場合、array_filterarray_column を組み合わせます。

“`php
$orders = [
[‘order_id’ => 1001, ‘amount’ => 1500, ‘status’ => ‘completed’],
[‘order_id’ => 1002, ‘amount’ => 800, ‘status’ => ‘pending’],
[‘order_id’ => 1003, ‘amount’ => 2500, ‘status’ => ‘completed’],
[‘order_id’ => 1004, ‘amount’ => 1200, ‘status’ => ‘cancelled’],
[‘order_id’ => 1005, ‘amount’ => 3000, ‘status’ => ‘completed’],
];

// ステータスが ‘completed’ の注文だけをフィルタリング
$completedOrders = array_filter($orders, fn($order) => $order[‘status’] === ‘completed’);

// 完了した注文の注文IDだけを抽出
$completedOrderIds = array_column($completedOrders, ‘order_id’); // [1001, 1003, 1005]

print_r($completedOrderIds);
/
出力:
Array
(
[0] => 1001
[1] => 1003
[2] => 1005
)
/

// ステータスが ‘completed’ の注文の注文IDをキーとし、金額を値とする連想配列を取得
$completedOrderIdToAmount = array_column($completedOrders, ‘amount’, ‘order_id’); // [1001 => 1500, 1003 => 2500, 1005 => 3000]
print_r($completedOrderIdToAmount);
/
出力:
Array
(
[1001] => 1500
[1003] => 2500
[1005] => 3000
)
/
“`

array_filter の結果は元の配列のキーを保持するため、その後の array_column の結果も、元の配列の要素順序やキー($index_key を指定した場合)を反映したものになります。

6.4.3. 特定の列の合計を計算 (array_sum)

数値の列を抽出した後、その合計値を計算したい場合に array_sum を組み合わせます。

“`php
$items = [
[‘name’ => ‘A’, ‘price’ => 100, ‘quantity’ => 2],
[‘name’ => ‘B’, ‘price’ => 250, ‘quantity’ => 1],
[‘name’ => ‘C’, ‘price’ => 50, ‘quantity’ => 5],
];

// 価格の列を抽出
$prices = array_column($items, ‘price’); // [100, 250, 50]

// 合計価格を計算
$totalPrice = array_sum($prices); // 400

print_r($totalPrice); // 出力: 400
“`

これは非常にシンプルですが、よくあるタスクです。array_column を使うことで、中間配列を明示的に作成するコードが非常に短くなります。

アイテムごとの小計(価格 * 数量)の合計を計算したい場合は、array_map などで計算列を一時的に作成してから array_column + array_sum を使うことも考えられますが、このケースでは array_reduce を使う方がより直接的で効率的かもしれません。ただし、array_column を使って「数量」列や「価格」列を別々に取得し、その後の処理で合計を計算するという流れも十分に考えられます。

6.4.4. キーと値を入れ替える (array_flip)

array_column でキーと値の連想配列を作成した後、さらにキーと値を入れ替えたい場合があります(ただし、値に重複がない場合に限ります)。

“`php
$users = [
[‘id’ => 101, ‘name’ => ‘山田 太郎’],
[‘id’ => 102, ‘name’ => ‘佐藤 花子’],
];

// IDをキー、名前を値とする
$idToName = array_column($users, ‘name’, ‘id’); // [101 => ‘山田 太郎’, 102 => ‘佐藤 花子’]

// 名前をキー、IDを値とする (名前がユニークである前提)
$nameToId = array_flip($idToName); // [‘山田 太郎’ => 101, ‘佐藤 花子’ => 102]

print_r($nameToId);
/
出力:
Array
(
[山田 太郎] => 101
[佐藤 花子] => 102
)
/
“`

このように、array_column は他の多くの配列関数と連携して、データ処理のパイプラインの一部として機能します。

6.5. より複雑なデータ構造への対応(制限と回避策)

array_column は、入力配列の各要素が「フラットな」配列(多次元ではない、単なる連想配列や数値添字配列)であることを想定しています。もし入力配列がさらに深くネストされた構造になっている場合、array_column は直接は使えません。

例えば、以下のようなデータ構造から部署名を取り出したい場合を考えます。

“`php
$companies = [
[
‘company_name’ => ‘A社’,
‘departments’ => [
[‘dept_id’ => ‘D01’, ‘dept_name’ => ‘開発部’],
[‘dept_id’ => ‘D02’, ‘dept_name’ => ‘営業部’],
]
],
[
‘company_name’ => ‘B社’,
‘departments’ => [
[‘dept_id’ => ‘D03’, ‘dept_name’ => ‘人事部’],
]
],
];

// 各会社の ‘departments’ 配列から部署名を抽出したい
// array_column($companies, ‘departments’) は departments 配列自体を抽出するだけ
// array_column($companies, ‘dept_name’) は動作しない(departments の中の dept_name にアクセスできない)
“`

このような場合は、array_mapforeach を使って一段階ずつ処理を進める必要があります。

“`php
// array_map を使って各要素から ‘departments’ 配列を取り出す
$allDepartments = array_column($companies, ‘departments’);
/
結果:
[
[
[‘dept_id’ => ‘D01’, ‘dept_name’ => ‘開発部’],
[‘dept_id’ => ‘D02’, ‘dept_name’ => ‘営業部’],
],
[
[‘dept_id’ => ‘D03’, ‘dept_name’ => ‘人事部’],
],
]
/

// 取り出した各部署配列を平坦化する(例: array_merge, array_reduceなどを使用)
$flattenedDepartments = array_merge(…$allDepartments); // PHP 7.4+ のスプレッド演算子を使用
/
結果:
[
[‘dept_id’ => ‘D01’, ‘dept_name’ => ‘開発部’],
[‘dept_id’ => ‘D02’, ‘dept_name’ => ‘営業部’],
[‘dept_id’ => ‘D03’, ‘dept_name’ => ‘人事部’],
]
/

// 平坦化された配列から部署名を抽出
$departmentNames = array_column($flattenedDepartments, ‘dept_name’); // [‘開発部’, ‘営業部’, ‘人事部’]

print_r($departmentNames);
/
出力:
Array
(
[0] => 開発部
[1] => 営業部
[2] => 人事部
)
/
“`

ネストが深くなるほど、このように複数のステップや他の関数との組み合わせが必要になります。array_column はあくまで入力配列の「直下の要素」から指定されたキーの値を抽出する関数であると理解しておくことが重要です。

7. array_column を使用する際の注意点

array_column は非常に便利ですが、使用する際にいくつか注意しておきたい点があります。

7.1. 入力配列の構造の均一性

array_column は、入力配列 $array の各要素が、指定された $column_key$index_key を持つことを前提としています。前述のように、これらのキーが存在しない要素は単にスキップされます。これによりエラーは発生しませんが、期待するすべてのデータが得られない可能性があります。

もし、入力配列の構造が一定でない(例えば、一部の要素が連想配列ではなく数値添字配列だったり、キーが存在しない要素が頻繁に混ざっていたり)場合、array_column だけでは不十分で、前処理として foreacharray_map などを使ってデータの整形やバリデーションを行う必要があるかもしれません。

7.2. $index_key で指定したキーの値に重複がある場合

$index_key を指定して結果配列のキーを設定する場合、$index_key で指定した列の値が重複していると、後から現れた値で上書きされます。PHPの配列のキーはユニークでなければならないため、同じキーが複数回現れた場合、最後の値がそのキーに対応付けられます。

“`php
$dataWithDuplicateKeys = [
[‘id’ => 1, ‘value’ => ‘Apple’],
[‘id’ => 2, ‘value’ => ‘Banana’],
[‘id’ => 1, ‘value’ => ‘Cherry’], // ID 1 が重複
];

// ‘value’ を抽出し、キーに ‘id’ を使用
$result = array_column($dataWithDuplicateKeys, ‘value’, ‘id’);

print_r($result);
/
出力:
Array
(
[1] => Cherry // ID 1 の ‘Apple’ は ‘Cherry’ で上書きされた
[2] => Banana
)
/
“`

$index_key に指定する列は、その値がユニークであることが期待されるカラム(例えばデータベースの主キーなど)を選ぶのが一般的です。もし重複が想定されるデータで $index_key を使用したい場合は、この上書きの挙動を理解しておくか、あるいは array_column の代わりに手動でループ処理を行い、重複するキーを持つ要素をどのように扱うか(例えば、値を配列に追加するなど)を制御する必要があります。

7.3. PHPのバージョン要件

array_column 関数は PHP 5.5.0 で導入されました。もしあなたが PHP 5.4 以前の古いバージョンを使用している場合、この関数は利用できません。その場合は、記事冒頭で示したような foreach ループなどの代替手段を使用する必要があります。

互換性を保つ必要があるプロジェクトで array_column を安全に使用するには、PHPのバージョンが 5.5.0 以降であることを確認してください。

7.4. $column_key$index_key に空文字列や数値0を指定する場合

$column_key$index_key に空文字列 ('') や数値の 0 を指定することも可能です。これは、入力配列の要素がキーとして空文字列や数値 0 を持つ場合に使用します。

“`php
$mixedKeysData = [
[” => ‘空文字列キーの値’, ‘0’ => ‘文字列”0″キーの値’, 0 => ‘数値0キーの値’, ‘name’ => ‘データA’],
[” => ‘別の空文字列値’, 0 => ‘別の数値0値’, ‘name’ => ‘データB’],
// …
];

// 空文字列キーの列を抽出
$emptyStringValues = array_column($mixedKeysData, ”);

// 文字列 “0” キーの列を抽出
$stringZeroValues = array_column($mixedKeysData, ‘0’);

// 数値 0 キーの列を抽出
$numericZeroValues = array_column($mixedKeysData, 0);

print_r($emptyStringValues);
/
出力例:
Array
(
[0] => 空文字列キーの値
[1] => 別の空文字列値
)
/

print_r($stringZeroValues);
/
出力例:
Array
(
[0] => 文字列”0″キーの値
// 2番目の要素には “0” キーが存在しないため含まれない
)
/

print_r($numericZeroValues);
/
出力例:
Array
(
[0] => 数値0キーの値
[1] => 別の数値0値
)
/
``
このように、キーとして空文字列や数値
0を正確に指定することで、対応する列を抽出できます。ただし、配列のキーとして文字列の“0”と数値の0はPHP内部で区別される場合とされない場合があるため、扱う際は注意が必要です。array_columnでは、指定された$column_key$index_keyの型と入力配列の要素のキーの型が厳密に一致しない場合でも、PHPの通常の型変換ルールに基づいてキーを検索しようとします。例えば、文字列キーの‘0’と数値キーの0が混在する配列に対して、array_column($array, 0)と指定した場合、通常は数値キーの0が優先してマッチしますが、入力配列の内部表現によっては挙動が異なる可能性もゼロではありません。できるだけ、入力配列のキーの型に合わせて$column_key$index_key` を指定するのが安全です。

8. array_column の代替手段(PHP 5.4 以前向け)

もし PHP 5.5.0 より前のバージョンを使用している場合、array_column は利用できません。この場合、同等の機能を実現するためには手動でループ処理を行う必要があります。

最も一般的な代替手段は、記事冒頭でも触れた foreach ループを使った方法です。

代替手段1: foreach ループ

``php
//
$column_key` のみ指定の代替
function array_column_manual(array $array, int|string $column_key): array
{
$result = [];
foreach ($array as $row) {
// 要素が配列であり、かつ指定キーが存在する場合のみ追加
if (is_array($row) && array_key_exists($column_key, $row)) {
$result[] = $row[$column_key];
}
}
return $result;
}

// $column_key$index_key を指定の代替
function array_column_manual_indexed(array $array, int|string $column_key, int|string $index_key): array
{
$result = [];
foreach ($array as $row) {
// 要素が配列であり、かつ両方のキーが存在する場合のみ追加
if (is_array($row) && array_key_exists($column_key, $row) && array_key_exists($index_key, $row)) {
$result[$row[$index_key]] = $row[$column_key];
}
}
return $result;
}

// $column_key に null、$index_key を指定の代替
function array_column_manual_indexed_row(array $array, int|string $index_key): array
{
$result = [];
foreach ($array as $row) {
// 要素が配列であり、かつ index_key が存在する場合のみ追加
if (is_array($row) && array_key_exists($index_key, $row)) {
$result[$row[$index_key]] = $row;
}
}
return $result;
}
“`

これらの手動実装は array_column と全く同じ挙動(キーが存在しない行をスキップするなど)を再現しようとしたものです。特に $column_keynull の場合の array_column の挙動(各行全体を値とする)は、手動ループでも比較的簡単に再現できます。

PHP 5.5.0 以降を使用できる環境であれば、これらの手動実装を使う理由はありません。array_column の方が簡潔で、かつパフォーマンスが最適化されているからです。しかし、レガシーな環境に対応する必要がある場合は、このような実装を参考にしてください。

代替手段2: array_map の応用

array_map を使って同等の処理を実現することも可能ですが、array_column の柔軟性(特に $index_key の指定や、キーが存在しない場合のスキップ挙動)を完全に再現しようとすると、無名関数の中身が複雑になる傾向があります。

例えば、$column_key のみ指定のケースは比較的簡単に array_map で実現できます。

php
// `$column_key` のみ指定の array_map 版
$emails_map = array_map(fn($row) => $row['email'] ?? null, $users);
// ただし、上記だとキーが存在しない場合に null が入る。
// array_column のようにスキップしたい場合は、後で array_filter で null を取り除くなどの追加処理が必要。
$emails_map_filtered = array_values(array_filter($emails_map, fn($value) => $value !== null));
// array_column と完全に同じ挙動にならない可能性がある(キーのスキップではなく値が null になるため)

$index_key を指定する場合や、$column_keynull の場合を array_map だけで実現するのはさらに複雑になり、手動ループの方が分かりやすい場合が多いでしょう。したがって、PHP 5.4 以前での代替としては、foreach ループが最も一般的で分かりやすい選択肢と言えます。

9. まとめ

PHPの array_column 関数は、多次元配列から特定の「列」の値や、その値をキーとした新しい配列を効率的に抽出するための強力なツールです。

  • 基本的な使い方として、array_column($array, $column_key) で特定の列の値のリストを取得できます。
  • より進んだ使い方として、array_column($array, $column_key, $index_key) で指定した列の値をキーとした連想配列を作成できます。また、$column_keynull を指定することで、各行全体を値として抽出し、特定の列をキーとする連想配列を作成することも可能です。
  • 指定したキーが存在しない行は、エラーや警告なく結果配列からスキップされます。この挙動は、データに欠損がある場合でも処理を継続できる反面、結果配列の要素数が減る可能性があることに注意が必要です。
  • PHPの内部(C言語)で実装されており、同等の処理を手動でループするよりも高速に動作することが期待できます。
  • データベース結果、CSV/APIデータ処理、フォーム部品データの準備など、多様なユースケースで活躍します。
  • array_unique, array_filter, array_sum といった他の配列関数と組み合わせて、より複雑なデータ処理を簡潔に記述できます。
  • PHP 5.5.0 以降で利用可能です。古いバージョンでは手動ループなどで代替する必要があります。
  • $index_key に指定した列の値に重複がある場合、後から現れた値で上書きされる点に注意が必要です。

array_column を活用することで、多次元配列からのデータ抽出処理をより簡潔に、効率的に、そして意図が明確なコードで記述できるようになります。日常的なPHP開発において、多次元配列を扱う機会は非常に多いため、この関数を使いこなすことは、あなたのコード品質と開発効率を大きく向上させるでしょう。ぜひ積極的に活用してください。


コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

上部へスクロール