Calling instance methods statically from within a class

According to one of the man pages http://www.php.net/manual/en/language.oop5.static.php :

Calling non-static methods statically generates a warning of the E_STRICT level.

But this does not seem to be the case when the call is made from within the class:

error_reporting(-1); class Test { private $id; function __construct($id) { $this->id = $id; } function id() { return $this->id; } function __toString() { return Test::id() . self::id() . static::id() . static::id() . call_user_func('Test::id') . call_user_func(array('Test', 'id')); } } $a = new Test('a'); $b = new Test('b'); echo "$a $b $a"; # aaaaaa bbbbbb aaaaaa var_dump(error_get_last()); # NULL 

Testing with php 5.4

DEMO: http://codepad.viper-7.com/IKp9iX

I believe I have demonstrated:

  • Warning E_STRICT not generated
  • This php magically fixes a call to a static method to an instance method call (access to the instance variable id confirms this).

edit - I would like to add that inserting debug_backtrace () into the __toString call causes a call like " -> , which means" method call ".

Is this a bug or a documented function?

+4
source share
2 answers

I would say that a semi-documented function :

In non-static contexts, the called class will be the class of the object. Since $ this-> will try to call private methods from the same scope, using static :: may give different results. Another difference is that static :: can only refer to static properties.

In other words (as I understand it), it can be used to implement late static binding: using self::id() and static::id() can give different results if you call them in some class that extends your test .

+2
source

If you call a non-statistical function with static syntax inside any class (and not just the declaration class), then the non-static function behaves as if it was called in the context of the current $ this object.

This means that I can use methods from another class inside my class, and these methods will consider my $ this class to be its $ this class. If they do not check InstanceOf or get_class() , they will behave exactly as usual.

When I say as usual, I mean that they will assume that your $ this class has all the other methods and properties that their $ this class will have.

This (I think) is called object context binding. In JavaScript, you must use the call() and / or apply() methods to make the function behave as if it were bound to a specific object. But in PHP, it just works using static syntax for non-static functions.

I remember that this works in C ++ as well, but I can’t remember if it only works if the methods belonged to inherited classes (possibly overridden methods that you want to access, even though they redefined).

Using this (hidden) function, you can implement the Decorator design template, with which you add new functions to the object at runtime. You can also simulate Mixins or Traits (which PHP 5.4 now supports) with an added bonus that this implementation is processed at runtime and as such can be executed / canceled dynamically, unlike the implementation of a language function that is processed at compile time and cannot to be executed / canceled dynamically, you need to change the code to change the function.

+2
source

All Articles