array_chunkで配列をきれいに分割する
array_chunk とは、配列を指定した個数ずつのまとまりに分割し、二次元配列として返す関数です。バッチ処理やページングの下ごしらえで出番の多い関数です。
指定した個数ずつに割る
配列を「n個ずつのまとまり」に分けたいとき、自前でカウンタを回すより array_chunk が素直です。第2引数に一塊のサイズを渡すと、その大きさで切り分けた二次元配列が返ってきます。最後の塊は端数のまま残ります。
$items = range(1, 7);
$chunks = array_chunk($items, 3);
// [[1, 2, 3], [4, 5, 6], [7]]
foreach ($chunks as $group) {
echo implode(',', $group) . "\n";
}
7要素を3ずつに割ると最後が1個だけになりますが、これはこれで自然な挙動ですね。均等割りを前提にコードを書くと端数で崩れるので、そこだけ気をつけたいところです。
第3引数でキーを保つ
デフォルトでは各塊のキーが0から振り直されます。元のインデックスを残したいときは第3引数 preserve_keys を true にします。連想配列を扱うときはこれがないと元のキーが消えるので、実務では地味に重要だと思います。
$data = ['a' => 1, 'b' => 2, 'c' => 3];
var_dump(array_chunk($data, 2, true));
// [['a' => 1, 'b' => 2], ['c' => 3]]
ページングとバッチ処理での定番
私がよく使うのは、大量レコードをまとめて処理するときの分割です。数万件を一気に INSERT すると重いので、chunk で小分けにしてループする、という形にすると DB もメモリも楽になります。ページング表示の下ごしらえにも使えます。
$records = fetchAllRecords(); // 大量の配列だとする
foreach (array_chunk($records, 500) as $batch) {
// 500件ずつまとめて処理
bulkInsert($batch);
}
// ページング: 1ページ10件として3ページ目を取る
$pages = array_chunk($allRows, 10);
$page3 = $pages[2] ?? [];
ただし array_chunk は全件をいったんメモリに載せる前提なので、本当に巨大なデータはジェネレータやカーソルで流したほうが良い場面もあります。あくまで「手元にある配列を割る」道具、という位置づけですね。
まとめ
array_chunk はバッチ処理とページングで出番の多い関数で、preserve_keys の有無で連想配列の扱いが変わる点だけ押さえておけば安心です。端数の塊が出ること、巨大データではメモリに気を配ること、この2つを意識しておくと実務でつまずきにくいと思います。
よくある質問
Q. 割り切れないとどうなりますか?
A. 最後の塊が端数のまま残ります。均等割りを前提にコードを書くと崩れるので、端数が出る想定で処理を書くと安全です。
Q. 連想配列のキーを残したいです。
A. 第3引数 preserve_keys を true にします。既定ではキーが0から振り直されるので、連想配列を扱うときはこれが要ります。
Q. 巨大なデータでも使えますか?
A. array_chunk は全件をいったんメモリに載せる前提です。本当に巨大なデータはジェネレータやカーソルで流すほうが向いています。