I'm following the method for translation specified here: http://framework.zend.com/manual/2.2/en/modules/zend.i18n.translating.html#setting-a-locale

Because most of my strings already existed in a DB and I didn't want to transfer them to POEdit, I'm generating a bunch of PHP Array files like en_US.php, de_DE.php, etc.

In module/Application/config/module.config.php the pattern is defined as:

        array(
            'type'     => 'phparray',
            'base_dir' => __DIR__ . '/../language',
            'pattern'  => '%s.php',
        ),

Setting the translator like this in module/Applicaation/Module.php:

   public function onBootstrap($e)
   {
    // ...snip...

   $sm = $e->getApplication()->getServiceManager();
   $sm->get('translator')
       ->setLocale(\Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']))
       ->setFallbackLocale('en_US');

    // ...snip...

}

And performing tranlations in the view like:

<th><?= $this->translate('Date Created'); ?></th>

Everything works except...Traditional and Simplified Chinese. If I'm reading the docs correctly zh_CN.php should be picked up for users with Simplified Chinese as their setting, and zh_HK should be picked up for users with Traditional Chinese. But it's not working. It only picks up zh.php and I lose my variations.

I'm on a Mac, so to test, I'm just changing my system preferences and relaunching my browser. All of my western languages (en_US.php, fr_FR.php, it_IT.php, nl_NL.php, etc) work as expected. But, for Japanese, I had to name my file ja.php, and I can't get Chinese to accommodate the different country codes.

Any ideas? How do I rule out if the problem is in my naming convention, an additional setting (is my pattern wrong) or do I need to pass more params when I call translate?

MORE INVESTIGATION Looking at what is being returned from the headers there is a difference:

 $locale = locale_accept_from_http($_SERVER['HTTP_ACCEPT_LANGUAGE']);
 var_dump($locale);

will print string(2) "zh" zh

var_dump($_SERVER['HTTP_ACCEPT_LANGUAGE']);

will print string(5) "zh-tw"

So perhaps I should be using the below, but it's absolutely not what's specified in the docs

        ->setLocale($_SERVER['HTTP_ACCEPT_LANGUAGE'])
有帮助吗?

解决方案

Why are you using Locale::acceptFromHttp()? You can write your own parser easily with the ZF2 request object.

$headers = $request->getHeaders();
if ($headers->has('Accept-Language')) {
    $locales = $headers->get('Accept-Language')->getPrioritized();
    $first   = array_shift($locales);

    // "language" here is the full locale, though it's quite confusing :s
    return $first->getLanguage();
}

There are others complaining about the magic of acceptFromHttp() and the apparent bugs in this part.

Mind that checking this code (as well as using acceptFromHttp() does not look for backup alternatives. Let's say your application defaults to 'fr-FR' and you support 'fr-FR' and 'en-US'. A client makes a request with Accept-Language 'nl-NL' and 'en-US'. Your code will check 'nl-NL', which is not supported, and uses the fallback 'fr-FR'. However, the second best option from the client ('en-US') is supported in your app. So you're sending back a locale which the client cannot understand, while you have in fact a negotiable locale available.

NB. You can use SlmLocale for ZF2 to detect locales automatically with a fallback and locale negotiation. The locale is set into php's Locale object with setDefault() so translators and the like pick up this locale automatically. Disclaimer I wrote that library :)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top