当有__construct()元素时,将类转换为函数

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');在新代码中使用函数.它们不再被维护,并且 已经开始弃用.看到 红色的盒子?了解准备好的语句,并使用 PDOMySQLi - 本文将帮助您确定哪些.如果您选择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)

您将如何以适当而简单(编码)的方式实现这一目标?是否有任何建议的方法有效,或者你能提供更好的方法吗?

Gor*_*don 6

如果问题只是那个问题

$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解决方案引入的那样.唯一的缺点是对象变量的非说话命名为$_().