dポイントプレゼントキャンペーン実施中!

お世話になってます。


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


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

A 回答 (6件)

たとえばこんな感じ



<?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;
    • good
    • 0
この回答へのお礼

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

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

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

お礼日時:2013/10/29 14:58

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



そうであれば全部の場合で失敗すると推測されるから違うか・・・
    • good
    • 0
この回答へのお礼

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


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

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

お礼日時:2013/11/06 13:08

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



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

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

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

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

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

お礼日時:2013/11/06 13:07

PHPの関数でバイナリセーフではないものと言えば「ファイル名」を扱う場所だけだと思います。

読み取り対象データはereg、ereg_replaceなどの関数を除けばバイナリセーフであったはずです。

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

バイナリセーフでないとはこういうことですね。


http://www.asahi-net.or.jp/~wv7y-kmr/memo/php_se …

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

但し$filepathをユーザーから受け取る場合はフィルタリングが必ず必要です。
    • good
    • 0
この回答へのお礼

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

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

お礼日時:2013/11/06 13:06

>PDFが壊れている



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

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

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

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

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

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

お礼日時:2013/10/29 09:44

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!