はじめに
Webアプリケーションを多言語対応する際、単純な文字列の翻訳だけでは不十分な場合があります。特に困るのが「1個のアイテム」「2個のアイテム」といった数量に応じた複数形の処理です。
英語では単純に単数形・複数形の2種類ですが、言語によってはもっと複雑なルールがあります。そんな時に活躍するのが、PHPのngettext
関数です。
ngettext関数とは?
ngettext
はGNU gettextライブラリの一部で、数量に応じて適切な翻訳テキストを選択してくれる関数です。単なる文字列翻訳を行うgettext()
の進化版と考えると分かりやすいでしょう。
基本的な構文
string ngettext(string $msgid1, string $msgid2, int $n)
パラメータ説明:
$msgid1
: 単数形のメッセージID(通常は1個の場合)$msgid2
: 複数形のメッセージID(通常は2個以上の場合)$n
: 判定する数値
実際の使用例
基本的な使い方
<?php
// ロケールを設定
setlocale(LC_ALL, 'ja_JP.UTF-8');
bindtextdomain('messages', './locale');
textdomain('messages');
$count = 1;
echo ngettext(
'%d item found', // 単数形
'%d items found', // 複数形
$count
);
// 出力: "1 item found"
$count = 5;
echo sprintf(ngettext(
'%d item found',
'%d items found',
$count
), $count);
// 出力: "5 items found"
?>
実用的なショッピングカートの例
<?php
function displayCartItems($itemCount) {
$message = ngettext(
'あなたのカートには %d 個の商品があります',
'あなたのカートには %d 個の商品があります',
$itemCount
);
return sprintf($message, $itemCount);
}
echo displayCartItems(1); // "あなたのカートには 1 個の商品があります"
echo displayCartItems(10); // "あなたのカートには 10 個の商品があります"
?>
言語による複数形ルールの違い
英語の場合
- 1 = 単数形(”1 item”)
- 2以上 = 複数形(”2 items”, “10 items”)
ロシア語の場合
- 1 = 第1形式
- 2-4 = 第2形式
- 5以上 = 第3形式
日本語の場合
実は日本語には文法的な複数形がないため、多くの場合同じ形式を使用します。
.poファイルでの設定方法
翻訳ファイル(.po)では以下のように記述します:
# 英語版 (messages.po)
msgid "%d item found"
msgid_plural "%d items found"
msgstr[0] "%d item found"
msgstr[1] "%d items found"
# 日本語版 (ja/LC_MESSAGES/messages.po)
msgid "%d item found"
msgid_plural "%d items found"
msgstr[0] "%d個のアイテムが見つかりました"
よくあるトラブルシューティング
1. gettextエクステンションが無効
if (!function_exists('ngettext')) {
die('gettextエクステンションが必要です');
}
2. ロケールが正しく設定されていない
// 設定確認
echo setlocale(LC_ALL, 0); // 現在のロケールを確認
3. .moファイルが生成されていない
# .poファイルから.moファイルを生成
msgfmt messages.po -o messages.mo
パフォーマンスを考慮した実装
大量のテキスト処理が必要な場合は、キャッシュ機構を導入することをお勧めします:
class LocalizedTextCache {
private static $cache = [];
public static function ngettext($singular, $plural, $count) {
$key = md5($singular . $plural . $count);
if (!isset(self::$cache[$key])) {
self::$cache[$key] = ngettext($singular, $plural, $count);
}
return self::$cache[$key];
}
}
まとめ
ngettext
関数は、国際化対応のWebアプリケーション開発において非常に重要な役割を果たします。単純な文字列置換では対応できない、言語固有の複数形ルールを適切に処理できるのが最大の特徴です。
多言語対応を考えているPHP開発者の皆さんは、ぜひngettext
関数をマスターして、より自然で使いやすいアプリケーションを作成してみてください。