指定したURIだけではなく、リンクをたどってサイト全体からリンクしているURIのリストを取得してみます。具体的には前回の『PHPでリンクしているURIのリストを取得』で再帰処理を行います。
作ってみて分かりましたが、このスクリプトはあまり役に立ちません。
今回のスクリプトはHTTPリクエストを伴う処理を再帰的に行います。下手に改造すると自分のサーバだけでなく他のサーバにもサーバダウンなどの被害が及ぶことが有るので十分注意してください。また、改造しなくても元からバグが含まれている可能性もあります。
また、このスクリプトを自分が管理しているサイト以外のURIを指定して実行するべきではありません。いわゆる絨毯爆撃と見なされてアクセス拒否などをされる場合が有ります。
このスクリプトはそのまま使用してもスクリプトを実行するサーバ、指定したURIが示すサーバに大きな負荷をかけることがあります。
すべて自己責任で使用してください。
処理自体は再帰処理だけなので簡単です。やるべき事はどのURIに対して再帰処理を実行するかのみです。
// --------------------------!! 警告 !!-------------------------------
// このスクリプトを不用意に変更すると再帰処理が無限に行われ、プログラムが
// 実行されたサーバだけでなく、他のサーバまでダウンさせる可能性があります。
// 改造する時は必ずローカルサーバで外部サーバにリンクが張られていないHTMLフ
// ァイルを使用してテストを行い、無限ループが起きないか、外部サーバのファイ
// ルを取得しないかを確認してください。
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// array get_url_list_all( string URI )
// URIで指定されたHTMLファイルがリンクしているURIおよび、リンクされている
// URIが指定したURIと同階層以下ならそのファイルからリンクされているURIも返
// します。
// get_url_list()に関してはhttp://www.arielworks.net/articles/2003/1220bを参
// 照してください。
// -----------------------------------------------------------------------
function get_url_list_all( $target, $known = array() ) {
// ターゲットURIに含まれるURIのリストを取得
$list = get_uri_list( $target );
$list = array_unique( $list );
// 今のところ分かっているURIのリストを生成
$list_new = array_merge( $list, $known );
$list_new = array_unique( $list_new );
// 内容が未チェックのURIを選別
$unknown = array_diff( $list, $known );
$info_tgt = parse_url( $target );
$list_next = array();
// 未チェックのものが自サイト内のページかチェック。
// 現在の階層以上、他ホスト、自分自身は調査する権利を持たせない。
foreach( $unknown as $item ) {
$info_item = parse_url( $item );
if( $info_item['scheme'] == $info_tgt['scheme']
&& $info_item['host'] == $info_tgt['host']
&& $info_item['path'] != $info_tgt['path'] ) {
// dirname() はスラッシュで終わっているURIはスラッシュを除いて
// ファイル名とするのでダミーを付けておく
$dir_item = dirname( $info_item['path'] . "dummy" );
$dir_tgt = dirname( $info_tgt['path'] . "dummy" );
if( strpos(
str_replace( '\\', '/', $dir_item ),
str_replace( '\\', '/', $dir_tgt )
) === 0 ) {
array_push( $list_next, $item );
}
}
}
// 未チェックのURIを再帰処理で処理
foreach( $list_next as $next ) {
$list_new =
array_merge( $list_new, get_url_list_all( $next, $list_new ) );
$list_new = array_unique( $list_new );
}
return $list_new;
}
TOPページのURIを指定すればサイト内でリンクされているURIがすべてリストされる事になります。
サイトの規模によってはPHPのタイムアウト(デフォルトで30秒)になるかもしれません。というより、大抵なります。また、負荷もそれなりにかかるので、出来るだけローカルサーバで実行した方が良いでしょう。
作ってみて気が付いたのですが、タイムアウトのせいであまり役に立ちません。grepでも使ってローカルでリストを作った方が早い気がします。
くれぐれも慎重に使用してください。