【问题标题】:PHP problems with using static object使用静态对象的 PHP 问题
【发布时间】:2017-09-15 10:37:44
【问题描述】:

我有一个名为 BaseContext 的类,还有一个名为 JsonReporter。 BaseContext 需要一个 JsonReporter 对象,并且必须在各个点调用它的方法。问题是 BaseContext 的方法是并且必须保持静态,但无论如何都需要使用 JsonReporter 对象。

这就是我所做的:

class BaseContext extends RootContext
{
  static $reporter;

  public function __construct() {
     self::$reporter = new JsonReporter();
  }

  public static function startSuite() {
     self::$reporter->startSuite();
  }
}

然后在 JsonReporter 中:

class JsonReporter
{
  private $message;

  public function startSuite() {      
    $this->message.="{ \"feature\" : [";
  }
}

好的,现在每次在 BaseContext startSuite() 被调用,我得到:

致命错误:在 null 上调用成员函数 startSuite()

我以前从未使用过 self::,而且我可能没有正确使用它。我正在尝试做的事情是否可行?我怎样才能让它发挥作用?

【问题讨论】:

  • 如何创建BaseContext 对象?
  • 你正在使用startSuite()静态的问题,所以你永远不会构造对象。
  • self 指的是类本身,它只能访问静态方法和属性,而$this 指的是new 类的实例化(称为对象)。对象可以访问静态方法和属性,但静态方法不能访问对象方法。
  • 嗯嗯。那太糟糕了。得用别的办法。谢谢
  • 避免使用任何静态的东西,除非类要求属性或方法独立于从它创建的任何对象。或者如果每个对象必须共享相同的属性。

标签: php class object static fatal-error


【解决方案1】:

致命错误:在 null 上调用成员函数 startSuite()

class BaseContext extends RootContext
{
  static $reporter; // !! => you have a placeholder but no obj

  public function __construct() { // !! => constructor only works when you create an obj   
  self::$reporter = new JsonReporter(); // !! => will be never set
  }

  public static function startSuite() {
     self::$reporter->startSuite(); // !! => you are calling method on empty placeholder
  }
}

解决方案

class BaseContext extends RootContext
{
  static $reporter; 

  public static function setReporter() {
     self::$reporter = new JsonReporter();
  } 

  public static function getReporter() {
     if(!isset(self::$reporter)) { // if not yet set
      self::setReporter(); // set one
     }
     return self::$reporter; // return reporter
  }

  public static function startSuite() {
     self::getReporter()->startSuite(); 
  }
}

【讨论】:

    【解决方案2】:

    好吧,你静态使用 startSuite() 的问题,所以你永远不会构造对象。

    来自docs

    构造函数和析构函数

    PHP 5 允许开发人员为类声明构造方法。 具有构造方法的类在每个新创建的对象上调用此方法,因此它适用于任何初始化 对象在使用之前可能需要。

    在您的情况下,您使用的是static methods

    静态关键字

    将类属性或方法声明为静态使它们可以访问 不需要类的实例化。声明为的属性 static 不能用实例化的类对象访问(尽管 静态方法可以)。

    为了解决这个问题,您可以轻松地在您的 startSuite 方法中实例化您的对象

    public static function startSuite() {
         self::$reporter = new JsonReporter();
         self::$reporter->startSuite();
    }
    

    【讨论】:

      猜你喜欢
      • 2013-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多