みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

PHPで生成したテキストファイルをダウンロード

PHPでMySQLデータベースからデータを取得してテキストファイルに出力し、それをダウンロードさせるプログラムを制作しています。
ただ、現在のやり方ではテキストファイル出力時の確認用にprintでページ内に表示させるものが、すべてダウンロードしてきたファイルに書き込まれてしまいます。
ダウンロード処理前に出力されて残っているテキストファイルは正常なので、ダウンロードの設定が悪いのだろうと思いますが、どう設定してやればいいのか分からない状態です。

以下ソース(テキストファイル生成部分などは省略します)
<?php
///////////////////////////////
//データベースからデータを取得
///////////////////////////////

//ファイルを書き込み専用で開く
$file = fopen("sample.txt", 'w');

///////////////////////////////
//printでデータを表示しながらファイルへ出力
///////////////////////////////

//ファイルをクローズ
fclose($file);

// MySQLに対する処理
$close_flag = mysql_close($link);

if ($close_flag){
print('<p>切断に成功しました。</p>');
}


download_file("sample.txt");

function download_file($tmp_file)
{
// ダウンロードさせるファイル名
//$tmp_file = "./sample.txt";
$j_file = "sample.txt";
$j_file = mb_convert_encoding($j_file, "SJIS", "UTF-8");

/* ファイルの存在確認 */
if (!file_exists($tmp_file)) {
die("Error: File(".$tmp_file.") does not exist");
}

/* オープンできるか確認 */
if (!($fp = fopen($tmp_file, "r"))) {
die("Error: Cannot open the file(".$tmp_file.")");
}
fclose($fp);

/* ファイルサイズの確認 */
if (($content_length = filesize($tmp_file)) == 0) {
die("Error: File size is 0.(".$tmp_file.")");
}

// ヘッダ
header("Content-Type: application/octet-stream");
// ダイアログボックスに表示するファイル名
header("Content-Disposition: attachment; filename=$j_file");
//表示するファイルサイズ
header("Content-Length: ".$content_length);
header('Pragma: no-cache');
header('Cache-Control: no-cache');


// 対象ファイルを出力する。
readfile($tmp_file);
exit;
}
?>

投稿日時 - 2012-10-18 17:16:34

QNo.7754617

すぐに回答ほしいです

質問者が選んだベストアンサー

printでメッセージを出力した時点で、httpレスポンスヘッダ(php標準のcontent-type; text/html)が送出されています。httpレスポンス(content-type: text/html)といくつかのメッセージのあとに、ファイルを返してもブラウザ側では複数のコンテンツは受け取れません(単一のコンテンツとして扱われます)。

#「httpの仕組み」が理解できていれば
#間違わない部分なんですが(汗

デバッグ時であればこの状態でもいいですが実運用をテストするのであれば、printは全部カットしてください(dieで止めるのは問題ありません)。

投稿日時 - 2012-10-18 17:58:55

お礼

ありがとうございます。
phpを触るのはこれが初めてで、httpに関しても完全に素人なもので・・・
ダウンロードをさせるならページへの表示はさせない方が無難、ということですね。
httpのことも少し調べてこようと思います。

投稿日時 - 2012-10-18 18:18:12

ANo.2

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(2)

=====以下引用=====
覚えておいて頂きたいのは、 header() 関数は、 通常の HTML タグまたは PHP からの出力にかかわらず、すべての実際の 出力の前にコールする必要があることです。 頻出するエラーとして、 include または require 関数、他のファイルをアクセスする関数に 空白または空行があり、 header() の前に出力が 行われてしまうというものがあります。同じ問題は、単一の PHP/HTML ファイルを使用している場合でも存在します。
=================
URL : http://php.net/manual/ja/function.header.php

ちなみに、
>header("Content-Disposition: attachment; filename=$j_file");

header("Content-Disposition: attachment; filename='" . $j_file . "'");
では?

それから、$tmp_fileと$j_fileの変数が入り乱れてますけど、合ってますか?

投稿日時 - 2012-10-18 17:43:13

お礼

ありがとうございます。
・・・リンク先は読んでみたのですが、「つまり・・・どういうことだってばよ?」状態になってしまいました。

投稿日時 - 2012-10-18 18:19:34

あなたにオススメの質問