PHPでfile_get_contents()関数の警告を処理するにはどうすればよいですか?


312

私はこのようなPHPコードを書きました

$site="http://www.google.com";
$content = file_get_content($site);
echo $content;

しかし、「http://」を削除すると$site、次の警告が表示されます。

警告:file_get_contents(www.google.com)[function.file-get-contents]:ストリームを開けませんでした:

私が試したtryし、catchそれはうまくいきませんでした。




set_error_handler機能付き使用のtry-catchは、ここで述べたようstackoverflow.com/a/3406181/1046909
MingalevME

2
URLからhttp://を削除すると、ローカルディスクで「www.google.com」というファイルを探していることになります。
Rauli Rajande 2017

これはどのようにして多くの注目と賛成を得ることができますか。プロトコル情報を削除する理由。2008年でさえ、FTPとHTTPSがありました。
ダニエルW.

回答:


507

ステップ1:戻りコードを確認します。 if($content === FALSE) { // handle error here... }

ステップ2:file_get_contents()の呼び出しの前にエラー制御演算子(つまり@)を置くことで警告を抑制します。 $content = @file_get_contents($site);


86
厳密な比較を使用することを忘れないでください:if($ content === FALSE)。ファイルに「0」が含まれている場合、偽陰性がトリガーされます。
アラムコチャリャ

7
こんにちは、これは私にとってはうまくいきませんでした。@を追加しても、E_WARNINGがグローバル(私のものではない)エラーハンドラーによってキャッチされ、戻り値を処理する前にスクリプトが停止します。何か案は?tnx。
Sagi Mann

1
副作用が検出されました:ファイルが存在しない場合、スクリプトは@file_get_contents行で停止します。
Dax

これが適切な解決策になろうとしても、これは私にはうまくいきません。データを受信して​​いないタイムアウト警告がありますが、$ content === FALSEは「トリガーされません」($ hostはローカルホストサーバーから呼び出されます。URLをブラウザーに貼り付けると、データがすぐに表示されることに注意してください)。
Oliver

4
回答は非常に古くなっていますが、使用@するとパフォーマンスに悪影響を与える可能性があるという注記を回答に追加することをお勧めします。かなりよく説明している関連記事でこの回答を参照してください。
Fr0zenFyr 2015年

148

エラーハンドラを、例外を呼び出す匿名関数として設定し、その例外に対してtry / catchを使用することもできます。

set_error_handler(
    function ($severity, $message, $file, $line) {
        throw new ErrorException($message, $severity, $severity, $file, $line);
    }
);

try {
    file_get_contents('www.google.com');
}
catch (Exception $e) {
    echo $e->getMessage();
}

restore_error_handler();

1つの小さなエラーをキャッチするために多くのコードのように見えますが、アプリ全体で例外を使用している場合は、最初に(たとえば、含まれている構成ファイルで)1回だけこれを行う必要があります。全体を通してすべてのエラーを例外に変換します。


これは、これまで見た中で最大のPHPの改善点の1つです。enobrevありがとう
Tomasz Smykowski 2012

@enobrev、なぜエラー番号と重大度の両方に同じ値を入れるのですか?
Pacerier 2013

set_error_handlerはエラー番号変数を提供しないため(残念ながら)、$ exception-> getCode()で有用な何かを提供する手段以外に特定の理由はありません。
enobrev 2013

1
@enobrev例外をスローする前に、匿名関数内のエラーハンドラーを復元することを忘れないでください。例外を処理できますが、その場合、ハンドラーはこの特定の例外をスローするように設定されますが、これは予期しないものとなる可能性があり、例外処理で別のエラーが発生したときに奇妙な、デバッグが難しい動作を引き起こします。
JosefSábl2017年

1
最終的にブロックにrestore_error_handler()呼び出しを含めることをお勧めします
peschanko

67

これを行う私のお気に入りの方法はかなり簡単です。

if (!$data = file_get_contents("http://www.google.com")) {
      $error = error_get_last();
      echo "HTTP request failed. Error was: " . $error['message'];
} else {
      echo "Everything went better than expected";
}

try/catch上記の@enobrevを試してみたところ、これが見つかりましたが、これにより、コードの長さ(およびIMO、読みやすさ)が短くなります。error_get_last最後のエラーのテキストを取得するために単に使用しfile_get_contents、失敗するとfalse を返すため、単純な「if」でそれをキャッチできます。


2
これは、この問題の最も簡単で最良の解決策です。たぶん@file_get_contentsブラウザへのエラー報告を抑制するためにそれを作るでしょう。
EDP

1
我々が使用することを強化したい場合は-私はすべての答えの中で、これが唯一の賢明な1であることを認める@file_get_contents警告を抑制すると、使用して結果値をテストします=== FALSE
kostix 2016

11
これは、本文を返さない、またはfalseと評価されるものを返す、成功したリクエストに対してエラーをトリガーします。する必要がありますif (false !== ($data = file_get_contents ()))
GordonM

ドキュメントでは明確にされていませんが、@を使用するとerror_get_last、私の経験では何も返されない可能性があります
Glenn Schmidt

33

@を前に付けることができます: $content = @file_get_contents($site);

これは警告を抑制します- 控えめに使用してください!エラー制御演算子を参照してください

編集:「http://」を削除すると、Webページではなく、ディスク上の「www.google .....」というファイルが検索されます。


それだけが実際に機能します。「ストリームを開けませんでした」というメッセージを他の方法で抑制できませんでした。
オラフ

21

1つの選択肢は、エラーを抑制し、後でキャッチできる例外をスローすることです。これは、コード内でfile_get_contents()を複数回呼び出す場合に特に便利です。それらすべてを手動で抑制および処理する必要がないためです。代わりに、単一のtry / catchブロックでこの関数を複数回呼び出すことができます。

// Returns the contents of a file
function file_contents($path) {
    $str = @file_get_contents($path);
    if ($str === FALSE) {
        throw new Exception("Cannot access '$path' to read contents.");
    } else {
        return $str;
    }
}

// Example
try {
    file_contents("a");
    file_contents("b");
    file_contents("c");
} catch (Exception $e) {
    // Deal with it.
    echo "Error: " , $e->getMessage();
}

15

ここに私がそれをした方法があります... try-catchブロックの必要はありません...最良の解決策は常に最も単純です...楽しんでください!

$content = @file_get_contents("http://www.google.com");
if (strpos($http_response_header[0], "200")) { 
   echo "SUCCESS";
} else { 
   echo "FAILED";
} 

4
-1:これは、404エラーなどが発生した場合に機能しますが、サーバーへの接続にまったく失敗した場合(たとえば、ドメイン名が間違っている場合)には機能しません。$http_response_headerHTTP応答が受信されないので、その場合は更新されないと思います。
ネイサンリード

1
@NathanReedが言ったように、リクエストが接続に失敗した場合に返されるのは$ contentがfalseではない(===である)ことを確認する必要があります
Seb

15
function custom_file_get_contents($url) {
    return file_get_contents(
        $url,
        false,
        stream_context_create(
            array(
                'http' => array(
                    'ignore_errors' => true
                )
            )
        )
    );
}

$content=FALSE;

if($content=custom_file_get_contents($url)) {
    //play with the result
} else {
    //handle the error
}

これは機能しません。が$url見つからない場合でも、警告が表示されます。
ラプター2014年

右のRaptor、私はstream_context_create();で答えを改善しました。「@」はお勧めできません
RafaSashi 2014年

1
ignore_errorsHTTPコンテキストに、HTTP応答ステータスコード> = 400をエラーとして解釈しないように指示するだけです。わずかに関連していますが、これはPHPのエラー処理の問題には答えません。

ignore_errorsオプションをありがとう!これは私が必要なものです!
Modder

6

これが私がそれを処理する方法です:

$this->response_body = @file_get_contents($this->url, false, $context);
if ($this->response_body === false) {
    $error = error_get_last();
    $error = explode(': ', $error['message']);
    $error = trim($error[2]) . PHP_EOL;
    fprintf(STDERR, 'Error: '. $error);
    die();
}

4

最善の方法は、独自のエラーハンドラと例外ハンドラを設定して、ファイルにログを記録したり、重要なハンドラにメールを送信したりすることです。 http://www.php.net/set_error_handler


1

このスクリプトを使用できます

$url = @file_get_contents("http://www.itreb.info");
if ($url) {
    // if url is true execute this 
    echo $url;
} else {
    // if not exceute this 
    echo "connection error";
}

これには厳密な比較が必要if ($url === true)...です0。応答として取得するか空の場合、接続エラーが発生するためです。
ダニエル

1

PHP 4以降はerror_reporting()を使用しています

$site="http://www.google.com";
$old_error_reporting = error_reporting(E_ALL ^ E_WARNING);
$content = file_get_content($site);
error_reporting($old_error_reporting);
if ($content === FALSE) {
    echo "Error getting '$site'";
} else {
    echo $content;
}


1

このようなもの:

public function get($curl,$options){
    $context = stream_context_create($options);
    $file = @file_get_contents($curl, false, $context);
    $str1=$str2=$status=null;
    sscanf($http_response_header[0] ,'%s %d %s', $str1,$status, $str2);
    if($status==200)
        return $file        
    else 
        throw new \Exception($http_response_header[0]);
}


-2

file_get_contents()を使用する前に、file_exists()関数を使用する必要があります。この方法で、phpの警告を回避できます。

$file = "path/to/file";

if(file_exists($file)){
  $content = file_get_contents($file);
}

これは、ローカルファイルを呼び出し、ローカルファイルが存在するかどうかを確認する適切な権限がある場合にのみ機能します
rubo77

-3

php.iniファイルを変更します。

allow_url_fopen = On

allow_url_include = On

これを行わないでください。特に、URLインクルードを許可しないでください。信じてはいけません。#c99という非常に正当な理由により、デフォルトで無効になっています。
ダニエルW.

-3

これはデータを取得しようとしますが、機能しない場合はエラーをキャッチし、キャッチ内で必要なことをすべて実行できます。

try {
    $content = file_get_contents($site);
} catch(\Exception $e) {
    return 'The file was not found';
}

-3
try {
   $site="http://www.google.com";
   $content = file_get_content($site);
   echo $content;
} catch (ErrorException $e) {
    // fix the url

}

set_error_handler(function ($errorNumber, $errorText, $errorFile,$errorLine ) 
{
    throw new ErrorException($errorText, 0, $errorNumber, $errorFile, $errorLine);
});

file_get_contentが常に例外をスローするとは限らない
marlar

回答を編集して、file_get_contentが例外をスローするタイミングを教えてください。
Ravinder Payal 2017

1
このコードは質問に答えることがありますが、このコードが質問に答える理由や方法に関する追加のコンテキストを提供すると、長期的な価値が向上します。
ジェイブランチャード

-3

また、

allow_url_use = On 

あなたにphp.ini警告を受けて停止します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.