Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 我应该使用静态方法和属性来检测语言和翻译文本吗? 选择_Php_Oop_Class_Static - Fatal编程技术网

Php 我应该使用静态方法和属性来检测语言和翻译文本吗? 选择

Php 我应该使用静态方法和属性来检测语言和翻译文本吗? 选择,php,oop,class,static,Php,Oop,Class,Static,我正在学习OOP PHP,但有些东西确实让人困惑。我对在哪里使用静态方法有一个大致的想法,但我不确定这是否是一个好主意 我的问题是,对于我所面临的具体问题(如下所述),哪种方法实际上是最好的方法。我在网上找到的一般准则对这个具体问题没有帮助。以下是我的想法(从更可能正确到更少): 扩展Language类,创建一个对象(在初始化中获取语言),并使用$id调用一个方法,该方法将返回转换后的字符串 将两个类合并为一个类。初始化时会找到语言,需要时会调用方法。但它会表现得有点像一只猫 使语言类保持静态

我正在学习OOP PHP,但有些东西确实让人困惑。我对在哪里使用静态方法有一个大致的想法,但我不确定这是否是一个好主意

我的问题是,对于我所面临的具体问题(如下所述),哪种方法实际上是最好的方法。我在网上找到的一般准则对这个具体问题没有帮助。以下是我的想法(从更可能正确到更少):

  • 扩展Language类,创建一个对象(在初始化中获取语言),并使用$id调用一个方法,该方法将返回转换后的字符串

  • 将两个类合并为一个类。初始化时会找到语言,需要时会调用方法。但它会表现得有点像一只猫

  • 使语言类保持静态。因此,我可以在文本中使用它。我将创建一个文本实例,并使用不同的$id调用一个方法。类似于将其用于globals。几乎没有其他地方需要我使用语言课程

  • 使用文本扩展语言类,为每个翻译创建一个对象。这可能会产生太多的开销

  • 什么也不做。这很诱人(如果它没有坏,就不要修复它),但我打算很快开始与其他人一起开发,因此需要干净清晰的代码

代码 现在是简单类:

class Language
  {
  public $Lang;
  public function __construct()
    {
    if ( !empty($_POST['lang']) )    // If the user tries to change the language
      {
      $this->Lang = mysql_real_escape_string($_POST['lang']);  // Assign the language to variable.
      $_SESSION['lang'] = $this->Lang;      //Sets the session to have that language.
      if ($_SESSION['logged']==1)          // If user is logged
        {
        $User=$_SESSION['user'];
        mysql_query("UPDATE users SET lang='$this->Lang' WHERE email='$User'") or die(mysql_error());  // Saves the language into user preferences
        }
      }
    else      // If no request is done.
      {
      if ($_SESSION['logged']==1)    // DO. Check for user's language
        {
        $User=mysql_real_escape_string($_SESSION['user']);
        $result=mysql_query("SELECT * FROM users WHERE email='$User'");
        $row=mysql_fetch_array($result);
        $this->Lang=$row['lang'];
        }
      else
        if ( !empty ($_SESSION['lang']))  // If the session exists (not empty)
          $this->Lang = $_SESSION['lang'];  // Assign the session language to variable.
        else          // If it doesn't exist
          $this->Lang = substr ($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);  // Get it from the browser
      }
    //If the language is not supported (or still doesn't exist), then put "en" as default. Supported so far: en, es.
    if ( $this->Lang !== "en" && $this->Lang !== "es") $this->Lang="en";
    }
  }
我在这个类中有几个方法,但这是这里唯一相关的代码。所以我用
$Language=newlanguage初始化它$Language->Lang
以获取用户语言。到目前为止还不错

这是我想重新转换为类的函数。它获取一个整数或字符串,使用mysql将其作为id进行搜索,并返回正确语言的翻译字符串。现在,我如何做到这一点?这里是text()函数。它与globals一起使用,这显然是一种非常糟糕的做法

