PHP

【PHP】大きいリモートファイルをfreadすると途中で切れる【理由と解決法】

投稿日:2018年11月15日 更新日:

PHPでリモートファイル(httpやsshで読み込むファイル)をfreadする際、容量の大きいファイルを読み込むと、読み込みが途中で切れる事があります。

エラーなど発生せず、freadの結果が読み込みファイルの途中で途切れてしまいます。
ちょっとやっかいですよね。

これはfreadの仕様でして、リモートファイルを読み込む場合は別の方法をで実装した方が良いです。

読み込みが切れる理由と、正しい実装方法をご紹介します。

スポンサーリンク

【理由】リモートファイルをfreadすると途中でファイル読み込みが切れる

リモートファイルをfreadすると、途中でファイル読み込みが切れる事があります。

恐ろしいのは、そこそこのファイルサイズじゃないと切れないので大きいサイズのファイルでテストしていないと気づかないんですよね。
テストをスルーして本番で不具合発覚なんてケースになりえるので要注意です。

なぜファイルの読み込みが途中で切れちゃうかというと…

警告
通常のローカルファイル以外のもの、例えば リモートファイル や popen()、fsockopen() が返す ストリームを読み込んでいる場合には、 パケットが有効になった後に読み込みはストップします。 つまり以下の例のように分割されたデータを結合すべきであるということです。

PHPリファレンスにちゃんと書いてありました。

ようはリモートファイルをfreadする場合は、パケットの単位で読み込みが途切れてしまうのです。

ちなみに、リファレンスではhttpでファイルを開いたケースが紹介されいますが、僕はssh2で読み込んだファイルで発生しました。

リモートファイルの読み込み全般で発生すると思われます。

【対策】freadではなくstream_get_contentsを使おう

正しい実装方法もリファレンスに書いてあります。

解決方法を引用します。

PHP5以降

PHP5未満

参考:PHPリファレンス

PHP5以降であれば、freadstream_get_contentsに変えればOKです。

PHP5未満の場合は、読み込み完了をチェックしながらループで繰り返しfreadする必要があります。

まとめ:リモートファイルの読み込みにfreadを使う場合は要注意

なかなかテストで気づけない不具合になりうるので、覚えておきましょう。

実際僕は、これで不具合をだしてしまいましたので…

最後までお読み頂きありがとうございました!

スポンサーリンク


-PHP

執筆者:

関連記事

【PHP】Shift-JISにエンコードしたCSVが文字化けするのはBOMが原因?

PHPでShift-JISに変換エンコードしたCSVをダウンロードする機能を実装したのですが、日本語の文字化けが発生。 この問題がちょっとややこしくて解決するのに時間がかかりました。 なんと文字化け …

【EC-CUBE】新しいフロントページを追加する方法

EC-CUBE2で新規にフロントページを追加する方法の解説です。 スポンサーリンク 目次dtb_pagelayoutにレコードを追加するPHPファイルを作成ページクラスを作成テンプレートファイルを配置 …

【EC-CUBE2】CSVをUTF-8でダウンロードさせる修正方法

デフォルトのEC-CUBE2だと、ダウンロードされるCSVはShift-JISになっています。 おそらく、EXCELでCSVを編集する事を考慮しているのでしょう。 でも、Shift-JISだと困るシー …

PhpStormに乗り換えて良かった!オススメの5つの機能

EclipseからPhpStormに乗り換えて2年目に突入し、迷わずPhpStormのライセンスを更新しました。 PhpStormにはかな〜り満足しています。 開発効率はだいぶ上がったんじゃないでしょ …

【EC-CUBE2】 SQLをデバック出力する方法

EC-CUBE2で実行されるSQLをデバッグ出力する方法について。 コードをコピペする事で、実行されたSQLを画面にデバッグ出力できます。 スポンサーリンク 目次EC-CUBE2でSQLをデバックする …

プロフィール

このサイトを運営しているDENです。
アングラーのフリープログラマー。 主にプログラミングと釣の話を発信しています。
プログラミングで自由になり思う存分に釣りをしまくる生活実践中。
詳しいプロフィールはこちら 
フォスターフリーランス