Проверить, выполняется ли функция из статического контекста

Я пишу класс 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 ответов


когда метод объявлен как static, не только волшебная переменная $this недоступно (возвращает NULL), но это невозможно сказать, была ли функция фактически вызывается из статического контекста. Трассировка означает, что для статического метод, вызывающий $object - >method () внутренне переведены на className:: method () во время выполнения.

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


вы можете проверить нестатический доступ, только если вы не заставляете метод быть только статическим. Оставьте static ключевое слово из объявления функции и теста с:

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

(его все еще можно назвать статической функцией, даже если вы не объявили ее таковой.)


Итог - Не создавайте классы, которые содержат только статические функции. Это не ООП, это просто ваш старый процедурный код, маскирующийся под ООП

если вы выполняете функции статически, нет $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 );

таким образом, Вы разделяете одно и то же соединение со всеми классами, которые его требуют. А теперь класс!--4--> не несет ответственности за подключение или должен знать ваши детали подключения.


Решение 1: Сделайте $db переменная private и используйте ее через геттер.

решение 2: реализуйте одноэлементный шаблон на стороне dbal.


даже при вызове статического метода из экземпляра (не рекомендуется), вы не имеете доступ к $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 однако можно определить статически, поэтому его нужно создать только один раз, независимо от того, является ли объект экземпляром или нет.