Php 我应该使用静态方法和属性来检测语言和翻译文本吗? 选择
我正在学习OOP PHP,但有些东西确实让人困惑。我对在哪里使用静态方法有一个大致的想法,但我不确定这是否是一个好主意 我的问题是,对于我所面临的具体问题(如下所述),哪种方法实际上是最好的方法。我在网上找到的一般准则对这个具体问题没有帮助。以下是我的想法(从更可能正确到更少):Php 我应该使用静态方法和属性来检测语言和翻译文本吗? 选择,php,oop,class,static,Php,Oop,Class,Static,我正在学习OOP PHP,但有些东西确实让人困惑。我对在哪里使用静态方法有一个大致的想法,但我不确定这是否是一个好主意 我的问题是,对于我所面临的具体问题(如下所述),哪种方法实际上是最好的方法。我在网上找到的一般准则对这个具体问题没有帮助。以下是我的想法(从更可能正确到更少): 扩展Language类,创建一个对象(在初始化中获取语言),并使用$id调用一个方法,该方法将返回转换后的字符串 将两个类合并为一个类。初始化时会找到语言,需要时会调用方法。但它会表现得有点像一只猫 使语言类保持静态
- 扩展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转义文本也是愚蠢的-如果你想在将来向用户提供一个纯文本文件呢?我已经在过去几个小时(以及其他几天)了研究模式和最佳实践,实现注释并重新编写我的代码。现在我将看到您所做的更改,可能会使用很多。但从一段时间以来,我不喜欢一些基本想法