[PHP]文章中の単語に自動でリンクを貼る(キーワードリンク)

Facebook にシェア
Delicious にシェア
LINEで送る
Pocket

よくコンピュータ系のサイトで専門用語に解説ページへのリンクが貼られているのを見かけますが、構造的には単語と URL を用意しておき、当てはまる単語にリンクを貼るというものです。

単純に組むとすでに置換した単語を二重に置換してしまうので、少し工夫が必要になります。

<?php
//元となる文章
$str = "ウェブブラウザとはウェブサイトを閲覧するためのソフトウェアです";
 
//単語とURLのリスト
$wordlist = array(
  "ウェブ" => "http://en.wikipedia.org/wiki/Web",
  "ウェブブラウザ" => "http://en.wikipedia.org/wiki/Web_browser",
  "ウェブサイト" => "http://en.wikipedia.org/wiki/Website",
  "ソフトウェア" => "http://en.wikipedia.org/wiki/Software"
);
 
//単語の文字数が長いものから順に並べ替える
uksort($wordlist, function($a, $b){
	return mb_strlen($b, 'utf-8') - mb_strlen($a, 'utf-8'); });

$pairs = array();

foreach($wordlist as $word => $url){
	$pairs[$word] = '<a href="' . $url . '">' . $word . '</a>';
}

$str = strtr($str, $pairs);
echo $str;

今回は「ウェブブラウザとはウェブサイトを閲覧するためのソフトウェアです」という文の用語にリンクをつけています。
単語は配列に $wordlist 登録し、キーが対象語句、値がリンク先です。

途中文字の長い順に単語を並び替えていますが、そうしておかないと「ウェブブラウザ」を置換するより先に「ウェブ」だけが置換され、「ブラウザ」の文字が取り残されてしまうからです。


(2014/05/07 加筆)

コメントで教えていただきましたが strtr は基本的にマルチバイト非対応の関数のため、文字コードによっては誤作動を起こす場合があるようです。
その場合は以下のマルチバイト対応版 mb_strtr() を使うことをおすすめします。

参考: 「マルチバイト未対応の関数をいろいろ対応させてみた」
http://qiita.com/mpyw/items/ceae0ed5285093c76087#2-7


Similar Posts:




  • This entry was posted in PHP and tagged , , . Bookmark the permalink.

    3 Responses to [PHP]文章中の単語に自動でリンクを貼る(キーワードリンク)

    1. CertaiN says:

      「単純に組むとすでに置換した単語を二重に置換してしまうので」
      とありますが、こういう場合はstr_replaceを使わずにstrtrを使うといいですよ。
      strtrではこのような心配が要りませんし、配列の作り方もstrtrの方が(私的には)好みです。
      ただstrtrもstr_replaceもそうなんですが、一応はマルチバイト非対応関数です。
      UTF-8を使っていれば基本的に心配は要りませんが、壊れたバイト列がきた場合に誤作動を起こします。
      こういう時に役立つのがpreg_replaceです。
      strtrをpreg_replace経由でマルチバイト対応させたのがこちらになります、ご参考にしていただければ幸いです。
      http://bloggdgd.blog28.fc2.com/blog-entry-265.html

    2. CertaiN says:

      すいませんコメント欄の表示乱れました・・・
      自分のブログに貼り直します。
      何回も申し訳ありません・・・

      http://bloggdgd.blog28.fc2.com/blog-entry-266.html

    3. PHP-Archive says:

      コメントありがとうございます。
      プレースホルダを使うやり方よりも直接的で見た目も綺麗ですね。
      文字コードに関する弱点も無いのでそちらのほうが良さそうです。

      自分のコードを見なおしてソート部分が冗長だったのでそちらの記事の方法を勝手ながら一部転用させていただきました。

    コメントを残す

    メールアドレスが公開されることはありません。