導入
Webアプリケーション開発において、商品名やユーザー名などを五十音順やアルファベット順に並び替える機能は必須です。しかし、PHPの標準関数である sort() をそのまま使用すると、ひらがなとカタカナが混在したり、アルファベットの大文字・小文字で優先順位が変わってしまったりと、ユーザーにとって直感とは異なる並び順になることがあります。本記事では、usort() 関数と文字変換関数を組み合わせ、ユーザーの期待に沿った「区別しないソート」を実現する方法を解説します。
基礎知識
PHPの sort() や asort() は、内部的には文字コードのバイト値に基づいて比較を行います。そのため、「ひらがな」と「カタカナ」は別々の文字コードとして扱われ、さらにアルファベットの大文字(ASCIIコード値が小さい)が小文字よりも優先されてしまいます。
これを解消するために使用するのが usort() です。usort() は「比較用関数(コールバック関数)」を引数に取ることで、開発者が独自の比較ルールを定義できる関数です。このコールバック内で、比較対象の文字列を正規化(統一)することで、意図した順序でのソートが可能になります。
実装/解決策
実装のポイントは以下の2点です。
1. 比較前に文字列を正規化する:mb_convert_kana() を使い、カタカナをひらがなに変換(あるいはその逆)することで、ひらがな・カタカナの区別をなくします。
2. 比較関数の選定:アルファベットの大文字・小文字を無視して比較するために、strcasecmp() を利用します。これにより、大文字と小文字が同一視されます。
サンプルプログラム
以下のコードは、ひらがな・カタカナ・アルファベットが混在した配列を、自然な順序でソートする実用的な例です。
apple
[1] => Banana
[2] => いちご
[3] => オレンジ
[4] => バナナ
[5] => ぶどう
[6] => りんご
/
?>
応用・注意点
1. パフォーマンスへの配慮:比較のたびに mb_convert_kana() などの変換処理を走らせるため、配列の要素数が非常に多い場合(数万件以上など)、処理速度が低下する可能性があります。その場合は、事前に「比較用のキー」を保持した配列を作成し、それをソートするなどの工夫が必要です。
2. ロケール設定:多言語対応が必要なシステムでは、setlocale() や Intl 拡張モジュールの Collator クラスの使用を検討してください。Collator を使うと、より高度な言語固有の辞書順ソートが可能になります。
3. 逆順ソート:逆順(Z→Aや「ん」→「あ」)にしたい場合は、比較関数の戻り値に -1 を掛けるだけで実現可能です。現場では「昇順・降順の切り替え」が頻繁に発生するため、このロジックを共通関数化しておくと保守性が向上します。