PHPのMysqlで五十音検索、五十音順のバグを解決。全角のひらがな、カタカナではなく、半角カナをDBに格納するのが正解だった
2023-05-13 732 1801PHPで社内システムを構築する案件をいただいている中で、ある日「五十音順がうまく機能していない」というエラーの報告が。しかし、コードには全然誤りがなく、google先生に粘り強く聞いてみたところ、半角カナでREGEXPやった方がよいという、かなりレアな情報に辿り着きました。無事に解決
mysqlテーブルのフィールドの一つに、並び替え用に半角カナで値を保存するようにしてあることが前提です。フリガナはひらがなで保存しておくのが好きだったのですが、半角カナが意外と優秀だったようです。
<五十音別の表示に成功したコード>
<?php
function makeGojuonQery($q){
switch($q){
case 1: $where = " AND `sort_kana` REGEXP '^(ア|イ|ウ|エ|オ|ァ|ィ|ゥ|ェ|ォ)+' "; break;
case 2: $where = " AND `sort_kana` REGEXP '^(カ|キ|ク|ケ|コ|ガ|ギ|グ|ゲ|ゴ)+' "; break;
case 3: $where = " AND `sort_kana` REGEXP '^(サ|シ|ス|セ|ソ|ザ|ジ|ズ|ゼ|ゾ)+' "; break;
case 4: $where = " AND `sort_kana` REGEXP '^(タ|チ|ツ|テ|ト|ダ|ヂ|ヅ|デ|ド)+' "; break;
case 5: $where = " AND `sort_kana` REGEXP '^(ナ|ニ|ヌ|ネ|ノ)+' "; break;
case 6: $where = " AND `sort_kana` REGEXP '^(ハ|ヒ|フ|ヘ|ホ|バ|ビ|ブ|ベ|ボ|パ|ピ|プ|ペ|ポ)+' "; break;
case 7: $where = " AND `sort_kana` REGEXP '^(マ|ミ|ム|メ|モ)+' "; break;
case 8: $where = " AND `sort_kana` REGEXP '^(ヤ|ユ|ヨ)+' "; break;
case 9: $where = " AND `sort_kana` REGEXP '^(ラ|リ|ル|レ|ロ)+' "; break;
case 10: $where = " AND `sort_kana` REGEXP '^(ワ|ヲ|ン)+' "; break;
default: $where = "";
}
return $where;
}
$q = $_GET['q'];
if($q) $where = makeGojuonQery($q);
$rst = $mysqli->query("SELECT * FROM `xxx` WHERE `flag` = 1 {$where} ORDER BY `sort_kana` ASC");
while($row = $rst->fetch_assoc()){
//処理
}
?>
元々は下記のコードでしたが、正しい五十音の検索にならなかった。
どうやら「REGEXP」は日本語があまり得意でないようで、半角カナをキーにすることで正しい五十音別の表示が可能になりました。
<五十音別の表示失敗したコード>
<?php
switch($q){
case 1: $where = " AND `kana` REGEXP '^(あ|い|う|え|お|ア|イ|ウ|エ|オ|ぁ|ぃ|ぅ|ぇ|ぉ|ァ|ィ|ゥ|ェ|ォ)+' "; break;
case 2: $where = " AND `kana` REGEXP '^(か|き|く|け|こ|カ|キ|ク|ケ|コ|が|ぎ|ぐ|げ|ご|ガ|ギ|グ|ゲ|ゴ)+' "; break;
case 3: $where = " AND `kana` REGEXP '^(さ|し|す|せ|そ|サ|シ|ス|セ|ソ|ざ|じ|ず|ぜ|ぞ|ザ|ジ|ズ|ゼ|ゾ)+' "; break;
case 4: $where = " AND `kana` REGEXP '^(た|ち|つ|て|と|タ|チ|ツ|テ|ト|だ|ぢ|づ|で|ど|ダ|ヂ|ヅ|デ|ド)+' "; break;
case 5: $where = " AND `kana` REGEXP '^(な|に|ぬ|ね|の|ナ|ニ|ヌ|ネ|ノ)+' "; break;
case 6: $where = " AND `kana` REGEXP '^(は|ひ|ふ|へ|ほ|ハ|ヒ|フ|ヘ|ホ|ば|び|ぶ|べ|ぼ|バ|ビ|ブ|ベ|ボ|ぱ|ぴ|ぷ|ぺ|ぽ|パ|ピ|プ|ペ|ポ)+' "; break;
case 7: $where = " AND `kana` REGEXP '^(ま|み|む|め|も|マ|ミ|ム|メ|モ)+' "; break;
case 8: $where = " AND `kana` REGEXP '^(や|ゆ|よ|ヤ|ユ|ヨ)+' "; break;
case 9: $where = " AND `kana` REGEXP '^(ら|り|る|れ|ろ|ラ|リ|ル|レ|ロ)+' "; break;
case 10: $where = " AND `kana` REGEXP '^(わ|を|ん|ワ|ヲ|ン)+' "; break;
default: $where = "";
}
?>
- 関連タグ: