URLが実際に存在するかどうかをPHPで調べる方法を紹介します。デッドリンクのチェックをおこなうプログラム等に利用できます。
fileの場合にはfile_exists()という関数があります。この関数でも良いのですが、PHP5で追加されたget_headers()関数を使う簡単な方法を紹介します。 注: get_headers()の前の@はエラー停止を抑制するためです。
- function url_exists($url) {
- $header = @get_headers($url);
- return true;
- }
- return false;
- }
$header[0]には以下のようなステータスコードが戻されます。
- URLが存在する場合:'HTTP/1.1 200 OK'
- URLが存在するがリダイレクトされている場合: 'HTTP/1.1 302 Found'
- URLが存在しない場合:'HTTP/1.1 404 Not Found'
- URLへアクセス許可されていない場合:'HTTP/1.1 403 Forbidden'
- サーバーにアクセスできない場合:'HTTP/1.1 500 Internal Server Error'
他のケースもありますが、主としてこういったステータスが戻ります。上記のコードではステータスコードが200の場合と302の場合にのみOKとしています。302はファイルは存在するがそのファイル内部で別のURLにリダイレクトする場合に返されるコードです。以下のコードのような内容のファイルなどがこのステータスになります。ですのでこれも使用目的によってはURLが存在するとするべきかと思いOKとしました。
- <?php
- ?>
ステータス 302 については以下のページに詳しい解説があります。
http://www.onflow.jp/cyano/archives/161
尚、get_headers()関数はPHP5で導入されましたので、PHP4では使用することができません。PHP4の環境の場合は同等の関数を自分で定義することで対応可能です。以下のPHPマニュアルのget_headers()のページのユーザからの投稿記事中にPHP4で使えるget_headers()と同等のコードサンプルがありますのでそちらを参照ください。
http://jp.php.net/manual/ja/function.get-headers.php
問題点
上記の関数でも、file_exists()でも、その他fopen()関数を内部的に使用するものは全て実行するPHP環境によってはうまく動作しない場合があります。PHPの初期設定ファイルであるphp.ini中で、allow_url_fopen=Offが設定されている場合は上記の関数は常にエラーとなりfalseを返してしまいます。そこでテストした結果、以下の方法であれば、php.iniのallow_url_fopenがOffでも正しく動作することがわかりました。
- function url_exists($url) {
- $errno = 0;
- $errstr = '';
- $timeout = 30;
- if (!$fid) return false;
- . $a_url['host'] . "\r\n\r\n");
- return $pos !== false;
- }
- }
- return false;
- }
ちなみに、この関数も以下のPHPマニュアルのget_headers()のページのユーザからの投稿記事中で見つけたものです。
http://jp.php.net/manual/ja/function.get-headers.php
また、参考までにですが、このPHPマニュアルのページに投稿されている以下のコードはホスト名のみでパスが付いていない場合はOKですが、それ以外は正しく動作しません。
- function url_exists3($url) {
- if($fp === false) return false;
- return true;
- }

