Reputation: 6240
I've found some strange (for me) behavior of the PHP interpreter and I'm not sure if it's safe to use it in production or not.
When we call Foo::bar()
and the Foo
class does not have the static bar
method but it has non-static bar
method, the interpreter will invoke non-static bar
on null
(yes, it sounds ridiculous). I expected the __callStatic
to be invoked in this case. But it's not what is happening for some reason.
I've then found a handy usage for this behavior: to provide the class with static and non-static methods with the same name like this:
class Foo
{
public function bar(){
if (isset($this)) {
$this->nonStaticBar();
} else {
static::staticBar();
}
}
private function nonStaticBar() {
echo "Non-static\n";
}
private static function staticBar() {
echo "Static\n";
}
}
(new Foo())->bar(); // Output: "Non-static"
Foo::bar(); // Output: "Static"
Yes I know, that this approach is not elegant and architecturally wrong. The question is if it's safe (standard-compliant) to use this "feature" or not. Are there any other cases when isset($this)
can equal false
?
Upvotes: 6
Views: 719
Reputation: 1082
While your above example does work, it is not best practice.
This is recognized in the PHP documentation here and states that in PHP versions before version 7, if E_STRICT
error reporting is enabled then it will emit the error:
Strict Standards: Non-static method Foo::bar() should not be called statically in /Path/to/file.php on line 22
Additionally in PHP versions 7 and above calling static functions statically is deprecated and will cause the following error upon execution:
Deprecated: Non-static method Foo::bar() should not be called statically in /Path/to/file.php on line 22
Upvotes: 3