2

我知道,全局变量不是 (;

我是 OOP 的新手,我正在将我创建的一些函数重构为类,但我遇到了一个问题。我的一些类是从用户输入的页面本身调用的(例如:)$Link->create('page/to/go');。由于这是在任何类之外,所以没有问题,链接被创建。

但是,我有一个类在创建时尝试登录用户,如果输入的电子邮件不在数据库中,它会将用户重定向到注册页面。显然,只做header ('Location '.$Link->create('page/to/go')) 是行不通的。

我要做的是将create方法设置为静态,然后从任何地方调用它。但我认为这类似于使用全局变量,我正在尝试纠正坏习惯。那么我该怎么做呢?

这是该类的一些代码,实现了我在此处Link解释的 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用于这种情况吗?

编辑。我的问题的难点在于,我见过的几乎所有书籍、教程、页面等都在谈论如何创建一个单一的课程。我还没有看到任何深入解释类应该如何相互交谈。

编辑 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
    }
  }
4

2 回答 2

1

创建 Link 类的实例并将其传递到需要的位置(使用 setter 或构造函数)。一定要阅读有关 DI(依赖注入)和 DI Containers 的内容。

Nette 框架中很好的介绍- 依赖注入

于 2012-09-06T13:20:00.483 回答
1

单例和静态不是一个好的选择。最后一切都落到了全局问题上。

您应该link helper通过构造函数或设置器(如@jasir 所说的DI)将您的注入到类中。

如果您要重定向用户,您还可以注入redirector helper

$redirector->redirect('controller','action', array('my','params'));

提示:这也很糟糕Configuration::get()。而是注入配置。
永远记住:不要找东西!

于 2012-09-06T13:22:18.973 回答