PHPを使用してプログラムで有効な(デッドではない)リンクを確認するにはどうすればよいですか?
質問
URLのリストがある場合、各URLを確認します:
- 200 OKステータスコードを返します
- X時間以内に応答を返します
最終目標は、管理者がそれらを確認できるように、潜在的に破損しているとしてURLにフラグを立てることができるシステムです。
スクリプトはPHPで記述され、ほとんどの場合、cronを介して毎日実行されます。
スクリプトは、一度に約1000個のURLを処理します。
質問には2つの部分があります:
- このような操作を行う大きな問題はありますか、どの問題に遭遇しましたか?
- 正確さとパフォーマンスの両方を考慮して、PHPでURLのステータスを確認する最良の方法は何ですか?
解決
PHP cURL拡張機能を使用します。 fopen()とは異なり、URLの可用性をチェックするのに十分なHTTP HEADリクエストを作成し、チェックするためにページ全体をダウンロードする必要がないため、帯域幅を大幅に節約できます。
出発点として、次のような関数を使用できます。
function is_available($url, $timeout = 30) {
$ch = curl_init(); // get cURL handle
// set cURL options
$opts = array(CURLOPT_RETURNTRANSFER => true, // do not output to browser
CURLOPT_URL => $url, // set URL
CURLOPT_NOBODY => true, // do a HEAD request only
CURLOPT_TIMEOUT => $timeout); // set timeout
curl_setopt_array($ch, $opts);
curl_exec($ch); // do it!
$retval = curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200; // check if HTTP OK
curl_close($ch); // close handle
return $retval;
}
ただし、可能な最適化が多数あります。cURLインスタンスを再利用し、ホストごとに複数のURLをチェックする場合は、接続を再利用することもできます。
ああ、このコードはHTTP応答コード200を厳密にチェックします。リダイレクト(302)には従いませんが、そのためのcURLオプションもあります。
他のヒント
cURLを調べます。 PHP用のライブラリがあります。
cURLの実行可能バージョンもあるため、bashでスクリプトを作成することもできます。
実際には、PHPで5k + URLのデータベース上でこれを行う何かを書きました。 PEARクラス HTTP_Request を使用しました。 getResponseCode ()と呼ばれるメソッド。 URLを反復処理してgetResponseCodeに渡し、応答を評価します。
ただし、FTPアドレス、httpまたはhttpsで始まらないURL(未確認ですが、そうだと思います)、および無効なセキュリティ証明書を持つサイト(0は見つかりません)では機能しません。また、server-not-foundには0が返されます(そのためのステータスコードはありません)。
そして、いくつかのファイルを含めて単一の関数を使用して整数コードを取得するので、おそらくcURLよりも簡単です。
- fopen()はhttp URIをサポートしています。
- より高い柔軟性(タイムアウトなど)が必要な場合は、cURL拡張機能を調べてください。
カールの仕事のようです。
PHPにとらわれていなければ、PerlのLWPも答えかもしれません。
また、別のページにリダイレクトする301または302 HTTP応答を返すURLに注意する必要があります。通常、これはリンクが無効であることを意味しません。たとえば、 http://amazon.com は301を返し、 http://www.amazon.com/ 。
200の応答を返すだけでは不十分です。多くの有効なリンクは引き続き「200」を返します。元の所有者が更新に失敗したときにポルノ/ギャンブルのポータルに変更した後。
ドメイン不法占拠者は通常、ドメイン内のすべてのURLが200を返すようにします。
間違いなく遭遇する可能性のある問題の1つは、このスクリプトを実行しているボックスがインターネットへのアクセスを失うときです... 1000の誤検出が発生します。
おそらく、スクリプトが何らかのタイプの履歴を保持し、5日間の失敗後にのみ失敗を報告する方がよいでしょう。
また、標準のチェックを続行する前に、スクリプトは何らかの方法で自己チェックする必要があります(既知の適切なWebサイト[google?]をチェックするなど)。
これを行うには、bashスクリプトのみが必要です。同様の投稿で私の回答をこちらで確認してください。 HTTP接続を再利用して速度を劇的に改善し、一時的なエラーをn回再試行し、リダイレクトに従うワンライナーです。