PHP version for plural string output

    As usual for an international project, a function was needed to display the word in various variants of the plural form.
    The project already has its own option for loading languages, so using a standard gettext would change most of the code.

    So a function was written that, for a supported set of 27 languages, implements the necessary functionality.

    Her code is presented below.



    1. Requires the definition in the global array $ lang 6 key-value pairs such as: The number 6 is the maximum number of forms to all supported languages. The language with these 6 forms is Arabic. 2. The language is encoded by the first level domain for the corresponding country (yes, I know that it is correct to use the ISO language identifier).
    $lang['comment_form_0'] = 'комментарий';
    $lang['comment_form_1'] = 'комментария';
    $lang['comment_form_2'] = 'комментариев';
    $lang['comment_form_3'] = 'комментариев';
    $lang['comment_form_4'] = 'комментариев';
    $lang['comment_form_5'] = 'комментариев';
    ?>







    One of the obvious drawbacks is that there is no explicit binding of the form number to the number of elements,
    which requires an understanding of the algorithm from the translator.

    Well, the code itself:

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


    Porting to another language, I think, will be easy.

    But if the project allows, then I recommend, of course, use standard solutions - in PHP it is gettext.

    Also popular now: