Pull to refresh

Вариант PHP кода для вывода строки в множественном числе

Reading time9 min
Views853
Как обычно для интернационального проекта понадобилась функция для вывода слова в различных вариантах множественной формы.
Проект уже имеет собственный вариант загрузки языков, так что использование стандартного gettext привело бы к изменению большой части кода.

Так что была написана функция, которая для поддерживаемого набора из 27 языков реализовывала необходимый функционал.

Её код представлен ниже.



1. Требует определения в глобальном массиве $lang 6 пар ключ-значения типа:
<?php
$lang['comment_form_0'] = 'комментарий';
$lang['comment_form_1'] = 'комментария';
$lang['comment_form_2'] = 'комментариев';
$lang['comment_form_3'] = 'комментариев';
$lang['comment_form_4'] = 'комментариев';
$lang['comment_form_5'] = 'комментариев';
?>


Цифра 6 является максимумом количества форм среди всех поддерживаемых языков.
Язык с этими 6 формами — арабский.

2. Язык кодируется доменом первого уровня для соответствующей страны (да, я знаю, что правильно использовать ISO идентификатор языка).

Один из явных минусов — нет явной привязки номера формы к количеству элементов,
что требует понимания алгоритма от переводчика.

Ну и сам код:

Copy Source | Copy HTML<br/><?php<br/>/**<br/> * get localized text by key in multi variant cases.<br/> * Attention: Lang ID is first-level domain for country but not ISo lang identificator!<br/> *<br/> * @param string $key - base part of key<br/> * @param int $n - number of items <br/>     ( special case == 0 -- it means that text will be fetched simply by $key)<br/> * @param string|null - lang ID which will be used for plural form check<br/> *<br/> * @return string - localized text<br/> */<br/>function get_lang( $key, $n = null, $lang_id = null ) {<br/> <br/>        global $lang;<br/>        if ( null === $n ) {<br/>                return $lang[ $key ];<br/>        }<br/> <br/>        $key_postfix = '_form_';<br/> <br/>        switch ( $lang_id ) {<br/> <br/>                case 'ar': // arabic, nplurals=6<br/>                        $s = $key_postfix.( ($n==0) ? '0' : ( ($n==1) ? 1 : ( ($n==2) ? 2 : ( ( ($n % 100 >= 3) && ($n % 100 <= 10) ) ? '3' : ( ( ($n % 100 >= 11) && ($n % 100 <= 99) ) ? '4' : '5' ) ) ) ) );<br/>                        $localized = $lang[ $key.$s ];<br/>                break;<br/> <br/>                case 'cz': // czech, nplurals=3<br/>                        $s = $key_postfix.( ($n==1) ? '0' : ($n>=2 && $n<=4) ? '1' : '2' );<br/>                        $localized = $lang[ $key.$s ];<br/>                break;<br/> <br/>                case 'de': // german <br/>                case 'bg': // bulgarian<br/>                case 'gr': // greek<br/>                case 'en': // english <br/>                case 'es': // espanol<br/>                case 'ee': // estonian<br/>                case 'il': // hebrew<br/>                case 'it': // italian<br/>                case 'mn': // mongolian<br/>                case 'nl': // dutch<br/>                case 'sq': // albainian<br/>                case 'my': // malay<br/>                        // nplurals=2;<br/>                        $s = $key_postfix.( ($n != 1) ? '0' : '1' );<br/>                        $localized = $lang[ $key.$s ];<br/>                break;<br/> <br/>                case 'pl': // polskiy, nplurals=3<br/>                        $s = $key_postfix.( ($n==1) ? '0' : ( ($n%10>=2) && ($n%10<=4) && ($n%100<10 || $n%100>=20) ) ? '1' : '2' );<br/>                        $localized = $lang[ $key.$s ];<br/>                break;<br/> <br/>                case 'ru': // russian, nplurals=3<br/>                        $s = $key_postfix.( (($n%10==1) && ($n%100!=11)) ? '0' : (( ($n%10>=2) && ($n%10<=4) && ($n%100<10 || $n%100>=20)) ? '1' : '2' ) );<br/>                        $localized = $lang[ $key.$s ];<br/>                break;<br/> <br/>                case 'sk': //    Slovak, nplurals=3<br/>                        $s = $key_postfix.( ($n==1) ? '1' : ( ($n>=2 && $n<=4) ? '2' : '0' ) );<br/>                        $localized = $lang[ $key.$s ];<br/>                break;<br/> <br/>                case 'fa': // farsi <br/>                case 'ja': // japan<br/>                case 'tr': // turkish<br/>                case 'vn': // vietnamese <br/>                case 'cn': // chinese +<br/>                case 'tw': // tradional Chinese (?)<br/>                case 'kz': // Kazakh<br/>                        // nplurals=1<br/>                        $s = $key_postfix.'0';<br/>                        $localized = $lang[ $key.$s ];<br/>                break;<br/> <br/>                case 'ua': // ukrainian, nplurals=3<br/>                        $s = $key_postfix.( ($n%10==1 && $n%100!=11) ? '0' : ( $n%10>=2 && $n%10<=4 && ($n%100<10 || $n%100>=20) ) ? '1' : '2' );<br/>                        $localized = $lang[ $key.$s ];<br/>                break;<br/> <br/>                case 'lt': // Lithuanian, nplurals=3<br/>                        $s = $key_postfix.( ($n%10==1 && $n%100!=11) ? '0' : ( $n%10>=2 && ($n%100<10 || $n%100>=20) ) ? '1' : '2' );<br/>                        $localized = $lang[ $key.$s ];<br/>                break;<br/> <br/>                case 'fr': // french, nplurals=2<br/>                        $s = $key_postfix.( $n > 1 ? '0' : '1' );<br/>                        $localized = $lang[ $key.$s ];<br/>                break;<br/>        }<br/> <br/>        return $localized;<br/>}<br/>?> <br/>


Портировать на другой язык, думаю, будет несложно.

Но если проект позволяет, то рекомендую, конечно, использовать стандартные решения — в PHP им является gettext.
Tags:
Hubs:
-1
Comments20

Articles