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

Php 测试函数是否从静态上下文运行,php,oop,static,Php,Oop,Static,我正在编写一个PHP类,其中包含了两个静态函数,用于快速访问,因为它们使用起来很普通,函数也很简单。但是,它们确实使用其中的对象来访问数据库。在整个代码中,我可能会从静态和非静态上下文中使用这些静态方法,因此我希望能够测试函数是从静态上下文调用还是从非静态上下文调用,这样,如果函数是从非静态上下文调用的,我就可以避免创建重复的对象(此实例对象和函数中要静态使用的实例对象)。是否有任何方法可以在函数中对此进行测试,以便在从非静态上下文调用函数时使用实例对象,并在从静态上下文调用函数时创建自己的对象

我正在编写一个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.
  }
}

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


解决方案2:在dbal端实现一个单例模式。

只有在不强制方法仅为静态的情况下,才可以检查非静态访问。在函数声明中省略
static
关键字,并使用以下方法进行测试:

public function myFunction(){
    if(!isset($this)) {
(它仍然可以作为静态函数调用,即使您没有将其声明为静态函数。)

当方法声明为静态时, 不仅是神奇的变量$this 不可用(返回NULL),但不可用 无法判断该函数是否正确 实际上是从静态上下文调用的。 回溯意味着对于静态 方法,调用$object->method()是 内部翻译为 运行时的className::method()


即使从实例调用静态方法(不推荐),您也没有 访问
$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
但是可以静态定义,因此无论对象是否为实例,只需创建一次。

底线-不要创建只包含静态函数的类。这不是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
不负责建立连接,也不需要知道您的连接详细信息。

对没有static关键字的函数的静态访问不会产生错误吗?它会生成严格的通知或警告(不确定分类)。至少在我的版本中是这样。(这些东西往往偶尔会被弃用和不确定。)感谢这个Shakti,它回答了我的问题。如果我想从静态上下文中使用它们,我只需要在内部为每个静态方法创建一个对象。或者,我似乎可以将
$db
实例变量声明为静态。在某些事情上使用
私有静态
对我来说似乎很奇怪。5个答案,而不是o我对这个问题投赞成票。