配置多语言支持
首先我们需要配置必要的文件,然后才能开始使用语言支持。 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 钩子构建一个快速有效的解决方案,为每个控制器自动加载语言文件。
将语言加载职责分配给 Hooks
CodeIgniter 在其执行过程中调用了一些内置的钩子。您可以在用户指南中找到完整的挂钩列表。我们将使用 post_controller_constructor 钩子,该钩子在我们的控制器被实例化之后并且在任何其他方法调用之前立即被调用。
我们通过在主config 文件中设置enable_hooks 参数来启用应用程序中的挂钩。
$config['enable_hooks'] = TRUE;
然后我们可以打开config目录下的hooks.php文件,创建一个自定义的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 访问语言库,因此我们需要使用get_instance() 函数获取CI 对象实例,然后像之前一样加载语言。现在,我们的应用程序的每个控制器都可以使用该语言文件,而无需在控制器中手动加载它。
在不同语言之间切换
一旦我们建立了对多种语言的支持,就可以向用户提供每种语言的链接,通常在我们的应用程序的一个菜单中,用户可以单击并切换语言。 session 或 cookie 值可用于跟踪活动语言。
让我们看看如何使用我们之前生成的 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>
每当用户选择特定语言时,LangSwitch 类的switchLanguage() 方法会将所选语言分配给session,并将用户重定向到主页。
现在活动语言将在会话中更改,但在我们加载活动语言的特定语言文件之前它不会受到影响。我们还需要修改我们的钩子类以从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