function text($Id)
    {
    // Already defined and tested that are valid (sql injection avoided also)
    global $Lang;
    global $Url;
    global $Version;
    global $Banner;
    if (!empty($Url["folder"])) $FullUrl = "/".$Url["folder"]."/";
      else $FullUrl="/";
    if (!is_int($Id)) $Id = mysql_real_escape_string( $Id );

    $numargs = func_num_args();  // Get the number of arguments that are being passed.
    if ($numargs == 2)  // If there are actually two
      $Var=func_get_arg(1);  // Set $Var with the second value (1).

    if (is_int($Id))  // If a number is being passed
      {
        // Add AND page='$FullUrl' to control scope of the strings translated
      $results = mysql_query("SELECT * FROM translations WHERE id='$Id'") or die ('Could not query:' . mysql_error());
      $row = mysql_fetch_assoc($results);
      if (!empty($row[$Lang]) && !isset($Var)) echo stripslashes($row[$Lang]);  // If there is some, echo it
        elseif ($Var==1) return stripslashes($row[$Lang]); // If it is required to be a returned string, send it.
      else error($FullUrl,$Lang);  // If there is nothing there, calls error function.
      }
    else  // If a string is being passed
      {
      $results = mysql_query("SELECT * FROM htranslations WHERE keyword='$Id'") or die ('Could not query:' . mysql_error());
      $row = mysql_fetch_assoc($results);

      if (!empty($row[$Lang]) && !isset($Var)) echo stripslashes($row[$Lang]);  // If it exists in the table, echo it
      elseif (!empty($row[$Lang]) && isset($Var)) return stripslashes($row[$Lang]);
      else  // Else (it doesn't exist)
        {
        $Id = str_replace("_", " ", $Id);  // Replace the "_" with " "
        if (!isset($Var))
          {
          echo $Id;  // Echo the passed string with spaces
          }
        else return $Id;

        $Banner="There might be some misstranslation. Please report if needed.";
        }
      }
    }

因此,文本功能有很多副作用;也就是说,这让我很感动 东西,有时返回,有时打印东西到 标准输出。这通常是不好的,因为它很难调试,单元测试 和重构

我会选择选项2:将两个类合并为一个。语言将会被发现 初始化时,并在需要时调用方法

下面是我将如何实现这一点(我尽可能完整地保存了大量代码,以便您能够理解 在OOP方面发生了什么变化。我会改变很多其他事情;主要是其他事情 已经对plus进行了评论,没有从方法中打印任何内容。这是一个很好的实践 让方法返回某些内容,而不是从内部修改应用程序状态

我改变的事情:

文本函数实际上是在特定时间内更改全局变量($Banner) 次,使用两个全局变量($Url)和($Lang),这两个变量实际上来自该语言 对象),然后从数据库返回Id或可能打印到 标准输出

由于将text函数移到了Language类中,我转换了全局$Lang 变量使用语言类的实例变量$Lang

$Url方法仅在文本函数中使用,因此可以传递到文本方法中

全局变量$横幅实际上是由我认为是坏的文本函数设置的。 副作用。我决定替换此代码:

$Banner=“可能有一些翻译错误。如果需要,请报告。”

返回false

这样,如果text方法返回false,则可以设置$Banner 变量为“可能有一些误译。如果需要,请报告。”哪个 从对象外部执行

另外,我从文本函数中删除了全局变量$Version,因为它没有在中使用 功能

我还建议让text方法只返回而不打印到 标准输出。误译拼写错误。应该是误译

我希望这有助于

<?php

class Language {

    public $Lang;

