どうも、コウイチです。

今回は、テキストボックスに文字列を入力すると、対象の文章にヒットした部分をハイライト(強調表示)させる機能を、PHPで実装してみたいと思います。

ヒットした文字列を黄色い蛍光ペンで塗ってみます。

作りたい機能

以下の機能を作ります。

検索画面

検索画面です。検索窓にキーワードを入力して、エンターか検索ボタンをクリックすると、下のサンプル文章に対して検索をかけ、ヒットしたらその部分を黄色くハイライトさせる。

それだけではつまらないので、あいまい検索を可能にしてみた

あいまい検索も可能にしてみました。

ただ検索するだけではなくて、多少のあいまいな検索にもヒットするように。

たとえば、

ひらがなでもカタカナでも、半角でも全角でも、大文字でも小文字でも、違いを無視してヒットさせるようにしました。

変換をミスったりするユーザーもいますし、半角全角の違いでヒットしないとなると結構不便です。

Google先生のような超高性能な「もしかして」機能は難しいですが、素人でも簡単なコードである程度はやれます。

ソースコードと解説

それでは完成形のサンプルコードをどうぞ。解説付きです。

作るファイルは、

  • index.php(メインファイル)
  • lib.php(ライブラリファイル)

の2つです。

index.php

メインのPHPです。

解説

まず、「検索される文字列」を変数に準備します。長いのでヒアドキュメントを使用してます。

 

「検索する文字列」をPOSTで受信します。

 

lib.phpに定義(あとでやります)してある検索処理(search_highlight関数)にかけます。

これは、「検索する文字列」が見つかったら、「検索される文字列」のその部分をハイライトするHTMLタグを追加したものを返し、見つからなければ「検索される文字列」をそのまま返す関数です(のちほど作ります)

 

検索窓を作ります。エンターキーまたは、検索ボタンをクリックすると、自分自身のページへ入力された文字列をPOST送信するように、フォームを作ってます。

 

検索したキーワードを表示します。

 

ハイライト後のサンプル文章を表示します。

lib.php

ライブラリファイルです。

あいまい検索用の変換処理の関数(search_henkan)と、それを使用して検索し、ハイライトする関数(search_highlight)を定義します。

search_henkan関数の解説

あいまい検索の処理の解説です。仕組みは単純なものです。

「検索する文字列」と、「検索される文字列」について、それぞれあいまい検索用の変換をかけます。

具体的には、以下の3つの変換を行います。

  1. 「全角カタカナ」は「全角ひらがな」に変換
  2. 「全角」英数字は「半角」に変換
  3. 「大文字」は「小文字」に変換

こうした上で、「検索される文字列(変換後)」から、「検索する文字列(変換後)」を検索すれば、半角全角等の違いを無視してヒットさせることができます。

具体的に見ていきましょう。

あいまい検索用の変換にかけずに検索する場合
検索する文字列
(変換前)
検索する文字列
(変換後)
検索される文字列
(変換前)
検索される文字列
(変換後)
検索結果
プログラミング中毒者 衣食住よりプログラミング
~プログラミング中毒者の本音~
衣食住よりプログラミング
プログラミング中毒者の本音~

変換ミスなく検索した場合は、問題なくヒットする。

 

検索する文字列
(変換前)
検索する文字列
(変換後)
検索される文字列
(変換前)
検索される文字列
(変換後)
検索結果
プログラみんぐ中毒者 衣食住よりプログラミング
~プログラミング中毒者の本音~
 衣食住よりプログラミング
~プログラミング中毒者の本音~

検索する文字列に変換ミスがあるので、ヒットしない。

あいまい検索用の変換にかけて検索する場合
検索する文字列
(変換前)
検索する文字列
(変換後)
検索される文字列
(変換前)
検索される文字列
(変換後)
検索結果
プログラみんぐ中毒者 ぷろぐらみんぐ中毒者 衣食住よりプログラミング
~プログラミング中毒者の本音~
衣食住よりぷろぐらみんぐ
~ぷろぐらみんぐ中毒者の本音~
衣食住よりプログラミング
プログラミング中毒者の本音~

検索する文字列に変換ミスがあるが、検索用の変換処理をかけているため問題なくヒットする。

 

これが、今説明した、あいまい検索用の変換処理のコードです。

だいたいイメージは沸きましたでしょうか。

search_highlight関数の解説

それでは次に、search_highlight関数の解説です。

検索する文字列が見つかったら、検索される文字列のその部分をハイライトするHTMLタグを追加したものを返し、見つからなければ検索される文字列をそのまま返す関数です。

 

まず、mb_strpos関数を使って、「検索される文字列(変換後)」から「検索する文字列(変換後)」を探し、見つかるかを判定します。

この関数は、「文字列の中に指定した文字列が最初に現れる位置を見つける」関数です。

公式ドキュメントをチェック

見つかるとFALSE以外が返されるので、FALSE以外が帰ってきたらヒットしたと判定しています。

ヒットすると$posに、最初にヒットした位置が格納されます。

 

検索してヒットしたことがわかったら、「検索される文字列(変換前)」のヒットした箇所をハイライトしたいので、「検索される文字列(変換前)」について、$pos~「検索する文字列」の文字数分だけ取り出します。

ここで取りだしたものが、のちにハイライトするべき文字列となります。

mb_substr関数は、文字列の一部を切り出す関数です。⇒ 公式ドキュメントをチェック

mb_strlen関数は、文字列が何文字かを取得する関数です。⇒ 公式ドキュメントをチェック

 

「検索される文字列(変換前)」に対して、ハイライトするべき文字列を、ハイライトタグ付きのものに置換し、それを返却すれば完了です。

実行結果

それでは実行してみましょう。

まずは初期状態の画面です。

検索キーワードの入力ボックスに、適当な文字列を入力して、エンターを押してみます。

 

ひらがなとカタカナを間違わずに、検索してみました。見事ヒットして、ハイライトされていますね。

 

今度は、わざとひらがなとカタカナをあべこべにして検索してみました。しかしちゃんとヒットして、ハイライトされています。

これが、あいまい検索のなせる業です。

最後に

今回は簡略化と、検索機能がメインの解説なのでデータベースは使ってません。

検索される対象の文章をデータベースから引っ張ってくることができると、
かなり実用的になるかと思います。

是非試してみてください。

それでは、ありがとうございました。