测试函数是否从静态上下文运行

时间:2011-04-30 16:16:35

标签: php oop static

我正在编写一个PHP类,并且包含了几个静态函数,可以快速访问,因为它们很常用,功能很简单。但是,他们确实使用其中的对象进行数据库访问。我可能会在整个代码中使用静态和非静态上下文中的这些静态方法,因此我希望能够测试是从静态或非静态上下文调用该函数,以便我可以避免创建重复的对象如果从非静态上下文调用该函数(此实例对象和要静态使用的函数中的实例对象)。有没有什么方法可以在函数中测试它,以便我可以使用实例对象,如果从非静态上下文调用该函数,并创建它自己的对象,如果从静态上下文调用该函数?

代码示例:

class MyClass {
  private $db;

  function __constuct(){
    $this->db = new DBConnect();
  }

  public static function myFunction(){
    if(/* Is static */){
      $db = new DBConnect();
    } else {
      $db =& $this->db;
    }
    // Do processing with $db, etc.
  }
}

5 个答案:

答案 0 :(得分:8)

  

当方法声明为static时,   不仅是魔法变量$ this   不可用(返回NULL),但确实如此   无法判断这个功能是否合适   实际上是从静态上下文调用的。   回溯意味着对于静态   方法,调用$ object-> method()是   内部翻译为   运行时的className :: method()。

http://php.net/manual/en/language.oop5.static.php

答案 1 :(得分:3)

只有在不强制该方法仅为静态时,才能检查非静态访问。从函数声明中省略static关键字并使用:

进行测试
public function myFunction(){
    if(!isset($this)) {

(它仍然可以被称为静态函数,即使你没有这样声明它。)

答案 2 :(得分:1)

底线 - 不要创建仅包含静态函数的类。它不是OOP,它只是伪装成oop的旧程序代码

如果您正在静态执行函数,则没有$ this,因为没有对象。 您最终也会将private $db设为静态变量,并将其用作self::$db

那就是说,我建议放弃这种模式并写下类似的东西:

class Foobar
{

   protected $_connection = null;

   public function __construct( DBConnect $db )  
   {
      $this->_connection = $db;
   }

   public function some_function()
   {
      $db = $this->_connection;
      // Do processing with $db, etc.
   }

}

你这样使用这个类:

$db = new DBConnection(  /* your password , user , host , etc. */);

$stuff = new FooBar( $db );
$stuff->some_function();

$blah = new DifferentClass( $db );

这样,您可以与需要它的所有类共享相同的连接。现在,班级FooBar不负责建立连接或必须知道您的连接详细信息。

答案 3 :(得分:0)

解决方案1:将$db变量设为私有,并通过getter使用它。

解决方案2:在dbal侧实施单例模式。

答案 4 :(得分:0)

即使从实例调用静态方法(不推荐),也没有 访问$this,所以你的课程将致命。

class sns {
   public static function moo() {
      var_dump($this->fng);
   }
   public function goo() {
      var_dump($this);
   }
}

sns::moo();
$_ = new sns;
$_->moo();
$_->goo();

正如另一张海报从php手册中指出的那样。

然而,

$db可以静态定义,因此无论对象是否是实例,都只需要创建一次。