PHP+MySQLで開発したシステムの検索機能に不具合があります。


あるテーブルの2つのフィールド(NAMEとKANA)から検索するために、以下のSQLを使用しています。

「select * from TABLE where NAME like '%$keyword%' or KANA like '%$keyword%'」

ほとんどの場合上手くいくのですが、キーワードが短い(1~2文字など)場合に、余計なデータが検索にかかってきてしまいます。原因と対処法をご存じの方、どうか教えて頂けないでしょうか。

※MySQLのバージョンは5.0.45、文字セットはUTF-8で、PHPスクリプト(.php)の文字コードはEUCです。(文字コードの違いによる問題でしょうか?)

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2009/07/06 22:48:19
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:kn1967 No.4

回答回数2915ベストアンサー獲得回数301

ポイント50pt

0)事前確認

検索キーワードはフォームから送られてくるものだと思いますが、

受け取ってからMySQLに投げるまでの間に文字化けしていないかを、

要所要所にechoを入れて出力させたりしてチェック。


1)php側で対処する方法。

1.MySQLに投げる直前にUTF-8にエンコードして試してみる。

   ↓

2.その php の内部エンコーディングをUTF-8に変えてみる。

PHP: mb_internal_encoding - Manual

PHP: mb_regex_encoding - Manual

   ↓

3.全てのphpで同様の動作を行わせたいならば php.ini で設定。

PHP: 実行時設定 - Manual


2)MySQL側で対処する方法。

MySQLのクライアント側キャラクタセット設定をEUC-JP にセットする。

  default-character-set

もしくは、MySQL側での変換は行わせないようにする。

  skip-character-set-client-handshake

MySQL :: MySQL 5.0 Reference Manual :: 5.1.2 Server Command Options

日本語版が見当たらない・・・。


※以上で解決すれば良いのですが・・・

id:dy7

色々とありがとうございます。

上記の方法を試したのですが、残念ながら上手くいきませんでした。

その後、他のサイト等の情報を参考に、

「select * from TABLE where NAME REGEXP '$keyword' or KANA REGEXP '$keyword'」

に修正したところ、希望通りの結果を得られるようになりました。

ありがとうございました。

2009/07/06 22:45:45

その他の回答3件)

id:b-wind No.1

回答回数3344ベストアンサー獲得回数440

ポイント30pt

MySQL :: MySQL 5.1 リファレンスマニュアル :: 11.3.1 文字列比較関数

よくあるケースとしては、MySQL 標準では文字列比較に大文字小文字を考慮しないことにあります。


次のふたつのステートメントは、オペランドのひとつがバイナリ ストリングでない限り、文字列比較は大文字小文字の区別をしないことを示しています :

mysql> SELECT 'abc' LIKE 'ABC';

-> 1

mysql> SELECT 'abc' LIKE BINARY 'ABC';

-> 0

文字コードの違いによる問題でしょうか?

PHP: mysql_set_charset - Manual

今回の例とは関係ないとは思いますが、適切に mysql_set_charset 関数を使っていれば文字コードの違いによる問題はほとんど防げます。

id:dy7

回答ありがとうございます。

大文字小文字の影響というよりは、明らかにキーワードが含まれていない結果が返ってきてしまうんですよね。

例えば、「A」(全角大文字)で検索すると、「A」が含まれていないデータが多数見つかります。

mysql_set_charsetは「注意: この関数は、MySQL 5.0.7 以降でないと使用できません。」のようですね。

2009/07/03 22:07:05
id:kn1967a No.2

回答回数356ベストアンサー獲得回数7

ポイント5pt

文字コードの違いによる問題だろ。

対策:MySQLのバージョンアップ

id:dy7

回答ありがとうございます。

レンタルサーバーのため、MySQLのバージョンは変更できません。

他に対応策は無いものでしょうか?

2009/07/04 00:00:15
id:kn1967a No.3

回答回数356ベストアンサー獲得回数7

ポイント5pt

それなら、スクリプトをUTF-8で書けばいい。

SQLをmb_convert_encodingで変換するだけで十分という話もあるが。

id:kn1967 No.4

回答回数2915ベストアンサー獲得回数301ここでベストアンサー

ポイント50pt

0)事前確認

検索キーワードはフォームから送られてくるものだと思いますが、

受け取ってからMySQLに投げるまでの間に文字化けしていないかを、

要所要所にechoを入れて出力させたりしてチェック。


1)php側で対処する方法。

1.MySQLに投げる直前にUTF-8にエンコードして試してみる。

   ↓

2.その php の内部エンコーディングをUTF-8に変えてみる。

PHP: mb_internal_encoding - Manual

PHP: mb_regex_encoding - Manual

   ↓

3.全てのphpで同様の動作を行わせたいならば php.ini で設定。

PHP: 実行時設定 - Manual


2)MySQL側で対処する方法。

MySQLのクライアント側キャラクタセット設定をEUC-JP にセットする。

  default-character-set

もしくは、MySQL側での変換は行わせないようにする。

  skip-character-set-client-handshake

MySQL :: MySQL 5.0 Reference Manual :: 5.1.2 Server Command Options

日本語版が見当たらない・・・。


※以上で解決すれば良いのですが・・・

id:dy7

色々とありがとうございます。

上記の方法を試したのですが、残念ながら上手くいきませんでした。

その後、他のサイト等の情報を参考に、

「select * from TABLE where NAME REGEXP '$keyword' or KANA REGEXP '$keyword'」

に修正したところ、希望通りの結果を得られるようになりました。

ありがとうございました。

2009/07/06 22:45:45
  • id:b-wind
    >例えば、「A」(全角大文字)で検索すると、「A」が含まれていないデータが多数見つかります。
    client_charset を binary にして接続しているとバイナリ列として扱うので、そういうことも多々起こる。

    もう少し設定等を明示してもらわないと明言は出来無いが。
  • id:dy7
    コメントありがとうございます。

    >client_charset を binary にして接続しているとバイナリ列として扱うので、そういうことも多々起こる。

    mysql_connectの後に、binaryで接続しないための手順を踏まなければならないという事でしょうか?

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません