PHPで生成したテキストファイルをダウンロードする方法について

このQ&Aのポイント
  • PHPでMySQLデータベースからデータを取得してテキストファイルに出力し、それをダウンロードさせるプログラムを制作しています。
  • ダウンロード処理前に出力されて残っているテキストファイルは正常なので、ダウンロードの設定が悪いのだろうと思いますが、どう設定してやればいいのか分からない状態です。
  • ファイルを書き込み専用で開いてデータを出力し、ダウンロードさせる際にはヘッダ情報を設定してファイルを出力する必要があります。
回答を見る
  • ベストアンサー

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; } ?>

  • PHP
  • 回答数2
  • ありがとう数2

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

  • ベストアンサー
  • shimix
  • ベストアンサー率54% (865/1590)
回答No.2

printでメッセージを出力した時点で、httpレスポンスヘッダ(php標準のcontent-type; text/html)が送出されています。httpレスポンス(content-type: text/html)といくつかのメッセージのあとに、ファイルを返してもブラウザ側では複数のコンテンツは受け取れません(単一のコンテンツとして扱われます)。 #「httpの仕組み」が理解できていれば #間違わない部分なんですが(汗 デバッグ時であればこの状態でもいいですが実運用をテストするのであれば、printは全部カットしてください(dieで止めるのは問題ありません)。

greatchahang
質問者

お礼

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

その他の回答 (1)

回答No.1

=====以下引用===== 覚えておいて頂きたいのは、 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の変数が入り乱れてますけど、合ってますか?

greatchahang
質問者

お礼

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

