PHP使用静态对象的问题

时间:2017-04-19 09:29:12

标签: php class object static fatal-error

我有一个叫做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 ::之前我可能没有正确使用它。我正在尝试做什么,我怎样才能让它发挥作用?

2 个答案:

答案 0 :(得分:3)

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

来自docs

  

构造函数和析构函数

     

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

虽然在您的情况下您正在使用static methods

  

静态关键字

     

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

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

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

答案 1 :(得分: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(); 
  }
}