直到现在,除非我做了一个多语言网站(我会使用。mo &.po文件),所有文本将在模板和/或类文件周围乱作一团。相反,我希望将所有静态文本存储在一个文件中,以便我的同事和客户端可以轻松编辑(这就排除了数据库存储和POedit)。
我制作了一个JSON文件,像这样存储消息/静态文本:
{
"titles": {
"main_title": "This is the main title of the website",
"login_page_title": "Please, sing in",
"about_page_title": "About us"
},
"errors": {
"empty_required_field": "This field is required.",
"database_connection_error": "Couldn't connect to the database.",
}
}
然后导入到index.php文件:
$messages = json_decode(file_get_contents("messages.json"));
并像这样使用:
echo($messages->titles->main_title);
迄今为止一直工作得很好(尽管我不确定是否有更好的方法来存档它)。至少在模板页面中,所有内容都是html,逻辑最少。
但是我在类的函数内使用JSON文件中的字符串时遇到了麻烦。例如,我希望在抛出异常时使用错误消息。但是我非常不愿意在每个使用它的函数中都声明"global $message"(感觉重复)。而且大家都说全局变量很淘气。
我的问题有两个:
1) JSON文件是处理我的问题的好方法吗?(如果不是,为什么,哪种方法会更好?)
2)我如何从类内部检索存储的字符串?我正在考虑扩展Exception类来包含错误消息,但我不确定如何做到这一点。
提前感谢您的帮助。
Laravel采用的一种方法是创建某种目录树,如下所示:
lang/
en/
titles.php
errors.php
title .php可以包含以下内容:
<?php
return [
'main_title' => 'This is the main title of the website',
'login_page_title' => 'Please, sing in',
'about_page_title' => 'About us'
];
对于errors.php:
<?php
return [
'empty_required_field' => 'This field is required.',
'database_connection_error' => "Couldn't connect to the database.",
];
我不太喜欢JSON方法,因为它不是很灵活。首先,在PHP文件中,你可以访问任何你想要给它的变量,有注释,可以使用函数来创建一些消息,等等。这就是我推荐以上方法的原因。
为了获得消息,您需要将文件放在变量中,如$titles = require 'lang/en/titles.php'
,使用如下:$titles['main_title']
。如果需要的话,这种方法还可以很容易地更改语言。
虽然我不是100%确定我理解你的异常问题,你会抛出一个异常与适当的消息,如:throw new Exception($errors['empty_required_field']);
最后,我选择了一个加载/包含单独文本文件的Singleton类。很好的全局作用域,应该很容易适应其他需求(multilingal,独立的语言文件,或其他)。正如我所说的,我不是专家,所以欢迎所有的批评。
<?php
class CustomText {
private static $instance = null;
private static $text;
private function __clone() {}
// On construct, checks if the strings are stored in a session.
// If not, retrieves them from file and stores them in a session.
private function __construct() {
if(self::isStoredInSession() == true) {
self::$text = $_SESSION["custom_text"];
} else {
//self::$text = json_decode(file_get_contents("messages.json"),true);
self::$text = include_once("messages.php");
self::saveToSession();
}
}
// Private initialization called on every public method so I don't have to worry about it on other files.
private static function initialize() {
if(self::$instance == null) {
self::$instance = new self;
}
}
// Session management
private static function saveToSession() {
if(session_status() == PHP_SESSION_NONE) {
session_start();
}
if(!isset($_SESSION["custom_text"])) {
$_SESSION["custom_text"] = self::$text;
}
}
private static function isStoredInSession() {
if(session_status() == PHP_SESSION_NONE) {
session_start();
}
if(isset($_SESSION["custom_text"])) {
return true;
}
return false;
}
// Sample public functions
public static function getText($section,$string){
self::initialize();
if(isset(self::$text[$section][$string])) {
return self::$text[$section][$string];
} else {
return "";
}
}
public static function getError($string) {
self::initialize();
if(isset(self::$text["error"][$string])) {
return self::$text["error"][$string];
} else {
return "";
}
}
public static function getWebsiteTitle($section,$divider = " - ") {
self::initialize();
$title = "";
if(isset(self::$text["title"]["main"])) {
$title .= self::$text["title"]["main"];
}
if(isset(self::$text["title"][$section])) {
if(!empty($title)) {
$title .= $divider;
}
$title .= self::$text["title"][$section];
}
return $title;
}
}
最让我担心的是,我不确定在会话中存储数据是否比在每个页面上包含一个文件更好,并且我在会话变量和类参数中拥有两次所有内容。