如何在CodeIgniter中切换语言

时间:2014-08-16 20:21:21

标签: codeigniter url multilingual

我设法使用两种语言的CodeIgniter创建网站,当我从那里直接切换URL时,URL工作正常:

localhost/projectname/en/index.php 

为:

localhost/projectname/it/index.php

现在我正在尝试创建两个小标记,单击这些标记会导致URL切换。我似乎找不到办法做到这一点,我已经尝试了很多。如果您对此有任何经验,请帮助我!

2 个答案:

答案 0 :(得分:5)

配置多语言支持

首先,我们需要在开始使用语言支持之前配置必要的文件。 CodeIgniter config文件位于application/config目录中,包含一个名为language的选项,用于定义应用程序的默认语言。

$config['language'] = 'english';

我们还需要创建包含不同语言消息的实际文件。这些文件需要放在application/language目录中,每个语言都有一个单独的目录。例如,English语言文件应位于application/language/english目录中,French语言文件应位于application/language/french

让我们创建一些包含示例应用程序错误消息的语言文件。创建文件english/message_lang.php(所有语言文件都必须具有后缀_lang.php)。以下代码包含我们语言文件内容的一些示例条目:

$lang["msg_first_name"] = "First Name";
$lang["msg_last_name"] = "Last Name";
$lang["msg_dob"] = "Date of Birth";
$lang["msg_address"] = "Address";

当然,您可以在单个语言目录中包含多个语言文件。建议根据消息的上下文和目的将消息分组到不同的文件中,并在消息密钥前添加特定于文件的关键字以保持一致性。

另一种方法是为每个控制器创建单独的消息文件。这种技术的优点是只加载了所需的消息而不是整个语言文件,这可能会产生一定程度的性能开销。

在控制器中加载语言文件

即使我们创建了语言文件,在我们将它们加载到控制器中之前它们也无效。以下代码显示了我们如何在控制器中加载文件:

class TestLanguage extends CI_Controller
{
    public function __construct() {
        parent::__construct();       
        $this->lang->load("message","english");
    }

    function index() {
        $data["language_msg"] = $this->lang->line("msg_hello_english");
        $this->load->view('language_view', $data);
    }
}

我们通常使用控制器和视图中的语言文件(使用模型中的语言文件并不是一件好事)。这里我们使用控制器的构造函数来加载语言文件,以便它可以在整个类中使用,然后我们在类“index()方法中引用它。”

lang->load()方法的第一个参数是没有_lang后缀的语言文件名。第二个参数是可选的,是语言目录。如果此处未提供默认语言,则会指向config中的默认语言。

我们可以使用lang->line()方法直接引用语言文件的条目,并将其返回给传递给视图模板的数据。在视图中,我们可以将上述语言消息用作$language_msg

我们可能还需要直接从视图中加载语言文件。例如,使用表单标签的语言项可能被认为是直接加载和访问视图内的消息的一个很好的理由。可以对视图内的这些文件使用与内部控制器相同的访问方法。

$this->lang->line("msg_hello_english");

虽然它完美无缺,但当我们的视图模板代码不是实际类时,$this可能会让人感到困惑。我们还可以在语言助手的支持下使用以下代码在视图中加载语言条目,这为我们提供了更清晰的代码。

lang("msg_view_english");

这基本上是您开始使用CodeIgniter语言文件时需要知道的全部内容。但即使这很简单,在每个控制器中加载必要的语言文件也是不必要和重复的工作,特别是如果你的项目包含数百个类。幸运的是,我们可以使用CodeIgniter钩子为每个控制器自动加载语言文件构建快速有效的解决方案。

指定语言加载对挂钩的责任

CodeIgniter调用一些内置钩子作为其执行过程的一部分。您可以在用户指南中找到完整的挂钩列表。我们将使用post_controller_constructor挂钩,它在我们的控制器被实例化之后立即调用,并且在任何其他方法调用之前。

我们通过在主enable_hooks文件中设置config参数来启用应用程序中的挂钩。

