PHP URLの存在確認
URLの存在確認
- 下記コードは、httpのリクエストを送信してURLにアクセス可能かどうか確認している。
確認する方法はいくつかある
- file_get_contents
- fopen
- get_headers
現状のコード
## URLのチェック $text = "チェックするURL" public static function validation_site_url($text) { // プロトコルがない場合 if(!preg_match('/^https?:\/\//', $text)) $text = 'http://'.$text; if($fp = @fopen($text, 'r')){ fclose($fp); return true; } else { return false; } }
参考 【php】 URLが存在するかどうか確認する at softelメモ
fopen()の返り値
成功した場合はファイルポインタを返します。失敗した場合はFALSEを返し、E_WARNINGレベルでエラーを発します。エラー制御演算子(@)が使用可能です。通常はこのファイルポインタを用いて、ファイル操作を行います。 PHP関数講座:fopen | そふぃのphp入門
ブラウザではアクセスできるのに、上記のコードでfalseが返ってくるURLがある
対策その1
- fopen()ではない処理を試す
get_headersを使ってみる
get_headersの返り値
数値添字配列あるいは連想配列でヘッダを返します。 失敗した場合は FALSE を返します。 PHP関数 - HTTPヘッダーを取得 - get_headers() - PHP入門 - Webkaru
問題のURLで試してみる
$url = "問題のURL"; $http_header = get_headers($url); var_dump($http_header); array(6) { [0]=> string(22) "HTTP/1.1 403 Forbidden" [1]=> string(35) "Date: Mon, 24 Dec 2018 17:03:33 GMT" [2]=> string(14) "Server: Apache" [3]=> string(19) "Content-Length: 328" [4]=> string(17) "Connection: close" [5]=> string(43) "Content-Type: text/html; charset=iso-8859-1" }
HTTPステータスコード403が返って来た
- 結果から考えられること
- 返り値が
false
ではないので、存在するURLである - ステータスコード403が返ってきた→アクセス権がない http://www5.plala.or.jp/vaio0630/mail/st_code.htm
- 返り値が
なぜブラウザでは200が返って来るのに、get_headersでは403が返ってくるのか
原因
fopen
やget_headers
ではUser-Agentヘッダーが送信されていないので、User-Agentヘッダーをチェックしているサイトでは期待する値を取得できない
対策
User-Agentヘッダーを送信する
User-Agentヘッダーとは
HTTPではUser-Agentヘッダーが定義されている。 クライアントはサーバーにリクエストを送る際に、ユーザーエージェントの情報をUser-Agentヘッダーとして送信する。User-Agentヘッダーには、アプリケーション名、バージョン、ホストオペレーティングシステムや言語といった情報が含まれる。 ユーザーエージェント - Wikipedia
取得してみる
var_dump($_SERVER['HTTP_USER_AGENT']) string(120) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36"
このUser-Agentヘッダーをfopen
やget_headers
の前にini_set
でセットする
ini_set ('user_agent', $_SERVER['HTTP_USER_AGENT']);
現状のコードを修正する
## URLのチェック public static function validation_site_url($text) { // プロトコルがない場合 if(!preg_match('/^https?:\/\//', $text)) $text = 'http://'.$text; ini_set ('user_agent', Input::server('HTTP_USER_AGENT')); //追記コード if($fp = @fopen($text, 'r')){ fclose($fp); return true; } else { return false; } }
fopen
はステータスコード1xx,4xx,5xxではfalseを返す
ファイルのオープンとクローズ(fopen, fclose) - ファイル関数 - PHP関数
[メモ] PHPのfile_get_contentsを、HTTPリクエストに使うときのTIPS ::ハブろぐ
404エラーとは〜今さら聞けない基礎知識と原因の対処方法を解説|ferret [フェレット]
PHP、URLの存在チェックを行うついでに「get_headers()」関数で遊んでみる。|マコトのおもちゃ箱 ~ぼへぼへ自営業者の技術メモ~