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

解決済みの質問

PDF ダウンロード

お世話になってます。


PHPからのPDFダウンロードで以下の様な現象が起きておりまして、
助言を頂きたいと思います。

管理者ページからPDFを添付してお知らせを入力し、
一般ユーザはお知らせを見たりPDFをダウンロードしたりする機能があります。

開発機では、まったく問題なくアップロード・ダウンロードができるのですが、
顧客環境では正常にアップロードができていることは確認ができますが、
Windows環境でダウンロードし、Acrobat Readerで確認するとPDFが壊れているという現象が起きています。
(実際にサーバーにアップロードされたファイルを確認しておりますのでアップロードは正常です。)

またそれは、全てのPDFファイルではなく1部のファイルにそのような現象が起きていて
さらには、MacOS 及び iPhoneから接続しダウンロードを行い閲覧するには問題はありません。

おそらくサーバー側のApacheのどこかに何か設定があるのかと思いますが検討がつきません。

環境は、CentOS5.9 + Apache 2.2.3

PHPのコードは、以下の通りです。


header("Cache-Control: public");
header("Pragma: public");
header("Content-Type: application/octet-stream; charset=UTF8");
header('Content-Disposition: attachment; filename="'. $file_name .'"');
header('Content-Length: ' . filesize($filepath));
readfile($filepath);


以上、どなたかお分かりのかたいらっしゃいましたら助言を頂けますでしょうか。
よろしくお願い致します。

投稿日時 - 2013-10-29 09:07:34

QNo.8325331

困ってます

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

たとえばこんな感じ

<?PHP
$filepath="hogehoge.pdf";
$file_name="fugafuga.pdf";
header("Content-type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"{$file_name}\"");
header("Content-Length: ".filesize($filepath));
$fp=fopen($filepath,"r");
while (!feof($fp)) {
print fread($fp,1024);
}
fclose($fp);
exit;

投稿日時 - 2013-10-29 11:04:04

お礼

ご丁寧にソースをご提供頂きありがとうございます。
確認させて頂きたいと思います。

ちなみに、大変申し訳ございませんがもしご存じであれば教えて頂きたいのですが、
アップロード・ダウンロードが正常にできるPDFとできないPDFでは何が異なるのでしょうか?
できるPDFは何度試してもできますし、
できないPDFは何度試してもできません。

PDFを作成する際の環境(バージョン等?)に左右されるのでしょうか?

投稿日時 - 2013-10-29 14:58:39

ANo.3

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

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

回答(6)

ANo.6

BOM付きUTF-8で書かれてるとか?

そうであれば全部の場合で失敗すると推測されるから違うか・・・

投稿日時 - 2013-10-29 17:27:45

お礼

ご連絡ありがとうございました。
BOM付きUTF-8ではなかったです。ささいなことでもご指摘頂きありがとうございます。


yambejp様提供のソースで問題なくダウンロードできました。

バイナリセーフではなかったことが原因のようでした。
ありがとうございました。

投稿日時 - 2013-11-06 13:08:51

ANo.5

>正常にできるPDFとできないPDFでは何が異なるのでしょうか?

なんでしょうね?
とりあえずファイルサイズが一緒だというのであれば
WindowsのFCコマンドなどでバイナリベースで比較をして
本当に完全に一致しているか確認するところからでしょうね。

また別解にもあったようにバイナリエディタで開き
特に先頭あたりにゴミがついていないかを見てみるとよいかもしれません。

header関数のContent-Lengthをコメントアウトすると、ファイルサイズが
変わるようであれば、ファイルの入出力のロジックに問題があるかも

投稿日時 - 2013-10-29 15:10:03

お礼

ご連絡ありがとうございました。
ご提供のソースで問題なくダウンロードできました。

ご指摘通り、バイナリセーフではなかったことが原因のようでした。
ありがとうございました。

投稿日時 - 2013-11-06 13:07:41

ANo.4

PHPの関数でバイナリセーフではないものと言えば「ファイル名」を扱う場所だけだと思います。読み取り対象データはereg、ereg_replaceなどの関数を除けばバイナリセーフであったはずです。

壊れたファイルをエディタで見てみると何か分かるかもしれません。バイナリデータの中にエラーメッセージが混入している可能性はあります。

投稿日時 - 2013-10-29 13:23:11

ANo.2

バイナリセーフでないとはこういうことですね。
http://www.asahi-net.or.jp/~wv7y-kmr/memo/php_security.html

要は$filepathにNULLバイトが入ってるとマズいということです。
(そんなこと早々ないと思いますが)

但し$filepathをユーザーから受け取る場合はフィルタリングが必ず必要です。

投稿日時 - 2013-10-29 10:11:57

お礼

ご連絡ありがとうございました。
yambejp様提供のソースで問題なくダウンロードできました。

ご指摘通り、バイナリセーフではなかったことが原因のようでした。
ありがとうございました。

投稿日時 - 2013-11-06 13:06:46

ANo.1

>PDFが壊れている

の状態次第ですね
・大幅にファイルサイズが大きい(小さい)
・微妙にファイルサイズが大きい(小さい)
どんな感じなのでしょうか?

readfileはバイナリセーフではないので、きちんとしたファイルI/Oで
開いて読んで出力してみてはいかがでしょうか?

投稿日時 - 2013-10-29 09:21:51

お礼

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

ファイルサイズにつきましては、まったく同じです。

> readfileはバイナリセーフではないので、きちんとしたファイルI/Oで
> 開いて読んで出力してみてはいかがでしょうか?

とは、 file_put_contents() を利用した方が良いということでしょうか?

投稿日時 - 2013-10-29 09:44:18

あなたにオススメの質問