array_column($rows, $column)は、行のリストのすべての行から$columnの値を返します。レコードの表を1つのフィールドの平らな配列に変えるもので、implode、in_array、array_sum、array_searchの前に必要になる処理です。
行の出どころは何でもかまいません。デコードしたJSONのレスポンス、CSVファイル、連想配列の配列を返したデータベースのクエリなどです。
インデックスキーでキーと値のペアを作る
3つ目の引数には、その値が各結果のキーになるフィールドを指定します。array_column($users, 'name', 'id')は、たとえば<select>のリスト用に、IDから名前を引く表を作る定番の方法です。
2つの行が同じインデックスの値を持つ場合は、あとの行が前の行を上書きします。
nullで行全体をIDで索引付けする
列にnullを渡すと、各行全体をインデックスのフィールドでキーを付け直して保ちます。IDで行を探すのが、ループではなく直接のキーアクセスになります。
索引を一度作れば、それ以降の検索は一瞬で終わります。ループの中で多くのIDを探すときに効いてきます。
array_columnとarray_searchで行を見つける
ある値を持つ行がどれかを見つけるには、列を検索して返ってきた位置を使います。最初の行で一致すると0が返るので、結果は!== falseで確認します。
これは$usersのキーが0, 1, 2であることを前提にしています。array_columnはリストを返すからです。配列が絞り込まれて欠番があるなら、先にarray_values($users)を呼びます。falseと0の落とし穴についてはarray_searchのページで詳しく扱っています。
列を合計する、数える、平均する
array_columnは数学のヘルパー関数と相性がよく、フィールドを取り出してから合計できます。
数量かける価格のように複数のフィールドから計算する値には、最後の行のようにarray_mapを使います。
オブジェクトに対するarray_column
オブジェクトのリストでは、array_columnはpublicなプロパティを読みます。privateとprotectedのプロパティは見えません。
2つ目の呼び出しは空の配列を返します。passwordはprivateなので、すべてのオブジェクトが飛ばされます。
フィールドのない行は飛ばされる
array_columnは、フィールドを持たない行のために代わりの値を埋めたりしません。結果は入力より短くなることがあり、その場合、位置は行と対応しなくなります。
最初の結果には電話番号が2つあり、Bobが持っていなかったことはわかりません。名前をインデックスキーにすれば、どの番号が誰のものかがわかります。フィールドを持たない行があるかもしれないときは、こちらのほうが安全な形です。
よくある質問
PHPのarray_columnは何をしますか?
行(配列やオブジェクト)のリストを受け取り、各行から1つのフィールドの値を返します:array_column($users, 'email')はメールアドレスの平らな配列を返します。そのフィールドを持たない行は飛ばされます。
行からキーと値の配列を作るには?
3つ目の引数にキーにするフィールドを渡します:array_column($users, 'name', 'id')は[id => name, ...]を返します。2つ目の引数にnullを渡す(array_column($users, null, 'id'))と、行全体をIDで索引付けして保ちます。
行にフィールドがないとき、array_columnはどうなりますか?
その行を飛ばすので、array_column($people, 'phone')は行の数より少ない値を返すことがあり、位置が対応しなくなります。インデックスキーを加えれば(array_column($people, 'phone', 'name'))、各値がどの行から来たかがわかります。
array_columnはオブジェクトにも使えますか?
使えます。オブジェクトの配列ではpublicなプロパティを読み、クラスが__issetを定義していれば__getで利用できるプロパティも読みます。privateとprotectedのプロパティは飛ばされます。