Как проверить на PHP, что я в статическом контексте (или нет)?

Есть ли способ проверить, вызван ли метод статически или на экземпляр объекта?

Solutions Collecting From Web of "Как проверить на PHP, что я в статическом контексте (или нет)?"

Попробуйте следующее:

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

Источник: seancoates.com через Google

«Выкапывать его из debug_backtrace ()« не слишком много. У debug_backtrace () был член 'type', который является '::', если вызов статический, а '->', если это не так. Так:

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'] == '::'; } }
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'] == '::'; } } 

Проверка того, установлен ли $this , не будет работать всегда.

Если вы вызываете статический метод из объекта, то $this будет задан как контекст вызывающих. Если вам действительно нужна информация, я думаю, вам придется выкапывать ее из debug_backtrace . Но зачем вам это нужно в первую очередь? Скорее всего, вы можете изменить структуру своего кода таким образом, чтобы вы этого не сделали.

Я действительно использую эту строку кода во всех моих сценариях, она работает хорошо и предотвращает ошибки.

 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 не является паранойей:

Если класс A вызывает класс B статически функцию $this может существовать в области A; Я знаю, что это довольно перепутано, но php делает это.

instanceof исправит это и позволит избежать конфликта с классами, которые могут реализовать ваши «полустатические» функции.

Тест для $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, вы также можете заставить метод оцениваться статически:

 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" 

Тестирование isset ($ this) не работало для меня, как упоминалось в troelskn «$, это будет установлено как контекст вызывающих».

 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() 

В моем случае у меня есть родительский класс с объектной и статической функцией контекста, которая выполняет одну и ту же задачу в дочернем классе. isset ($ this) всегда возвращался true, однако я заметил, что в то время как $ this переключается между тем, что он является дочерним по классу в контексте объекта и вызовом (?) класса в статическом контексте, замечательная магическая константа __class__ осталась в качестве родительского класса!

Вскоре после этого, после нахождения функции is_a, мы можем теперь проверить, находимся ли мы в статическом контексте:

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

Возвращает true в контексте объекта, false в статическом контексте.

Проверьте свои собственные реализации, поскольку я тестирую это только для своего конкретного сценария (уникальный случай вызова наследования) в 5.3.

К сожалению (для моего случая) я еще не смог найти способ вызвать static_bar() поскольку $ this и static ссылаются на отдельный класс, а __class__ ссылается на родительский класс. Мне нужен способ вызова child :: static_bar () …

Проверьте, определено ли $this

 <? class A { function test() { echo isset($this)?'not static':'static'; } } $a = new A(); $a->test(); A::test(); ?> 

Изменить: избили.

Это старый вопрос, но я добавлю альтернативный ответ.

Существует два магических метода

__call($name, $arguments)
запускается при вызове недоступных методов в контексте объекта.

__callStatic($name, $arguments)
запускается при вызове недоступных методов в статическом контексте.

 <?php class MethodTest { public function __call($name, $arguments) { // Note: value of $name is case sensitive. echo "Calling object method '$name' " . implode(', ', $arguments). "\n"; } /** As of PHP 5.3.0 */ public static function __callStatic($name, $arguments) { // Note: value of $name is case sensitive. echo "Calling static method '$name' " . implode(', ', $arguments). "\n"; } } $obj = new MethodTest; $obj->runTest('in object context'); MethodTest::runTest('in static context'); // As of PHP 5.3.0 

Выходы

Вызов метода объекта «runTest» в контексте объекта
Вызов статического метода «runTest» в статическом контексте

Просто верните класс как новый в функцию.

 return new self();