関連するQ&A

  • PHP:wavファイルのダウンロード

    音楽ファイルを会員に配信するサイトを運営しています。 mp3は問題なくダウンロード・再生できるのですが、wavファイルはダウンロードしてもファイルが破壊されており、再生できません。 wavファイルのバイト数に変化はありませんでした。FTPからファイルをダウンロードすると正常に再生できるので、問題はウェブでのダウンロードをする過程にあることは分かっています。いろいろ調べているのですがそれ以降の原因が分からず困っています。 誰か原因をご存知の方、目星の付く方などおられましたら、ぜひ解答お願いいたします。 ファイルダウンロードには、以下のようなphp関数を使っています。 function download_file($path_file){ if (!file_exists($path_file)) { die("Error: No Such File."); } if (($content_length = filesize($path_file)) == 0) { die("Error: File size is 0.(".$path_file.")"); } if($_POST['sort'] == mp3){ header("Content-Type: audio/mpeg"); }elseif($_POST['sort'] == wav){ header("Content-Type: audio/x-wav"); } header("Content-Disposition: attachment; filename=\"" .basename($path_file)."\""); header("Content-Length: ".$content_length); header("Content-Transfer-Encoding: binary"); $handle = fopen($path_file, 'rb'); while (!feof($handle)) { echo fread($handle, 4096); ob_flush(); flush(); } fclose($handle); }

    • 締切済み
    • PHP
  • phpプログラミングについて

    php初心者です。 ファイルをダウンロードして保存するプログラムを作成しています。 ダイアログを表示させる形式をとっているのですが、保存されたファイルが正しく開けないんです。 ワードの場合だとファイルが壊れ、テキストファイルの場合、htmlのコードが一緒に入ってしまいます。 以下にソースコードと、ファイルの表示結果も載せるので、アドバイスお願いします。 [download.php] <html> <head> <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8"> <title>testdownload</title> </head> <body> テキストリンクの場合<br> <a href = "sample.php">sampleファイルをダウンロードする</a> <br><br> フォームボタンの場合<br> <form method = "post" action = "sample.php"><input type = "submit" value = "download"></form> </body> </html> [sample.php] <html> <head> <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8"> <title>downloadphp</title> </head> <body> <?php $path_file = "./test2.txt"; $path_file = mb_convert_encoding($path_file,"Shift_JIS","AUTO"); /* ファイルの存在確認 */ if (!file_exists($path_file)) { die("Error: File(".$path_file.") does not exist"); } /* オープンできるか確認 */ if (!($fp = fopen($path_file, "r"))) { die("Error: Cannot open the file(".$path_file.")"); } fclose($fp); /* ファイルサイズの確認 */ if (($content_length = filesize($path_file)) == 0) { die("Error: File size is 0.(".$path_file.")"); } /* ダウンロード用のHTTPヘッダ送信 */ header("Content-Disposition: attachment; filename=\"".basename($path_file)."\""); header("Content-Length: ".$content_length); header("Content-Type: application/octet-stream"); /* ファイルを読んで出力 */ if (!readfile($path_file)) { die("Cannot read the file(".$path_file.")"); } ?> </body> </html> [test2.txt] これはテストです。 [ダウンロード後のtest2.txt] <html> <head> <meta http-equiv = "Content-Type" content = "text/html; charset = UTF-8"> <title>downloadphp</title> </head> <body> これはテストです。 </body> </html> 以上、よろしくお願いします。

    • 締切済み
    • PHP
  • PHPでのファイルダウンロードについて

    初めて質問させていただきます。 社内用でファイルのアップロード・ダウンロードができるシステムを開発しています。 PCからは問題なくアップロードもダウンロードも行えていたのですが、 スマホからアクセスしてダウンロードをすると失敗してしまいます。 下記のコードを使ってます。 ファイルの種類はいろいろなので、「application/octet-stream」にしてます。 が、それぞれのファイルタイプに合わせて変更させても状況は変わりませんでした。 -- header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="'.$file_name.'"'); header('Content-Length: '.filesize($dl_file)); readfile($dl_file); exit; -- なにか解決策があるようでしたら、教えていただけないでしょうか。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • PHPでファイルのダウンロードすると開けません。

    PHPでファイルのダウンロードすると開けません。 文書を整理するために、アップロードして、必要に応じてダウンロードする仕組みを作っています。 PDFや画像のファイルは問題ないのですが、、 word文書(エクセルもダメでした)を、以下のファイルを作って、ダウンロードし開こうとすると 「ファイル******.docxは無いように問題があるため、開けませんでした。」となります。 ※エクセルでは、「Exelで****.xlsxを開くことが出来ません。ファイル形式またはファイルか拡張子が正しくありません。ファイル拡張子とファイル形式が一致していることを確認してください」  とダイアログが出てきます。 $file="アップロードしてある実ファイル名"; $file_name="ローカルに保存する際のファイル名"; ※ファイル名を変更しなくても同じなので、そこは関係ないと思います。 header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=$file_name"); header('Content-Length: '.filesize('$file')); readfile($file); リンクを張って開くのには何の問題もありません。 <a href="http://www.******.com/images/$file">$file_name</a> ダウンロードする際に名前を変更したいので、ダウンロード用のファイルを作ってダウンロードさせようとしています。 何か、ダウンロードをする前に処理が必要なのでしょうか? よろしくご教授お願いいたします。 ※ワード、エクセルは2010を使用しています。

    • ベストアンサー
    • PHP
  • PHPでファイルをダウンロードさせるコード

    PDFファイルをその場では開かせず、ダウンロードさせるコードを作成しています header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="' . basename($path_file) . '"'); header('Content-Length:' . $content_length); ファイルをダウンロードさせること自体は成功しており、ファイル容量も間違ってないのですが ダウンロード後に開こうとするとファイルが破損していて開くことができません。 また、ハイパーリンクから直接開かせた場合は問題なく表示できております。 原因の分かる方がいらっしゃいましたらアドバイスお願い致します。

    • ベストアンサー
    • PHP
  • PHPで複数ファイルのダウンロード

    はじめまして、PHPについて質問させていただきます。 PHPでファイルを複数ダウンロードできるようしたいと思っています。 色々調べ、header関数を使用し、以下のように記述すると ファイルのダウンロードは成功しました。 /*****************************************/ // ダウンロードさせる元ファイル(絶対パス) $filepath = 'test_01.pdf'; // 保存時のファイル名(デフォルト) $filename = 'download001.pdf'; // HTTPヘッダ送信 header("Content-length: " . filesize($filepath)); header("Content-type: application/pdf"); header("Content-Disposition: attachment; filename=\"{$filename}\""); // ファイルを読み込んで出力 readfile($filepath); /*****************************************/ 一つのファイルのダウンロードに成功したので、 次に複数のファイルを順番にダウンロードをさせる為にループ処理をしました。 /*****************************************/ //配列 複数ファイル $downfile = array("test_01","test_02","test_03"); //データ数 $max = count($downfile); // ダウンロードさせるディレクトリ(絶対パス) $filepath = "/home/sites/www.eshop-himawari.com/web/test_nihon/form_down/file/"; // 保存時のファイル名(デフォルト) $filename = "download"; $filetype = ".pdf"; $kazu = 1; //ループ処理 for( $i = 0; $i < count( $max ); $i++ ){ $downpath = $filepath.$downfile[$i].$filetype; $filename = $filename.$kazu.$filetype; $kazu = $kazu++; // HTTPヘッダ送信 header("Content-length: " . filesize($downpath)); header("Content-type: application/pdf"); header("Content-Disposition: attachment; filename=\"{$filename}\""); // ファイルを読み込んで出力 readfile($downpath); // $fp = fopen( "$downpath", "rb" ); // @fpassthru( $fp ); } /*****************************************/ しかし実行すると最初のファイルはダウンロードしますが 2つ目からのファイルはダウンロードされませんでした。 きちんとループ処理をされて、2つ目以降のファイルをダウンロード するには、どうすればいいのでしょうか?

    • 締切済み
    • PHP
  • PHPでのファイルのダウンロードについて

    お世話になります。 タイトルのとおりPHPでファイルのダウンロードを行いたいのですが、 ファイルを保存するというダイアログが出てくれません。 tesuto.php <?php $file="/work/tesuto.csv"; header ("Content-Disposition: attachment; filename=$file"); header ("Content-type: application/x-csv"); readfile ($file); ?> tesuto.phpを実行するとダウンロードされずに、ファイルの中身が表示されてしまいます。 よろしくお願いします。

    • ベストアンサー
    • PHP
  • PHPでファイルのダウンロードについて

    お世話になります。ダウンロードボタンを付けてファイルのダウンロードを行う処理で困った事になってます。 (DL.php) $file_name=htmlspecialchars(@$_POST['file_name']); $file_name=addslashes($file_name); mb_convert_variables("SJIS-WIN","EUC-JP",$file_name); $file_to=htmlspecialchars(@$_POST['file_to']); $file_to=addslashes(@$_POST['file_to']); header ("Content-Disposition: attachment; filename=".$file_name); header ("Content-type: application/octet-stream"); require_once("dl_config.php"); readfile ($data_pas.$file_to); dl_config.php <?PHP $data_pas="/data/"; ?> この状態でテキストファイルをダウンロードすると、DLしたファイルの中に不要な改行ファイルが挿入されています。 またrequire_once("dl_config.php");を削除し readfile ($data_pas.$file_to);を readfile ("/data/".$file_to);とすると、改行は入らなくて、正常なファイルがダウンロードされます。 よろしくお願いします。

    • 締切済み
    • PHP
  • PHP CSV 出力

    失礼します。 現在PHPで指定したパスに置いてあるCSVを出力したいのですが、 CSVは出力できているのですが、HTMLが先頭に入ってしまいます。 htmlファイルに設置したボタンに対して phpファイルで処理をしています。 どこかおかしい部分があればご教授頂きたいです。 HTMLファイル <?php $self = $_SERVER["SCRIPT_NAME"]; ?> <form method='POST' action='<?php $self ?>'> <input type='submit' value='CSV出力' name='get_csv'> </form> PHPファイル function This_Month(){ $filepath = 'hoge.csv'; //ダウンロードしたいファイルパス $filename = 'test.csv'; //ダウンロードした際のファイル名 if(!file_exists($filepath)){ die("Error:File(".$filepath.") does not exist"); } //オープンできるか確認 if(!($fp = fopen($filepath,"r"))) { die("Error:Cannot open the file(".$filepath.")"); } fclose($fp); //ファイルサイズの確認 if(($content_length = filesize($filepath)) == 0){ die("Error:File size is 0.(".$filepath.")"); } //ファイルの処理方法 header('Content-Disposition: attachement; filename="'.$filename.'"'); //ファイルタイプ指定 header('Content-Type: application/octet-stream'); header('Content-Transfer-Encoding:binary'); //ファイルサイズ header('Content-Length: '.filesize($filepath)); mb_convert_encoding($filepath,'utf-8','shift-jis'); readfile($filepath); exit(); } //ボタンに合わせて条件を変えていく if(isset($_POST["get_csv"])){ //ユーザーから来たデータをエスケープする $csv_output = htmlspecialchars($_POST["get_csv"], ENT_QUOTES, "UTF-8"); switch ($csv_output) { case "CSV出力": ”This_Month();  break; default: echo "エラー"; exit; } }

    • ベストアンサー
    • PHP
  • ACCESSでテキストファイルを出力したい

    Function txt_file() Open "a.txt" For Random As #1 Put #1, 1, "aaaaaaaaaaa" Put #1, 2, "bbbbbbbbb" Close #1 End Function こんな感じでテキストファイルを出力したいのですが 上のコーディングを正確に直すアドバイスをしてもらうか サンプルソースが乗っている、URLを 教えてください

専門家に質問してみよう