Laravel で chunk を使いながらトータル件数を計算
はじめに
Laravel で chunk
もしくは chunkById
を使いながらトータル件数を計算する方法。
TL;DR
目次
環境・条件
1 | $ cat /etc/os-release |
詳細
前置き: どのような状況を想定しているか
Laravel で大量のデータを処理する際、get()
や all()
を使うと大量のメモリが必要となるため、一定件数ずつ処理する際には chunk
や chunkById
を使うことになる。
例えば CSV へのデータ書き出し時に、データ件数(1〜n)も合わせて出力したいようなケースを想定。
以下はダメな例なので読み飛ばしても OK
ダメな例1
これだと foreach
ごとに $i
が初期化されるので 1
, 2
, … 100
の後にまた 1
, 2
, … と繰り返してしまう。
1 | User::chunk(100, function ($users) use ($file) { |
ダメな例2
例1の反省を活かして chunk
の外側にカウンタを定義。
一見問題なさそうにも見えるが、これも例1と同じ結果になってしまう。
※PHP に詳しくないので間違っているかもしれないが、おそらくチャンク(100件)ごとにコールバック(function ...
)の部分が実行される(毎回 use ($i)
で値渡しとなり 1
が入る)のだと思う。
1 | $i = 1; |
対応方法
参考: php - How can I get the return value of a Laravel chunk? - Stack Overflow
値渡しではなくリファレンス渡し(参照渡し)すれば OK
1 | $i = 1; |
参照するだけなら chunk
で良いが、更新するなら chunkById
を使った方が良いので注意。
1 | User::chunkById(100, function ($users) { |
まとめ
その他・メモ
chunk
以外にも cursor
ってメソッドもあるので、覚えておくと良い。以下の記事が参考になる。
参考文献
- php - How can I get the return value of a Laravel chunk? - Stack Overflow
- PHP: リファレンス渡し - Manual
- Eloquent:利用の開始 5.7 Laravel
- データベース:クエリビルダ 5.7 Laravel
- Laravel(Eloquent): chunk() vs cursor() - Qiita
- Laravelのcursorとchunkの違いとバッファクエリの対処法 - honeplusのメモ帳
関連記事
- Laravel で現在の URL 取得方法まとめ
- Laravel で Cookie を使う(参照/設定/削除)
- Laravel で PDF ファイルをブラウザで開く
- Laravel で withCount と having を使って絞り込み
- Laravel で「開始日時 < 終了日時」であることをバリデーションする
- Laravel で生 SQL を実行
- JavaScript で URL のクエリパラメータを操作する方法
- jQuery Select2 で、初期値の設定と選択状態のクリア