• 締切
  • すぐに回答を!

phpプログラミングについて

  • 質問No.6430721
  • 閲覧数316
  • ありがとう数1
  • 気になる数0
  • 回答数6
  • コメント数0

お礼率 7% (1/14)

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件)

  • 回答No.6

ベストアンサー率 60% (3/5)

「中身がとれない」とはどう意味でしょうか?

headerの部分をすべてコメントアウトして、ブラウザになにかエラーが表示されないかやってみてください。
  • 回答No.5

ベストアンサー率 60% (3/5)

>で、上記のプログラムを、ファイル名を./files/サンプル1.docxに変更(filesというディレ
>クトリにおいています。)したところ、ファイルの破損はなくなりましたが、変わりに中身
>がとれません。。

ファイル名はファイルの名前のみ。パスは付けない。
readfileに入れるファイルはパス付きのファイル。

私の例に合わせるなら

$file = './files/サンプル1.docs';
$filename = 'サンプル1.docs';

になります。
補足コメント
taka_janu27

お礼率 7% (1/14)

説明不足ですみません。

その点は間違いなくやってます。

それでも中身が取れないんです。。
投稿日時:2011/01/13 20:15
  • 回答No.4

ベストアンサー率 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等では正しく表示されません。
補足コメント
taka_janu27

お礼率 7% (1/14)

とても丁寧な回答ありがとうございます。

>セッションやクッキーも使えません。スクリプト内のヘッダーと衝突するからです。

これはこのプログラム内で、ということですよね?

で、上記のプログラムを、ファイル名を./files/サンプル1.docxに変更(filesというディレクトリにおいています。)したところ、ファイルの破損はなくなりましたが、変わりに中身がとれません。。
投稿日時:2011/01/12 15:39
  • 回答No.3

ベストアンサー率 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してみてください
補足コメント
taka_janu27

お礼率 7% (1/14)

ありがとうございます。

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);

に変える、という形でよいのでしょうか??
投稿日時:2011/01/07 15:56
  • 回答No.2

ベストアンサー率 51% (1060/2054)

こんにちは。

http://maranellog.blogspot.com/2008/04/php.html
なんか参考になりませんでしょうか。

(これが原因と確信があるわけではありませんが・・・)
補足コメント
taka_janu27

お礼率 7% (1/14)

ありがとうございます。

参考のURLを見ましたが、そこの設定はデフォルトでpassになっていました。
投稿日時:2011/01/07 14:07
  • 回答No.1

ベストアンサー率 51% (1060/2054)

こんにちは。

sample.phpのファイル出力処理がhtml内に入っているからではないでしょうか?
ファイルを出力するのであればその処理のみphpに記述します。
<?php
?>
にある処理のみでphpを作ってみてください。
補足コメント
taka_janu27

お礼率 7% (1/14)

回答ありがとうございます。


ご指摘の部分、phpのみにしてみたところ、テキストファイルに関してはうまくいきましたが、
ワードファイルは破損してしまいます。
「開いて修復」を実行すれば内容は受け取れるのですが・・・
投稿日時:2011/01/07 10:55
結果を報告する
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。
AIエージェント「あい」

こんにちは。AIエージェントの「あい」です。
あなたの悩みに、OKWAVE 3,600万件のQ&Aを分析して最適な回答をご提案します。

関連するQ&A

ピックアップ

ページ先頭へ