質問: お世話になっております。 当方Laravel5.5にてWebSiteを構築しております、 環境はmac OS Mojave10.14.2 ブラウザはGoogle Chrome バージョン: 71.0.3578.98になります。 ### やりたいこと・問題 * 下記を参考にデータベースから取得した値をcsvにダウンロードする方法を実装していますが、 https://www.grooving-earth.com/csv-download-with-laravel/ csvの出力値が、ヘッダを除いて空になってしまいます。 * 参考記事からデータベースの名称などを書き換えてソースそのままでも動く のですが、下記の通り、Eloquentから直接chunkするのではなく、 取得した値の一部を書き換えた変数($data)に対してchunkしている 部分が異なっています。 * 記事と異なる部分だけ書き換えて、 参考ソースと同じく「データベース名::where(~~)->chunk」とすると うまくいくので、 下記の部分が原因であることは明確です。 * $dataの中身は、 「データベース名::where(~~)->chunk」で取得した時と 項目数(attributesのarrayの中身の数)が異なるだけで、 型は同じCollectionです。 --3/28 22:37追記修正start-- * chunkだけ単体で$dataに対して実行しても、 「データベース名::where(~~)->chunk」で取得した時と項目数以外の結果が 変わらない一方で、 foreach文のみ、つまり ``` foreach($data as $datum){fputcsv($stream,[$result->data_id,$result->data_category_name_full,$result->business_category,$result->data_company,$result->company_size,$result->data_group])} ``` ですと、正しいデータが出力されることを確認しました。 --3/28 22:37追記修正end-- 参考ソース ``` Sample::where('sample1', 'LIKE', '%'.$keyword.'%')->chunk( 1000, function($results) use ($stream) { foreach ($results as $result) { fputcsv($stream, [$result->id,$result->sample1,$result->sample2,$result->sample3,$result->created_at,$result->updated_at]); } }); ``` 下記は構築中のソースで、$dataはこのソースの前で データベースの検索、データ取得後、 idを名称に書き換えるなどの処理を入れています。 尚、中身だけ変えるようにしており、処理後もCollectionの型を維持しています。 ``` $data->chunk( 1000, function($results) use ($stream) { foreach ($results as $result) { fputcsv($stream, [$result->data_id,$result->data_category_name_full,$result->business_category,$result->data_company,$result->company_size,$result->data_group]); } }); ``` 宜しくお願い致します。
回答: `\Illuminate\Database\Eloquent\Builder`の`chunk`と`\Illuminate\Database\Eloquent\Collection`の`chunk`を混同していると思います。 `Sample::where('sample1', 'LIKE', '%'.$keyword.'%')->chunk( 1000, function($results) use ($stream) {`で使われている`chunk`は`\Illuminate\Database\Eloquent\Builder`の方で、Eloquent:利用の開始の「結果の分割」で説明されているものです。これは2引数で2つめの引数にはchunkにわけたコレクションを受け取るコールバックを指定して使います。 `$data->chunk( 1000, function($results) use ($stream) {`の方は$dataがコレクションということなので、これはベースコレクションから継承したchunkメソッドであり、「コレクション」の「chunk」で説明されているものになります。こちらは1引数で全く違うものです。前者のつもりでコールバックを渡していますが、PHPは余計なパラメータはエラーにならず単に無視するだけなのでなんの働きもしていません。こちら指定されたサイズに分割したコレクションのコレクションを返しますので、それに対してさらに処理を続ける必要があります。追記にあるようにforeachを使っても良いし、コレクションの`each`を併用する方法もあります。 ``` $data->chunk(1000)->each(function($results) use ($stream) { foreach ($results as $result) { fputcsv($stream, [$result->data_id,$result->data_category_name_full,$result->business_category,$result->data_company,$result->company_size,$result->data_group]); } }); ```