    public function __construct() {
        if (!empty($_POST['lang'])) {    // If the user tries to change the language
            $this->Lang = mysql_real_escape_string($_POST['lang']);  // Assign the language to variable.
            $_SESSION['lang'] = $this->Lang;      //Sets the session to have that language.
            if ($_SESSION['logged'] == 1) {          // If user is logged
                $User = $_SESSION['user'];
                mysql_query("UPDATE users SET lang='$this->Lang' WHERE email='$User'") or die(mysql_error());  // Saves the language into user preferences
            }
        } else {      // If no request is done.
            if ($_SESSION['logged'] == 1) {    // DO. Check for user's language
                $User = mysql_real_escape_string($_SESSION['user']);
                $result = mysql_query("SELECT * FROM users WHERE email='$User'");
                $row = mysql_fetch_array($result);
                $this->Lang = $row['lang'];
            } else
            if (!empty($_SESSION['lang']))  // If the session exists (not empty)
                $this->Lang = $_SESSION['lang'];  // Assign the session language to variable.
            else          // If it doesn't exist
                $this->Lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);  // Get it from the browser
        }
        //If the language is not supported (or still doesn't exist), then put "en" as default. Supported so far: en, es.
        if ($this->Lang !== "en" && $this->Lang !== "es")
            $this->Lang = "en";
    }

    public function text($Id, $Url) {
        // Already defined and tested that are valid (sql injection avoided also)
        if (!empty($Url["folder"]))
            $FullUrl = "/" . $Url["folder"] . "/";
        else
            $FullUrl = "/";
        if (!is_int($Id))
            $Id = mysql_real_escape_string($Id);

        $numargs = func_num_args();  // Get the number of arguments that are being passed.
        if ($numargs == 2)  // If there are actually two
            $Var = func_get_arg(1);  // Set $Var with the second value (1).

        if (is_int($Id)) {  // If a number is being passed
            // Add AND page='$FullUrl' to control scope of the strings translated
            $results = mysql_query("SELECT * FROM translations WHERE id='$Id'") or die('Could not query:' . mysql_error());
            $row = mysql_fetch_assoc($results);
            if (!empty($row[$this->Lang]) && !isset($Var)) {
                echo stripslashes($row[$this->Lang]);  // If there is some, echo it
            } elseif ($Var == 1) {
                return stripslashes($row[$this->Lang]); // If it is required to be a returned string, send it.
            } else {
                error($FullUrl, $this->Lang);  // If there is nothing there, calls error function.
            }
        } else {  // If a string is being passed
            $results = mysql_query("SELECT * FROM htranslations WHERE keyword='$Id'") or die('Could not query:' . mysql_error());
            $row = mysql_fetch_assoc($results);

            if (!empty($row[$this->Lang]) && !isset($Var)) {
                echo stripslashes($row[$this->Lang]);  // If it exists in the table, echo it
            } elseif (!empty($row[$this->Lang]) && isset($Var)) {
                return stripslashes($row[$this->Lang]);
            } else {  // Else (it doesn't exist)
                $Id = str_replace("_", " ", $Id);  // Replace the "_" with " "
                if (!isset($Var)) {
                    echo $Id;  // Echo the passed string with spaces
                } else {
                    return $Id;
                }

                return false;
            }
        }
    }

}

?>

请不要使用
mysql.*
函数来编写新代码。它们不再被维护,社区已经开始。请看?相反,您应该了解并使用或。如果您不能决定使用哪一个,将对您有所帮助。如果您选择PDO,。另外,让我们澄清一些事情,
全局
是邪恶的,存在大量的资源这个主题,所以我将留给你去学习。另外,静态变量/方法不是OOP。它们是伪装的全局变量/方法!小心使用!我确实知道这一点。我已经访问了你发布的3个链接,但我现在的重点是学习OOP PHP。关于伪装的全局变量/方法,我声明:
Similar将其用于全局性。
我还声明了
它用于全局性,这显然是一个非常糟糕的做法。
当我对OOP有了更多的了解后,我将研究所有这些。这是我重写代码以摆脱全局性的众多原因之一。您的类不应该存储SQL转义字符串(在
->Lang
中)。只有sql在生成sql查询时才转义。绝对。存储原始数据,并在需要转义时转义。这样,您可以决定将来转义到html,而不必首先取消转义sql。此外,这意味着您始终知道是否输出转义数据,因为您可以在使用转义数据的地方转义。对于同样的原因,在数据库中存储html转义文本也是愚蠢的-如果你想在将来向用户提供一个纯文本文件呢?我已经在过去几个小时(以及其他几天)了研究模式和最佳实践,实现注释并重新编写我的代码。现在我将看到您所做的更改,可能会使用很多。但从一段时间以来,我不喜欢一些基本想法