質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

3回答

683閲覧

PHPで巨大なCSVをデータベースからダウンロードさせたい

gesunokiwami

総合スコア17

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

phpMyAdmin

phpMyAdminはオープンソースで、PHPで書かれたウェブベースのMySQL管理ツールのことです。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

1クリップ

投稿2019/01/28 07:03

編集2019/01/28 08:24

phpで巨大なDBのデータをCSVで落としたいと思い、
以下のサイトを参考にしたのですが、実際に落としてきたCSVには何も保存されていませんでした。
https://qiita.com/39ff/items/54a14c84e90f4cab4e7b
下記の処理でおかしな点はありますか?

test.php

header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=export.csv"); try { $pdo = new PDO('mysql:dbname=test;host=IP;port=22;charset=utf8mb4', 'root', 'password', [ \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, \PDO::ATTR_EMULATE_PREPARES => true, \PDO::ATTR_TIMEOUT => 10, \PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false ]); $stmt = $pdo->prepare("SELECT * FROM `log` WHERE 1"); if ($stmt->execute()) { $stream = fopen('php://temp', 'wb'); stream_filter_prepend($stream, 'convert.iconv.utf-8/cp932'); fputcsv($stream, [ "ID", ],","); while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { fputcsv($stream, [ $row['id'], ],","); } fclose($stream); } }catch (\PDOException $e){ //..var_dump($e->getTraceAsString()); }

追記
皆さんのおかげでデバッグ方法がわかったのですが、以下のエラー?が出ました。
これはどのような意味でしょうか?

string(72) "#0 /var/www/html/~/test.php(85): PDOStatement->execute() #1 {main}"

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/01/28 07:06

質問は何でしょうか。 データ自体は質問者さんしか持っていませんし、どこまで処理が正常に進んでいるかは質問者さんが見るしかありません。まずは(できれば質問前に)デバッグしてみてください。
gesunokiwami

2019/01/28 07:16

すいません質問に関しては「test.phpの処理でおかしな点はありますか」になります。 どこまで処理が正常に進んでいるかのデバッグなども、どのようにしたらよいか分からなかったので質問をさせていただきました。
tabuu

2019/01/28 07:26

巨大なDBとあるのでメモリ不足かもしれません。 whereで数行取得するように調整して問題を切り分けてみてください。 whileの中でログを出力するなどでデバッグも可能です。
m.ts10806

2019/01/28 08:35

追記された内容はエラーではないですね。どこにどう書いたのでしょうか
gesunokiwami

2019/01/28 08:37

catchのコメントを解除したら表示されました。
m.ts10806

2019/01/28 08:50

エラーを確認したいのでしたらgetTraceよりも getErrorMessageの方がいいかもしれません。
gesunokiwami

2019/01/28 09:32

ちなみに、追記に書いた下記の部分は何を意味しているものなのでしょうか? string(72) "#0 /var/www/html/~/test.php(85): PDOStatement->execute() #1 {main}"
m.ts10806

2019/01/28 10:03

特に意味はないかと。エラーが出ている(キャッチした)箇所がトレースされたものと考えられます
mpyw

2019/01/28 20:06

getErrorMessage メソッドは存在しないので getMessage かあるいはそのままオブジェクトごとそのままダンプしたほうがいいですね
m.ts10806

2019/01/28 21:37

mpywさん フォローございます。 質問者さん 既に回答がついてますし、できればそちらそれぞれ参照してください
guest

回答3

0

凡ミス

$stream = fopen('php://temp', 'wb');

$stream = fopen('php://output', 'wb');

  • php://temp はテンポラリメモリ(書き込んだあと読み出さないなら何の意味もない)
  • php://output は mod_php や php-fpm におけるHTTPのボディパート出力(echo で出すのと同じ場所)

【追記】

これでお試しください↓

php

