- 締切済み
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> 以上、よろしくお願いします。
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- nak2052
- ベストアンサー率60% (3/5)
「中身がとれない」とはどう意味でしょうか? headerの部分をすべてコメントアウトして、ブラウザになにかエラーが表示されないかやってみてください。
- nak2052
- ベストアンサー率60% (3/5)
>で、上記のプログラムを、ファイル名を./files/サンプル1.docxに変更(filesというディレ >クトリにおいています。)したところ、ファイルの破損はなくなりましたが、変わりに中身 >がとれません。。 ファイル名はファイルの名前のみ。パスは付けない。 readfileに入れるファイルはパス付きのファイル。 私の例に合わせるなら $file = './files/サンプル1.docs'; $filename = 'サンプル1.docs'; になります。
- nak2052
- ベストアンサー率60% (3/5)
参考にお使いください。 ファイルはLinux上に日本語名(UTF-8)で保存されているものとします。 クライアントはWindowsを前提にしています。 適当に書き換えてください。 <?php ini_set('display_errors', 1); $file = "/var/www/html/file/xxxx.doc";///ここでは、仮に。 $filename = "xxxx.doc";///ここでは、仮に。 $filneame = mb_convert_encoding($filename, 'SJIS-WIN', 'UTF8');///SJISでもいいですが、Windows上では化ける文字もあります。 //サーバがWindowsならおそらくココは必要ない。 header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename='.$filneame); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . filesize($file)); ob_clean(); flush(); readfile($file); exit; ?> ・他の方ご指摘のとおり、HMLT内にPHPを埋め込む書き方ではできません。これ単体のPHPにします。 ・<?phpの前には何も書いてはいけません。空行もダメです。 ・セッションやクッキーも使えません。スクリプト内のヘッダーと衝突するからです。 ・Content-Lengthを出さないとファイル名がIE等では正しく表示されません。
補足
とても丁寧な回答ありがとうございます。 >セッションやクッキーも使えません。スクリプト内のヘッダーと衝突するからです。 これはこのプログラム内で、ということですよね? で、上記のプログラムを、ファイル名を./files/サンプル1.docxに変更(filesというディレクトリにおいています。)したところ、ファイルの破損はなくなりましたが、変わりに中身がとれません。。
- yambejp
- ベストアンサー率51% (3827/7415)
(1)ヘッダを工夫してみてください <?PHP header("Content-Type: application/vnd.ms-word"); header("Content-Type: application/force-download"); header("Content-Type: application/octet-stream"); header("Content-Type: application/download");; header("Content-Disposition: attachment;filename=test.doc"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Pragma: public"); header("Content-Transfer-Encoding: binary "); readfile("hoge.doc"); exit; ?> (2)readfileは挙動が信用できないので きちんとopen→read→print→closeしてみてください
補足
ありがとうございます。 1ですが、特に変化はありませんでした。 2に関してですが、 if (!readfile($path_file)) { die("Cannot read the file(".$path_file.")"); } の部分を $handle = fopen($file_path,"rb"); $filedata = fread($handle,$cotent_length); fclose($handle); に変える、という形でよいのでしょうか??
- LancerVII
- ベストアンサー率51% (1060/2054)
こんにちは。 http://maranellog.blogspot.com/2008/04/php.html なんか参考になりませんでしょうか。 (これが原因と確信があるわけではありませんが・・・)
補足
ありがとうございます。 参考のURLを見ましたが、そこの設定はデフォルトでpassになっていました。
- LancerVII
- ベストアンサー率51% (1060/2054)
こんにちは。 sample.phpのファイル出力処理がhtml内に入っているからではないでしょうか? ファイルを出力するのであればその処理のみphpに記述します。 <?php ?> にある処理のみでphpを作ってみてください。
補足
回答ありがとうございます。 ご指摘の部分、phpのみにしてみたところ、テキストファイルに関してはうまくいきましたが、 ワードファイルは破損してしまいます。 「開いて修復」を実行すれば内容は受け取れるのですが・・・
補足
説明不足ですみません。 その点は間違いなくやってます。 それでも中身が取れないんです。。