$config['enable_hooks'] = TRUE;

然后我们可以打开hooks.php目录中的config文件并创建自定义hook,如下面的代码所示:

$hook['post_controller_constructor'] = array(
    'class' => 'LanguageLoader',
    'function' => 'initialize',
    'filename' => 'LanguageLoader.php',
    'filepath' => 'hooks'
);

这定义了钩子并提供了执行它所需的信息。实际的实现将在application/hooks目录中的自定义类中创建。

class LanguageLoader
{
    function initialize() {
        $ci =& get_instance();
        $ci->load->helper('language');
        $ci->lang->load('message','english');
    }
}

在这里,我们无法使用$this->lang访问语言库,因此我们需要使用CI函数获取get_instance()对象实例,然后我们加载我们之前做的语言。现在语言文件将可用于我们应用程序的每个控制器,而无需在控制器内手动加载。

在不同语言之间切换

一旦我们建立了对多种语言的支持,就可以为用户提供每种语言的链接,通常在我们的应用程序菜单中,用户可以单击并切换语言。 sessioncookie值可用于跟踪活动语言。

让我们看看如何使用我们之前生成的hooks类来管理语言切换。首先,我们需要创建一个类来切换语言;我们将使用一个单独的控制器,如下所示:

class LangSwitch extends CI_Controller
{
    public function __construct() {
        parent::__construct();
        $this->load->helper('url');
    }

    function switchLanguage($language = "") {
        $language = ($language != "") ? $language : "english";
        $this->session->set_userdata('site_lang', $language);
        redirect(base_url());
    }
}

然后我们需要定义切换每种可用语言的链接。

<a href='<?php echo $base_url; ?>langswitch/switchLanguage/english'>English</a>
<a href='<?php echo $base_url; ?>langswitch/switchLanguage/french'>French</a>

每当用户选择特定语言时,switchLanguage()类的LangSwitch方法会将所选语言分配给session,并将用户重定向到主页。

现在,活动语言将在会话中更改,但在我们加载活动语言的特定语言文件之前,它仍然不会受到影响。我们还需要修改我们的hooks类,以便从session动态加载语言。

class LanguageLoader
{
    function initialize() {
        $ci =& get_instance();
        $ci->load->helper('language');

        $site_lang = $ci->session->userdata('site_lang');
        if ($site_lang) {
            $ci->lang->load('message',$ci->session->userdata('site_lang'));
        } else {
            $ci->lang->load('message','english');
        }
    }
}

LanguageLoader类中,我们获得了活动语言并加载了必要的语言文件,或者如果会话密钥不存在,我们会加载默认语言。我们可以在这个类中加载单个语言的多个语言文件。

从这里阅读更多内容Multi-Language Support in CodeIgniter

答案 1 :(得分:1)

您的多语言设置必须有更多信息,但SitePoint写了一个很好的教程,说明如何完全按照您的要求进行操作,但这又取决于您如何设置语言。

http://www.sitepoint.com/multi-language-support-in-codeigniter/

如果这没有帮助,有点看起来你已经将index.php分成了语言目录?如果是这种情况,您可以设置路线,这样当您单击英文标记时,它会设置会话变量以使用英文网站,并返回当前页面。

HTML:

<form method="POST" action="/change-lang">
  <input type="hidden" name="uri" value="<?= uri_string(); ?>" />
  <input type="image" src="/images/en-flag.jpg" name="lang" value="en" />
  <input type="image" src="/images/it-flag.jpg" name="lang" value="it />
</form>

<强>控制器:

<?php

// Other methods and __construct() here....

public function change-lang() {
  $uri = $this->input->post('uri');
  $lang = $this->input->post('lang');
  $_SESSION['lang'] = $lang;
  redirect($uri, 'refresh');
}

<强>配置/ config.php中

...

if(isset($_SESSION['lang'])) {
  $config['base_url']   = 'http://localhost/projectname/'.$_SESSION['lang'].'/';
} else {
  $config['base_url']   = 'http://localhost/projectname/en/';
}

...