1<?php 2 3try { 4 5 $pdo = new PDO('mysql:dbname=test;host=IP;port=22;charset=utf8mb4', 6 'root', 7 'password', 8 [ 9 \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, 10 \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, 11 \PDO::ATTR_TIMEOUT => 10, 12 \PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false, 13 ] 14 ); 15 16 $stmt = $pdo->query("SELECT * FROM `log`"); 17 18} catch (\PDOException $e) { 19 20 // デバッグ用 21 header("Content-Type: text/plain; charset=UTF-8", true, 500); 22 exit($e->getMessage()); 23 24} 25 26// ヘッダ出力 27header("Content-Type: text/csv; charset=Windows-31J"); 28header("Content-Disposition: attachment; filename=export.tsv"); 29 30// ストリームの用意 31$stream = fopen('php://output', 'wb'); 32stream_filter_prepend($stream, 'convert.iconv.utf-8/cp932'); 33 34// 見出しを書き込む 35fputcsv($stream, ["ID"]); 36 37// 各行を書き込む 38foreach ($stmt as $row) { 39 fputcsv($stream, [$row['id']]); 40}

投稿2019/01/28 20:01

編集2019/01/28 20:34
mpyw

総合スコア5223

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mpyw

2019/01/28 20:05 編集

凡ミス入ってますがまだエラー原因ありそうですね。 string(72) "#0 /var/www/html/~/test.php(85): PDOStatement->execute() #1 {main}" ↑の部分だけ見ても不明なので var_dump($e->getTraceAsString()); ↓ var_dump($e); にしてください
guest

0

php

1<?php 2 3// デバッグ段階なのに、エラーを表示していないのはおかしい 4ini_set('display_errors', true); 5error_reporting(E_ALL); 6 7// デバッグしていておかしい時に header() を無効にしてみること。 8// エラーがブラウザ上に表示されなくなるため。 9// 問題がなくなればコメントを外す 10 11//header("Content-Type: application/octet-stream"); 12//header("Content-Disposition: attachment; filename=export.csv"); 13 14try { 15 16 // port が 22 ??? 17 // 22 は SSH のポートだぞ??? 普通は 3306じゃないの? 18 $pdo = new PDO('mysql:dbname=test;host=IP;port=22;charset=utf8mb4', 19 'root', 20 'password', 21 [ 22 \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION, 23 \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC, 24 \PDO::ATTR_EMULATE_PREPARES => true, 25 \PDO::ATTR_TIMEOUT => 10, 26 \PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => false 27 ]); 28 29 $stmt = $pdo->prepare("SELECT * FROM `log` WHERE 1"); 30 31 if ($stmt->execute()) { 32 $stream = fopen('php://temp', 'wb'); 33 stream_filter_prepend($stream, 'convert.iconv.utf-8/cp932'); 34 fputcsv($stream, [ 35 "ID", 36 ],","); 37 38 while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { 39 fputcsv($stream, [ 40 $row['id'], 41 ],","); 42 } 43 fclose($stream); 44 } 45} catch (\PDOException $e){ 46 // せっかくcatch しているのになぜコメントアウト??? 47 var_dump($e->getTraceAsString()); 48}

投稿2019/01/28 07:38

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2019/01/28 07:41

port気づかなかった・・・。 エラーOFFにしている人多いですよね。catchコメントアウトは私も気になったので突っ込んでます。
mpyw

2019/01/28 20:08

execute で例外飛んでるってことはポートだけが原因ではないはず…
guest

0

下記、ご確認ください。(順不同です。できるものから試してください)
※デバッグ方法込みです

  1. SQLを直にDBに対して実行して(phpMyAdminの「SQL」でも良いですが)正常に実行結果が返ってくるか
  2. その結果は何件あるのか
  3. phpMyAdminからエクスポートは可能か
  4. set_time_limit(0)で処理は正常終了できるか
  5. エラー表示をOnにしたら何かエラーがでていないか(というかcatchで何か捕捉してませんか?コメントアウト外して確認してください)
  6. データ取得直後にvar_dump();したときに正しくデータは取れているか
  7. while 内で$rowの内容を出力(echoでもvar_dumpでも良いです)したときにどこまで通っているか
  8. whileの1週目でexit;したときにファイル内容はどうなっているか

ちなみにheader関数でダウンロードさせる際は中身ができていようとできていなかろうとそのままそのファイル名でアタッチメントします。
中身に書き込まれるのはその後に画面出力された内容ですが、何も出力していない場合は、何も中身がないファイルがダウンロードできます。
つまり、catchの方にいっている可能性が高いです。
各所でecho __LINE__."\n";入れてみてください。プログラムの行数が出力されるので、どこまでいっているか追いやすくなります。

投稿2019/01/28 07:37

編集2019/01/28 07:44
m.ts10806

総合スコア80850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問