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以降

<?php
// PHP 5 以降での例
$handle = fopen("http://www.example.com/", "rb");
$contents = stream_get_contents($handle);
fclose($handle);
?>

PHP5未満

<?php
$handle = fopen("http://www.example.com/", "rb");
if (FALSE === $handle) {
    exit("Failed to open stream to URL");
}

$contents = '';

while (!feof($handle)) {
    $contents .= fread($handle, 8192);
}
fclose($handle);
?>

参考:PHPリファレンス

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

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

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

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

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

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

スポンサーリンク


-PHP

執筆者:

関連記事

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

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

【PHP】日時を計算する2つの方法

現在日を起点にして日時を取得して処理したいことってよくありますよね。 例えば、現在日時の1日前のデータのステータスを変更するとか。 今回は、PHPで日時を計算する2つ方法をご紹介します。 PHPの内部 …

EclipseからPhpStormへ乗り換える時に行った事

こんにちは! DENです! 僕はもともとJavaエンジニアだったので、PHPの開発ももっぱらEclipseです。 もう10年近くEclipseを使っています。 使い慣れたIDEで不満もなく使っていまし …

【PhpStorm/MAMP】デバッグ中にphpMyAdminで中断してしまう場合の対処方法

PhpStormでデバッグしていると、なぜかphpMyAdminで一時停止してしまう問題。 開発環境は、ローカルのMAMPです。 phpMyAdminを使う時は毎回デバッグをOFFにしていたのですが、 …

【現役エンジニアがオススメ】『いきなりはじめるPHP』はプログラミング入門に最適

こんにちは!DENです。 PHPの入門書『いきなりはじめるPHP』が、なかなか良い本だったのでご紹介します。 いきなりはじめるPHP posted with ヨメレバ 谷藤賢一 リックテレコム 201 …

プロフィール

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