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

发布于 2024-11-03 23:04:14 字数 571 浏览 2 评论 0原文

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

I am writing a PHP class and have included a couple static functions for quick access as they are common for use and are simple in function. However they do use an object in them for database access. I will likely be using these static methods from both a static and non-static context throughout my code so I want to be able to test whether the function was called from a static or non-static context so that I can avoid creating a duplicate object if the function was called from a non-static context (this instance object and the one within the function to be used statically). Is there any way that I can test this in the function so that I can use the instance object if the function is called from a non-static context and create it's own object if the function is called from a static context?

Code Example:

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.
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

泼猴你往哪里跑 2024-11-10 23:04:14

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

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

When a method is declared as static,
not only is the magic variable $this
unavailable (returns NULL), but it is
impossible to tell if the function was
actually called from a static context.
A backtrace implies that for a static
method, calling $object->method() is
internally translated to
className::method() at run time.

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

蓝海似她心 2024-11-10 23:04:14

仅当您不强制方法仅静态时,才可以检查非静态访问。从函数声明中省略 static 关键字并使用以下命令进行测试:(

public function myFunction(){
    if(!isset($this)) {

它仍然可以作为静态函数调用,即使您没有这样声明。)

You can check for non-static access only if you do not force the method to be static-only. Leave out the static keyword from the function declaration and test with:

public function myFunction(){
    if(!isset($this)) {

(It can still be called as static function, even though you did not declare it as such.)

極樂鬼 2024-11-10 23:04:14

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

Bottom line - don't make classes which contain only static functions. It is not OOP, it is just your old procedural code masquerading as oop

If you are executing functions statically, there is no $this, as there is no object.
You will end up making the private $db a static variable too , and use it as self::$db.

That said, i would recommend to drop this pattern and write something like :

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.
   }

}

And you use this class like this :

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

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

$blah = new DifferentClass( $db );

This way you share the same connection with all the classes that require it. And now the class FooBar is not responsible for making connection or has to know your connection details.

断爱 2024-11-10 23:04:14

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

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

Solution 1: Make the $db variable private, and use it via a getter.

Solution 2: Implement a singleton pattern on the dbal side.

最笨的告白 2024-11-10 23:04:14

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

Even when calling a static method from an instance (not recommended), you do not have
access to $this, so your class will fatal.

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

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

As another poster has indicated from the php manual.

$db however can be defined statically instead so it only needs to be created once regardless of whether the object is an instance or not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文