Nasıl ben statik içeriği (veya değil) olduğumu PHP kontrol edebilirim?

8 Cevap php

Bir yöntem statik veya bir örneği nesne çağırdı ediliyor olmadığını kontrol edebilirsiniz herhangi bir yolu var mı?

Jamie

8 Cevap

Aşağıdaki deneyin:

class Foo {
   function bar() {
      $static = !(isset($this) && get_class($this) == __CLASS__);
   }
}

Kaynak: seancoates.com Google üzerinden

$this ayarlanmış olup olmadığını kontrol etme, her zaman çalışmaz.

Eğer bir nesne içinde bir statik yöntemini çağırırsanız, o $this arayanlar bağlamında olarak kurulacaktır. Eğer really bilgi isterseniz, ben size debug_backtrace dışarı kazmak zorundasınız düşünüyorum. Ama ilk etapta neden ihtiyaç duyulsun ki? Şansını olmadığını böylece bir şekilde kod yapısını değiştirmek olabilir vardır.

"Debug_backtrace dışarı Kazma ()" çok fazla iş değildir. Eğer değilse - '>' debug_backtrace () a '::' bir çağrı statik ise 'tip' üyesi, ve vardı. Yani:

class MyClass {
    public function doStuff() {
        if (self::_isStatic()) {
            // Do it in static context
        } else {
            // Do it in object context
        }
    }

    // This method needs to be declared static because it may be called
    // in static context.
    private static function _isStatic() {
        $backtrace = debug_backtrace();

        // The 0th call is to _isStatic(), so we need to check the next
        // call down the stack.
        return $backtrace[1]['type'] == '::';
    }
}

Aslında bütün komut dosyaları bu kod satırını kullanın, iyi çalışır ve hataları önler.

class B{
      private $a=1;
      private static $static=2;

      function semi_static_function(){//remember,don't declare it static
        if(isset($this) && $this instanceof B)
               return $this->a;
        else 
             return self::$static;
      }
}

Instanceof kullanımı paranoya değil:

If class A call class B statically function $this may exist on the A scope; I know it's pretty messed up but php does it.

instanceof bunu düzeltmek olacak ve "yarı-statik" fonksiyonlarını uygulayabilir sınıfları ile çelişen önlemek olacaktır.

Için test $this:

class Foo {

    function bar() {
        if (isset($this)) {
            echo "Y";
        } else {
            echo "N";
        }
    }
}

$f = new Foo();
$f->bar(); // prints "Y"

Foo::bar(); // prints "N"

Pygorex1 belirttiği gibi Edit:, ayrıca force yöntem statik değerlendirilebilir yapabilirsiniz:

class Foo {

    static function bar() {
        if (isset($this)) {
            echo "Y";
        } else {
            echo "N";
        }
    }
}

$f = new Foo();
$f->bar(); // prints "N", not "Y"!

Foo::bar(); // prints "N"

Troelskn tarafından belirtildiği gibi test isset ($ this) "$ this arayanlar bağlamda olarak kurulacaktır.", Benim için çalışma değildi

abstract class parent
{
    function bar()
    {
        if( isset( $this ) ) do_something();
        else static::static_bar();
    }

    function static static_bar()
    {
        do_something_in_static_context();
    }
}

class child extends parent
{
    ...
}

$foo = new child();
$foo->bar(); //results in do_something()
child::bar(); //also results in do_something()

Benim durumumda, ben bir çocuk sınıf içinde aynı görevi gerçekleştiren bir nesne ve statik bağlam fonksiyonu ile bir üst sınıf var. isset ($ this) her zaman doğru dönüyordu, ancak, ben bu $ nesne bağlamında varlık sınıfı çocuk arasında geçer ve statik bağlama (?) sınıf çağrısı yaparken, harika __class__ sihirli sabit olarak kaldığını fark sınıf ebeveyn!

Biz statik bağlamda eğer kısa bir süre var-sonra fonksiyon is_a bulma, biz şimdi test edebilirsiniz:

if(  is_a($this, __CLASS__) ) ...

Statik bağlamında yanlış, nesne bağlamında true döndürür.

Ben sadece 5.3 benim belirli bir senaryo (miras arama benzersiz bir vaka) için bu test ediyorum gibi, kendi uygulamaları için test edin.

Ne yazık ki (benim durumumda için) henüz $ bu ve statik ayrı bir sınıfa başvuruyorsunuz beri static_bar() aramak için bir yol bulamadı ve __class__ üst sınıfa başvurduğu . Neye ihtiyacım çocuğu aramak için bir yoldur :: static_bar (...)

$this tanımlı olup olmadığını kontrol edin

<?

class A {
    function test() {
            echo isset($this)?'not static':'static';                                }

}

$a = new A();
$a->test();
A::test();
?>

Düzenleme: dövüldü.