Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/243.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CakePHP如何在同一请求中更改_;()语言_Php_Cakephp_Localization_Internationalization_Gettext - Fatal编程技术网

CakePHP如何在同一请求中更改_;()语言

CakePHP如何在同一请求中更改_;()语言,php,cakephp,localization,internationalization,gettext,Php,Cakephp,Localization,Internationalization,Gettext,我使用的是CakePHP2.6.x 我的应用程序本地化为法语和英语。默认为英语 我的翻译文件当前如下所示: /app/Locale/eng/LC_MESSAGES/default.po /app/Locale/fra/LC_MESSAGES/default.po echo __("Foo"); 在我的视图中,我通常可以显示当前语言的本地化文本,如下所示: /app/Locale/eng/LC_MESSAGES/default.po /app/Locale/fra/LC_MESSAGES/de

我使用的是CakePHP2.6.x

我的应用程序本地化为法语和英语。默认为英语

我的翻译文件当前如下所示:

/app/Locale/eng/LC_MESSAGES/default.po
/app/Locale/fra/LC_MESSAGES/default.po
echo __("Foo");
在我的视图中,我通常可以显示当前语言的本地化文本,如下所示:

/app/Locale/eng/LC_MESSAGES/default.po
/app/Locale/fra/LC_MESSAGES/default.po
echo __("Foo");
但是,在一些情况下,我需要覆盖当前语言并返回特定语言的翻译。我的理解就是为了这个。但是,以下内容不适用于我:

echo __d("fra", "Foo");
[更正:
\uu d
不适用于此。]

这似乎总是返回当前语言的翻译。基本上,只需链接
\uuuu()

经过多次尝试和错误,我重新命名了French.PO文件

/app/Locale/fra/LC_MESSAGES/fra.po
…然后是
(“fra”、“Foo”)按预期工作。但是,
\uuu()
不再起作用了。更改文件名后,
的所有实例都以默认语言返回文本

我做错了什么?如何使
\uu d()
\uu()
同时工作?或者以另一种方式问同样的问题:如何在同一请求中更改
\uu()
使用的语言

更新

我的第一反应是尝试下面拉尔斯建议的东西。但由于某种原因,它不起作用。我正在电子邮件视图中执行以下操作:

    Configure::write("Config.language", "fra");
    $this->log(Configure::read("Config.language")); //'fra'
    $this->log( __("yes") ); //'yes'

请注意,配置语言设置正确。但是
忽略它,并且无论如何都会回显当前语言。(顺便说一句,我选中了,PO文件中有yes/oui)

您最好在通话前更改设置语言,稍后再更改:

$before = Configure::read('Config.language');
Configure::write('Config.language', 'fra');
echo __('Your String');
Configure::write('Config.language', $before);
您甚至可以将其放入函数中:

function __lang($string, $language) {
    $before = Configure::read('Config.language');
    Configure::write('Config.language', $language);
    echo __($string);
    Configure::write('Config.language', $before);
}
function __lang($string, $language) {
    echo I18N::translate($string, null, null, I18n::LC_MESSAGES, null, $language);
}
编辑 正如mdm在注释中所解释的,这基本上就是函数所做的

如果这个(和我的函数)不起作用,我猜你的翻译文件有问题。您是否尝试过在全球范围内切换到目标语言?那打印的字符串正确吗

要绕过所有配置和会话值,只需依赖I18N::translate函数:

function __lang($string, $language) {
    $before = Configure::read('Config.language');
    Configure::write('Config.language', $language);
    echo __($string);
    Configure::write('Config.language', $before);
}
function __lang($string, $language) {
    echo I18N::translate($string, null, null, I18n::LC_MESSAGES, null, $language);
}

根据@ndm的建议,我编写了一个用于在请求中间“切换”语言的小实用程序

以下是我如何使用它:

App::uses('L10nTool', 'Lib');
$L10n = new L10nTool();
$L10n->startToggleLg("fra");
...
//Bonjour, mon ami
...
$L10n->stopToggleLg();//Back to initial language
稍后,我可能会添加另一种方法,类似于Lars的答案,用于在单个方法中执行一个快速字符串。但是现在我正在用“切换”的语言做一些电子邮件逻辑,所以这样做对我来说比较容易

代码如下:

<?php
App::uses('AppHelper', 'View/Helper');
App::uses('CakeSession', 'Model/Datasource');

class L10nTool {

    public $start_lg;
    public $use_session = FALSE;

    public function startToggleLg($lg) {

        if (CakeSession::check("Config.language")) { 
            $this->start_lg = CakeSession::read("Config.language");
            $this->use_session = TRUE;
        } else {
            $this->start_lg = Configure::read("Config.language");
        }

        if ( $this->use_session ) {
            CakeSession::write("Config.language", $lg);
        } else {
            Configure::write("Config.language", $lg);
        }

    }

    public function stopToggleLg($lg = NULL) {

        $lg = ($lg) ? $lg : $this->start_lg;

        if ( $this->use_session ) {
            CakeSession::write("Config.language", $lg);
        } else {
            Configure::write("Config.language", $lg);
        }        

    }

}

可能的快速解决方法:在您的LC_MESSAGES目录中创建一个从default.po到fra.po的符号链接,例如
ln-s default.po fra.po
@marian0-Hmm。这种黑客可能会奏效,但我怀疑它将来会给我带来痛苦:-)。我真的需要找出我做错了什么导致蛋糕的l10n不能按预期工作。我不认为你想做的是可能的。
\uu d
函数不是用来覆盖语言的,它是用来在当前设置的语言中选择另一个语言文件的。恐怕不是。我想,您可以在执行
之前切换语言,然后再切换回来。选择此路线时,您希望实现什么?如果配置的语言没有被使用,尽管有正确的文件可用,请检查会话中是否设置了语言(
CakeSession::read('Config.language')
),这是通过
Configure
使用的,在对翻译进行更改后,请确保已清除缓存
tmp/cache/persistent
。也可以解释一下
I18N::translate()
(这里您可以显式地传递一种用于配置的语言)和
I18N::insertArgs()
,就像
()
方法在内部执行。@ndm这听起来正是我需要的。不是吗?@Lars你的解决办法我试过了,但没能奏效。我正在更新我的问题以显示问题…@ndm我不知道它们存在;)我将我的答案编辑为直接使用I18N类,这将忽略所有当前的语言设置。