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

執筆者:

関連記事

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

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

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

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

【PHP】Mac/XAMPP/Eclipseでローカルに複数サイトの開発環境構築

Mac/XAMPP/Eclipseでバーチャルホストを使って複数の開発環境を構築する方法についてのメモです。 (Windowsでの構築方法はWindows/XAMPP/Eclipseでローカルに複数サ …

Windows/XAMPP/Eclipseでローカルに複数サイトの開発環境構築

Windows/XAMPP/Eclipseでバーチャルホストを使って複数の開発環境を構築する方法についてのメモです。 (Macの環境構築方法はMac/XAMPP/Eclipseでローカルに複数サイトの …

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

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

プロフィール

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