Table of Contents
URLを入力するだけで、そのページのタイトルを取ってきて、それにリンクを貼る方法です。
最近のWebサービスでは一般的になってきており、それを実現するためのライブラリも存在します。
今回はライブラリを使わず実装したかったので、やり方を調べてみました。
動作確認を行ったPHPのバージョンは7.0.xです。
cURLを使う方法
ページの内容をすべて取得してから、その中に含まれるtitleタグを正規表現で切り出します。切り出したタイトルをリンクタグ(a)で囲い、タイトル文字列をリンクとします。
ページ内容が取得できなかった場合は、そのままURL文字列にリンクを貼ります。
以上の手順を踏まえた関数のコードは以下に記します。URLを引数として受け取ると、そのページのタイトル文字列をリンクタグで囲ったタグを返します。
<?php function getPageTitleFromURL($url) { $curl = curl_init($url); if (!$curl) { // cURLが使えない場合はURLにリンクを貼る return '<a href="' . $url . '">' . htmlspecialchars($url) . '</a>'; } // HTMLソースを取得 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); $html = curl_exec($curl); curl_close($curl); if (preg_match("/<title>(.*?)<\/title>/i", $html, $matches)) { // タイトル文字列にリンクを貼る return '<a href="' . $url . '">' . $matches[1] . '</a>'; } // URLにリンクを貼る return '<a href="' . $url . '">' . htmlspecialchars($url) . '</a>'; } ?>
特に制約もなく使いやすい方法ですが、リンク先のページ内容をすべて読み込むため、動作速度が若干遅いのが欠点です。
この方法で、自分のTwitterページ(https://twitter.com/JoyPlot_2016)のタイトルを取得してリンクを貼った場合、どの程度時間がかかるか調べてみました。
10回表示させたときの、一回あたりの時間と全体の合計時間を画面に出力しています。
最も遅かった時
10回で19秒程度かかっています。
最も早かった時
早い場合は1回あたり1.2秒程度でした。
時間計測のPHPコード
上記のプログラムをループで10回実行した時の1回ごとの時間と、それらの合計時間を出力します。
<?php $total = 0; for ($i = 0; $i < 10; $i++) { $start = microtime(true); echo '<p>' . getPageTitleFromURL("https://twitter.com/JoyPlot_2016") . '</p>'; $end = microtime(true); $diff = $end - $start; echo "<time>$diff</time>"; $total += $diff; } echo "<p><strong>$total</strong></p>"; ?>
fopenを使う方法
読み込み時間を早くしたい場合は、ページ全体を読み込まずにタイトルタグの中身を取得できればいいですね。
fopen でページを読み込み、fgets を使ってタイトルタグが見つかるまで1行ずつ探して、見つかったら処理を中断すればページをすべて読み込まずに済みます。
HTML5の仕様上、head内にtitleタグがない場合はありえないと思いますが、一応titleタグが見つからなかった場合は、headタグの閉じタグ以降は読み込まないで処理を終了するようにしています。
<?php function getPageTitleFromURL($url) { if ($file = fopen($url, 'r')) { while (!feof($file)) { $line = fgets($file); if (preg_match("/<title>(.*?)<\/title>/i", $line, $matches)) { // タイトル文字列にリンクを貼る return '<a href="' . $url . '">' . $matches[1] . '</a>'; } if (preg_match("/<\/head>/i", $line)) { // headタグ内にタイトルタグが見つからなかったらループ終了 break; } } } // URLにリンクを貼る return '<a href="' . $url . '">' . htmlspecialchars($url) . '</a>'; } ?>
先ほどと同じように実行速度を測ってみます。
最も遅かった時
一番遅い時でも10回で10秒以下に収まっています。
最も早かった時
約8秒でした。
速度は速くなりましたが、1つ注意しなければならないことがあります。
この方法を使う場合、サーバ側のPHP設定で allow_url_fopen が ON になっている必要があります。このフラグが有効でなかった場合以下のような警告が出ます。
fopen(): http:// wrapper is disabled in the server configuration by allow_url_fopen=0 in ~.php on line ~ allow_url_fopenが無効になっている場合、fopenでURL等をファイルとして読み込むことができないため、fopenは使えません。
allow_url_fopen は .htaccess などでも変更できないため、サーバ側の元の設定を変更する権限がない場合、変更できないということが起きます。
以上、2つの方法を紹介しましたが、どちらにも良い点と悪い点があるため、状況に応じて使い分けると良いと思います。
面倒くさがらず高性能なライブラリを使うという方法もあると思います。