我知道,全局不是(;
我是OOP的新手,我正在重构我在课堂上创建的一些函数,但是我遇到了一个问题。我的一些类是从用户输入的页面本身调用的(例如:$Link->create('page/to/go');
)。由于这不在任何课程之内,因此没有问题,链接会被创建。
但是,我有一个类在创建时尝试登录用户,如果输入的电子邮件不在数据库中,则会将用户重定向到注册页面。显然,只做header ('Location '.$Link->create('page/to/go')
)不起作用。
我要做的是将create
方法设置为 static ,然后从任何地方调用它。但我认为这与使用全局变量类似,我正在努力纠正不良习惯。那我该怎么做呢?
以下是类Link
的一些代码,实现了我在here解释的404检测:
class Link
{
private function valid($check)
{
$exceptions=array("help/report", "translate"); // More pages and rules to be added
return in_array($check,$exceptions);
}
public function create($arg)
{
if (!file_exists("/path/to/".$arg) && !$this->valid($arg))
{
// Call a function to store the error in a database.
error ("404 for ".$arg);
// One way of handling it. Replace '/' for ' ' and google that string in this page.
$arg=str_replace("/","%20",$arg);
return "https://www.google.com/#q=site%3A".Configuration::get('BaseUrl')."%20".$arg;
}
else
{
// If the page exists or is an exception, create the normal link.
if(empty($arg)) return Configuration::get('BaseUrl');
else return Configuration::get('BaseUrl').$arg;
}
}
}
正如您在代码中看到的,当我将error()实现到类中时,我会遇到类似的问题。
我只想到一个选项是我可能想要返回一个错误并从User类的__construct()外部解析它。但它只适用于此,因为它是/是,我不认为制作错误代码适用于其他情况。
那么,您对将属性和方法从一个类传递给其他类的建议是什么?是否可以在此上下文中使用static
?
EDIT。我的问题很难解决,几乎所有的书籍,教程,页面等我都看过如何创建一个SINGLE类。我没有看到任何课程应该如何相互交谈。
编辑2.根据评论中的要求,这里有更多代码。用户访问他的课程仅输入电子邮件(获得级别1),而用户只有在设置页面中获得级别2时才能编辑他的设置。没完,因为我会提出更多的方法。
class User
{
private $Email;
private $Name;
public function __construct()
{
if (!empty($_POST['logout'])) session_destroy();
else if ( !empty($_POST['email']) )
{
$this->loginEmail($_POST['email']);
}
else if ( $_SESSION['level'] == 1 )
{
if (!empty($_POST['password']))
{
$this->loginFull($_SESSION['email'],$_POST['password']);
}
else
{
$this->loginEmail($_SESSION['email']);
}
}
else if ( $_SESSION['level'] == 2 )
{
$this->loginFull($_SESSION['email'],$_SESSION['pass']);
}
else session_destroy();
}
private function loginEmail($Email)
{
$sql=mysql_query("SELECT * FROM users WHERE email='".mysql_real_escape_string($Email)."'"); //Retrieve the entries from the database
$row=mysql_fetch_assoc($sql);
if(mysql_num_rows($sql)==1)
{
$this->getData($row);
$_SESSION['level']=1;
}
else header ('Location: http://example.org/new/student/');
}
private function loginFull($Email,$Pass)
{
$sql=mysql_query("SELECT * FROM users WHERE email='".mysql_real_escape_string($Email)."' AND pass='".md5($Pass)."'"); //Retrieve the entries from the database
$row=mysql_fetch_assoc($sql);
if(mysql_num_rows($sql)==1)
{
$this->getData($row);
$_SESSION['pass']=$Pass;
$_SESSION['level']=2;
}
else $this->loginEmail($Email);
}
private function getData($row)
{
$_SESSION['email']=$row['email'];
$this->Email=$row['email'];
$this->Name=$row['name'];
}
public function get($Var)
{
return $this->$Var;
}
}
现在是班级Error
。正如你所看到的,我已经在不知道它的情况下完成了一些DI。
class Error
{
private $Page;
private $Language;
private $User;
public function __construct($Page,$Language,$User="None")
{
$this->Page=$Page;
$this->Language=$Language;
$this->User=$User;
if (!empty($_REQUEST['banner']))
$this->Banner=$_REQUEST['banner'];
}
public function add($Kind)
{
if (!mysql_query("INSERT INTO error (kind, page, lang, user, version, date) VALUES ('".mysql_real_escape_string($Kind)."', '".mysql_real_escape_string($this->Page)."', '".mysql_real_escape_string($this->Language)."', '".mysql_real_escape_string($this->User)."', '".Configuration::get('Version')."',NOW() )"))
mail(Configuration::get('ErrorEmail'), "Error '".$Kind."' that couldn't be stored.",
"Full url: ".$FullUrl."\n Language: ".$this->Language->Lang."\n User: ".$Identif."\n Version: ".$Version); // Inform of the error by email
}
}
答案 0 :(得分:1)
创建Link类的实例并将其传递到需要的位置(使用setter或constructor)。 Definitelly读取了DI(依赖注入)和DI容器的内容。
中的精彩介绍答案 1 :(得分:1)
Singletons和Static不是一个好选择。最终一切都落在了全局问题上。
你应该通过构造函数或setter将你的link helper
注入类中(DI为@jasir所说的。)
如果您要重定向用户,还可以注入redirector helper
:
$redirector->redirect('controller','action', array('my','params'));
提示:这也很糟糕
Configuration::get()
。请改为注入配置 永远记住:Don't look for things!