【PHP】file_get_contents関数のエラー処理とかいろいろ
file_get_contents関数は手軽に外部にあるデータを取得できますが、外部の環境に依存するためエラー処理をしっかり記述しておく必要があります。
ここではfile_get_contents関数を使うときの詳細なエラー処理について説明しています。
file_get_contetns関数のエラー処理
まずは結論から!ということで最終的なコードを載せます。
これをコピペ&カスタマイズすることでfile_get_contents関数のエラー処理ができます。
<?php
//コンテンツ取得先
$url = "http://ysklog.net/life/2223.html";
//コンテンツ取得
if($data = @file_get_contents($url)){
//ここにコンテンツの取得が成功した場合の処理
}else{
//エラー処理
if(count($http_response_header) > 0){
//「$http_response_header[0]」にはステータスコードがセットされている
$status_code = explode(' ', $http_response_header[0]); //「$status_code[1]」にステータスコードの数字だけが入る
//エラーの判別
switch($status_code[1]){
//404エラーの場合
case 404:
echo "指定したページが見つかりませんでした";
break;
//500エラーの場合
case 500:
echo "指定したページがあるサーバーにエラーがあります";
break;
//その他のエラーの場合
default:
echo "何らかのエラーによって指定したページのデータを取得できませんでした";
}
}else{
//タイムアウトの場合 or 存在しないドメインだった場合
echo "タイムエラー or URLが間違っています";
}
}
//「$http_response_header」の初期化
$http_response_header = array();
?>
「$http_response_header」について
file_get_contetns関数を実行した後は自動で「$http_response_header」(定義済み変数なので記述不要)にレスポンスヘッダーがセットされます。
<?php
//データ取得先
$url = "http://ysklog.net/life/2223.html";
//データ取得
$data = @file_get_contents($url);
//「$http_response_header」の参照
print_r($http_response_header);
?>
試しに上のコードを実行すると、次のような情報を取得できます。
取得が成功した場合
Array
(
[0] => HTTP/1.1 200 OK
[1] => Date: Sat, 07 Feb 2015 00:27:40 GMT
[2] => Server: Apache
[3] => X-Pingback: http://ysklog.net/xmlrpc.php
[4] => Link: ; rel=shortlink
[5] => Connection: close
[6] => Content-Type: text/html; charset=UTF-8
)
存在しないページだった場合(404エラー)
Array
(
[0] => HTTP/1.1 404 Not Found
[1] => Date: Sat, 07 Feb 2015 01:00:50 GMT
[2] => Server: Apache
[3] => X-Pingback: http://ysklog.net/xmlrpc.php
[4] => Expires: Wed, 11 Jan 1984 05:00:00 GMT
[5] => Cache-Control: no-cache, must-revalidate, max-age=0
[6] => Pragma: no-cache
[7] => Connection: close
[8] => Content-Type: text/html; charset=UTF-8
)
タイムアウトの場合 or 存在しないドメインだった場合
null(レスポンスヘッダはセットされない)
※その他のエラー(4**エラーや5**エラー)の場合は省略
「$http_response_header」からエラーコードを抽出する
上のように、file_get_contents関数を実行した後は「$http_response_header」にレスポンスヘッダーが配列でセットされます。
そして都合がいいことにどんな場合でも「$http_response_header」(配列)の最初の要素に半角スペースで区切られてエラーコードが含まれます。
つまり、次のようにすれば3桁のステータスコードが取得できます。
//「$http_response_header」(配列)の最初の要素を半角スペースで分割
$status_code = explode(' ', $http_response_header[0]);
/* 「$status_code[1]」にステータスコードの数字だけが入る */
また、タイムアウトやドメインが存在しない場合、「$http_response_header」には「null」がセットされます。
file_get_contents関数を複数回使うときの注意点
一つのプログラムで複数回file_get_contents関数を使う場合は注意が必要です。
それは、1回目でfile_get_contents関数でのアクセスが成功した場合、「$http_response_header」にレスポンスヘッダーが格納されます。
しかし、次にfile_get_contents関数でタイムエラー or 存在しないドメインだった場合、「$http_response_header」にはnull値が上書きされず、前回のレスポンスヘッダがセットされたままとなります(つまりエラー処理の条件分岐がおかしくなる)。
//①データの取得が成功
file_get_contents($url);
//②タイムエラーが生じる
file_get_contents($url);
//②ではなく①のレスポンスヘッダがセットされている
print_r($http_response_header);
これを防ぐためには、次のようにfile_get_contents関数を実行後は必ず「$http_response_header」を初期化しておく必要があります。
//「$http_response_header」の初期化
$http_response_header = array();
file_get_contents関数の前には「@」をつける
file_get_contents関数で存在しないページにアクセスして404エラーとなった場合、次のようにE_WARNING レベルのエラーとなります。
PHP Warning: file_get_contents(): failed to open stream: HTTP request failed! HTTP/1.1 404 Not Found
エラーの出力設定次第ではプログラムが強制終了する場合もあるので、file_get_contents関数の前には「@」をつけてエラー出力をキャンセルするようにしてください。
あわせて読んでほしい!
1:ぞえまるx:2019/03/05 11:52:20
アクセス数の記事面白かったです。
僕もブログをやっているのですが、もっとpv少ないです笑笑
応援しています^^