【PHP】file_get_contents関数のエラー処理とかいろいろ

公開日:
更新日:
カテゴリー: PHP

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少ないです笑笑
応援しています^^

コメントフォーム
お名前
コメント