多语言支持,也称为国际化,是现代 Web 应用程序的一个关键特性。大多数全栈 PHP 框架都提供多语言支持,这使我们能够以不同的语言动态呈现应用程序的界面,而无需复制每种语言的现有源代码。今天我们将讨论如何使用 CodeIgniter 启用多种语言,以及一些自定义核心功能的技巧。
配置多语言支持
首先,我们需要配置必要的文件,然后才能开始使用语言支持。位于 application/config 目录中的 CodeIgniter 配置文件包含一个名为 language 的选项,它定义了应用程序的默认语言。
<?php
$config['language'] = 'english';
我们还需要创建包含不同语言消息的实际文件。这些文件需要放在应用程序/语言目录中,每种语言都有一个单独的目录。例如,英语文件应位于 application/language/english 目录中,法语文件应位于 application/language/french 中。
让我们为示例应用程序创建一些包含错误消息的语言文件。创建文件english/message_lang.php(重要的是所有语言文件都具有后缀_lang.php)。以下代码包含我们语言文件内容的一些示例条目:
<?php
$lang["msg_first_name"] = "First Name";
$lang["msg_last_name"] = "Last Name";
$lang["msg_dob"] = "Date of Birth";
$lang["msg_address"] = "Address";
当然,您可以在一个语言目录中拥有多个语言文件。建议根据上下文和目的将消息分组到不同的文件中,并在消息键前面加上文件特定的关键字以保持一致性。
另一种方法是为每个控制器创建单独的消息文件。这种技术的优点是只加载所需的消息而不是整个语言文件,这会产生一定程度的性能开销。
加载语言文件
即使我们创建了语言文件,但在我们将它们加载到控制器中之前它们是无效的。以下代码显示了我们如何在控制器中加载文件:
<?php
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 后缀的语言文件名。第二个参数是可选的,是语言目录。如果此处未提供,它将指向您配置中的默认语言。
我们可以使用 lang->line() 方法直接引用语言文件的条目,并将其分配给传递给视图模板的数据。在视图内部,我们可以使用上述语言消息作为 $language_msg。
有时我们也需要直接从视图中加载语言文件。例如,将语言项用于表单标签可能被认为是直接加载和访问视图内消息的一个很好的理由。可以在视图内对这些文件使用与控制器内相同的访问方法。
<?php
$this->lang->line("msg_hello_english");
虽然它工作得很好,但是当我们的视图模板代码不是一个实际的类时,使用 $this 可能会令人困惑。我们还可以在语言助手的支持下使用以下代码在视图中加载语言条目,这为我们提供了更简洁的代码。
<?php
lang("msg_view_english");
这基本上是您开始使用 CodeIgniter 语言文件所需要知道的全部内容。但是即使这很简单,在每个控制器中加载必要的语言文件也是不必要的和重复的工作,特别是如果您的项目包含数百个类。幸运的是,我们可以使用 CodeIgniter 钩子构建一个快速有效的解决方案,为每个控制器自动加载语言文件。
将语言加载职责分配给 Hooks
CodeIgniter 在其执行过程中调用了一些内置的钩子。您可以在用户指南中找到完整的挂钩列表。我们将使用 post_controller_constructor 钩子,它在我们的控制器被实例化之后并且在任何其他方法调用之前立即被调用。
我们通过在主配置文件中设置 enable_hooks 参数在我们的应用程序中启用钩子。
<?php
$config['enable_hooks'] = TRUE;
然后我们可以打开 config 目录中的 hooks.php 文件并创建一个自定义的钩子,如下代码所示:
<?php
$hook['post_controller_constructor'] = array(
'class' => 'LanguageLoader',
'function' => 'initialize',
'filename' => 'LanguageLoader.php',
'filepath' => 'hooks'
);
这定义了钩子并提供了执行它的必要信息。实际实现将在 application/hooks 目录中的自定义类中创建。
<?php
class LanguageLoader
{
function initialize() {
$ci =& get_instance();
$ci->load->helper('language');
$ci->lang->load('message','english');
}
}
在这里,我们无法使用 $this->lang 访问语言库,因此我们需要使用 get_instance() 函数获取 CI 对象实例,然后像之前一样加载语言。现在该语言文件将可用于我们应用程序的每个控制器,而无需在控制器中手动加载它。
在不同语言之间切换
一旦我们建立了对多种语言的支持,就可以向用户提供每种语言的链接,通常在我们应用程序的一个菜单中,用户可以单击该菜单并切换语言。会话或 cookie 值可用于跟踪活动语言。
让我们看看如何使用我们之前生成的 hooks 类来管理语言切换。首先我们需要创建一个类来切换语言;我们将为此使用一个单独的控制器,如下所示:
<?php
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() 方法会将所选语言分配给会话并将用户重定向到主页。
现在活动语言将在会话中更改,但在我们加载活动语言的特定语言文件之前它不会受到影响。我们还需要修改我们的钩子类以从会话中动态加载语言。
<?php
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 类中,我们获取活动语言并加载必要的语言文件,或者如果会话密钥不存在,我们将加载默认语言。我们可以在这个类中加载单一语言的多个语言文件。参考:http ://www.sitepoint.com/multi-language-support-in-codeigniter/