Fra*_*cia 4 php oop class function
我正在学习PHP(不断),我前段时间创建了一个处理翻译的课程.我想模仿gettext但是从数据库中获取翻译的字符串.但是,现在我再次看到它,我不喜欢它,作为一个类,我需要使用它$Translate->text('String_keyword');.我不想要使用,$T->a('String_keyword');因为那完全不直观.
我一直在思考如何使用简单的_('String_keyword')gettext样式调用它,但是从我从SO中学到的东西,我还没有找到一个"很好"的方法来实现这一点.我需要以某种方式将默认语言传递给函数,我不想每次调用它时都传递它_('String_keyword', $User->get('Language')).我也不想在_()函数中包含用户检测脚本,因为它只需要运行一次而不是每次运行.
最简单的一个办法是使用全局变量,但是我在这里了解到,他们是完全,彻底禁止(会是这样,我唯一的情况下可以使用它们?),那么我认为DEFINE变量与用户的语言一样define ( USER_LANGUAGE , $User->get('Language') ),但它似乎与全球一样.这是我可以看到的两个主要选项,我知道还有其他一些方法,比如依赖注入,但它们似乎为这么简单的请求添加了太多的复杂性,而我还没有时间深入研究它们.
我正在考虑首先创建一个包装器来测试它.像这样的东西:
function _($Id, $Arg = null)
{
$Translate = new Translate (USER_LANGUAGE);
return $Translate -> text($Id, $Arg)
}
Run Code Online (Sandbox Code Playgroud)
这是翻译代码.在创建之前检测语言并将其传递给对象.
注意:这是旧代码 不要
$Translate->text('String_keyword');在新代码中使用函数.它们不再被维护,并且 已经开始弃用.看到 红色的盒子?了解准备好的语句,并使用 PDO或MySQLi - 本文将帮助您确定哪些.如果您选择PDO,这是一个很好的教程.
// Translate text strings
// TO DO: SHOULD, SHOULD change it to PDO! Also, merge the 2 tables into 1
class Translate
{
private $Lang;
function __construct ($Lang)
{
$this->Lang = $Lang;
}
// Clever. Adds the translation so when codding I don't get annoyed.
private function add ($Id, $Text)
{
$sql="INSERT INTO htranslations (keyword, en, page, last) VALUES ('$Id', '$Text', '".$_SERVER['PHP_SELF']."', now())";
mysql_query($sql);
}
private function retrieve ( $Id )
{
$table = is_int ($Id) ? "translations" : "htranslations"; // A small tweak to support the two tables, but they should be merged.
$results = mysql_query ("SELECT ".mysql_real_escape_string($this->Lang)." FROM ".$table." WHERE keyword='".mysql_real_escape_string($Id)."'");
$row = mysql_fetch_assoc ($results);
return mysql_num_rows ($results) ? stripslashes ($row[$this->Lang]) : null;
}
// If needed to insert a name, for example, pass it in the $Arg
public function text($Id, $Arg = null)
{
$Text = $this->retrieve($Id);
if (empty($Text))
{
$Text = str_replace("_", " ", $Id); // If not found, replace all "_" with " " from the input string.
$this->add($Id, $Text);
}
return str_replace("%s", $Arg, $Text); // Not likely to have more than 2 variables into a single string.
}
}
Run Code Online (Sandbox Code Playgroud)
您将如何以适当而简单(编码)的方式实现这一目标?是否有任何建议的方法有效,或者你能提供更好的方法吗?
如果问题只是那个问题
$Translate->text('String_keyword');
Run Code Online (Sandbox Code Playgroud)
感觉很长,然后考虑通过实现__invoke:将Translate对象变成Functor :
class Translate
{
// all your PHP code you already have
public function __invoke($keyword, $Arg = null)
{
return $this->text($keyword, $Arg)
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用所有必需的依赖项和设置定期实例化对象并调用它:
$_ = new Translate(/* whatever it needs */);
echo $_('Hallo Welt');
Run Code Online (Sandbox Code Playgroud)
这不会引入相同数量的耦合和摆弄全局范围,正如您目前考虑通过包装函数或其他地方建议的Registry/Singleton解决方案引入的那样.唯一的缺点是对象变量的非说话命名为$_().