あるテーブルの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です。(文字コードの違いによる問題でしょうか?)
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 で設定。
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
日本語版が見当たらない・・・。
※以上で解決すれば良いのですが・・・
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 関数を使っていれば文字コードの違いによる問題はほとんど防げます。
回答ありがとうございます。
大文字小文字の影響というよりは、明らかにキーワードが含まれていない結果が返ってきてしまうんですよね。
例えば、「A」(全角大文字)で検索すると、「A」が含まれていないデータが多数見つかります。
mysql_set_charsetは「注意: この関数は、MySQL 5.0.7 以降でないと使用できません。」のようですね。
文字コードの違いによる問題だろ。
対策:MySQLのバージョンアップ
回答ありがとうございます。
レンタルサーバーのため、MySQLのバージョンは変更できません。
他に対応策は無いものでしょうか?
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 で設定。
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
日本語版が見当たらない・・・。
※以上で解決すれば良いのですが・・・
色々とありがとうございます。
上記の方法を試したのですが、残念ながら上手くいきませんでした。
その後、他のサイト等の情報を参考に、
「select * from TABLE where NAME REGEXP '$keyword' or KANA REGEXP '$keyword'」
に修正したところ、希望通りの結果を得られるようになりました。
ありがとうございました。
色々とありがとうございます。
上記の方法を試したのですが、残念ながら上手くいきませんでした。
その後、他のサイト等の情報を参考に、
「select * from TABLE where NAME REGEXP '$keyword' or KANA REGEXP '$keyword'」
に修正したところ、希望通りの結果を得られるようになりました。
ありがとうございました。