$file = "hoge.dat";
$fp = fopen($file, "r");
$file_val = fread($fp, filesize($file));
fclose($fp);
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=$file");
echo $file_val;
このようにした場合、送られてきたファイルが3バイト増えてます。
ファイルの先頭に3つ改行が入っているように見えます。
読み取って送るだけなので増える要素は無いように見えるのですが、何か原因のようなものがあれば教えてください。
環境は
CentOS 5.4
PHP 5
読み取り対象ファイルはblowfishで暗号化したものです。
http://taak.desperado.in/?eid=1029811
あまり関係ないとは 思いますが、filesizeを取得する前にキャッシュのクリアをしてみたらいかがでしょうか?
clearstatcache()
また、ファイルサイズが2GB以上の場合は、正しく取得できないようです。
header('Content-Transfer-Encoding: binary'); header('Content-Length: ' . filesize($file));
を追加してみてください。
ありがとうございます。
こちらを付加してみても状況は変わらずでした。
content-lengthできっているのでファイルサイズは合っていますが、逆に末尾3バイトが切られた様な形になってました。
直接的な回答ではありませんが、どこで問題が生じているのか調べてみましょう。
例えば、
出力を echo "hoge" とかに置き換えてみる。
header 出力をコメントアウトしてみる。
echo $file_val; echo $file_val; としてみて 3バイト入るのは最初だけか、2回入るか。
など。
ありがとうございます。
色々と試してみました。
echo "hoge";にした場合
最初に3行入ってhogeとなりました。
またecho $file_val;echo $file_val;としたところ、最初だけ3行入って2回目には改行は入ってませんでした。
freadした時にはもう改行がくっついてるということでしょうか・・・。
ますます解らなくなってきました。
ついでに
fclose($fp);
var_dump(strlen($file_val));
header("Content-Type: application/octet-stream");
とした場合は
3行改行
int(ファイルサイズ)
ファイル本体
という感じになっておりました。
<?php $file = "hoge.dat"; $fp = fopen($file, "r"); $file_val = fread($fp, filesize($file)); fclose($fp); header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=$file"); ?> <?php echo $file_val; ?>
こんな感じで、header関数とファイル出力の間に改行が入っているとすれば起こり得ますが…
意外にこんなケアレスミスが原因になりますので、念のため確認してみてください。
ありがとうございます。
改行は入っていないのですが、念の為全ての改行をとって1行のスクリプトにして行ってみましたがやはり改行は入っておりました。
うーん。ちょっとお手上げです。
追記
原因が判明しました。
どうやらincludeで読み込んでいる関数のリストに問題があったようで、includeをコメントアウトしたら現象は消えました。
とは言えfunctionしか入ってないもので呼び出しも何もしてない状態です。根本原因は解りませんが原因は特定できました。
みなさん本当にありがとうございました。
外部のPHPファイル等をインクルードしていませんか?
本体だけではなく、インクルードしたファイルに改行が入っている場合も
同じようなことが起こるようです。
a.php
<?php $file = "hoge.dat"; $fp = fopen($file, "r"); $file_val = fread($fp, filesize($file)); fclose($fp); header("Content-Type: application/octet-stream"); header("Content-Disposition: attachment; filename=$file"); require "b.php"; echo $file_val; ?>
b.php(改行3つのみのファイル)
手探りの状態でポイントを使わせてしまうのは忍びないので、
コメント欄を開放していただければと思いますが可能でしょうか?
ありがとうございます。
たとえ手探りでも回答していただいている時間を割いてもらっているのでポイント差し上げるのは普通だと思ってます。
昨日、徹夜で調べた所include自体は問題なかったのですが、その中でさらに再帰的に呼び出しているものがあり、さらにそのなかで特定の条件が重なった場合のみなぜか改行がくっついておりました。
さすがにこれには驚きましたがバグでも何でもなかったので今まで見落とされていたようです。
今回の件で大変勉強になりましたし、今後のコーディングとかでも気をつけていこうかと思います。
みなさんありがとうございました。
ありがとうございます。
早速filesizeの前においてみましたが変化ははありませんでした。
ダウンロードしようとしているサイズは5Mくらいなので大丈夫だとは思っています。
追記
fcloseの後ろに
var_dump(strlen($file_val));
を入れてサイズを見た所、この時点でのファイルサイズは合っていました。
さらに追記
バイナリエディターで見てみた所、ファイルの先頭に
0a
が3つ付加されてました。
保存時に付加されてるのだと思いますが、一体どの時点で付加されたのか謎です。