2

I have a static function being called that is giving a strange error. Here is an example of the php code:

class foo {
     public $stat;
     public function __construct() {
         $this->stat = stat::isValid('two');
     }
}

class stat {
     protected static $invalidNumbers = array('one', 'two');
     function isValid($number) {
         return in_array($number, static::$invalidNumbers);
     }
}

$foo = new foo();
var_dump($foo->stat);

This code results in the following error:

Fatal error: Access to undeclared static property: foo::$invalidNumbers

However changing static:: to self:: makes the code behave as expected. I was under the impression that in this context using static:: should work.

Why does this error occur using static?

3 Answers 3

6

You begin by making a method call in a static context:

stat::isValid('two');

When you do this, PHP "remembers" the context from within which isValid was called specifically so that it can resolve what to bind to when it sees something like static:: inside the method body, determine if some property you are trying to access is visible, and in general be able to implement some OO-related language features.

The actual method isValid is not static, but PHP still allows you to call it using the static method syntax (it does give an E_STRICT warning about that). However, this has the side effect that isValid itself does not participate in modifying the curent calling context for (late) static bindings.

The result: when PHP sees static::$invalidNumbers, it still thinks you are halfway through making a static method call from within the foo class! Once you realize this, it is obvious why static:: resolves to foo:: and it ends up looking for the property at the wrong place.

If you correctly declare isValid as static

 static function isValid($number) {
     return in_array($number, static::$invalidNumbers);
 }

then upon calling the method PHP does update its context internally and manages to bind to the intended member.

Sign up to request clarification or add additional context in comments.

1 Comment

Good answer! It is indeed so, that the code in question is working when you have declared foo::invalidNumbers. Although this makes totally sense, I didn't realized this before.
3

You are trying to call the method stat::isValid() statically but have not declared it static. Change the stat class to:

class stat {
     protected static $invalidNumbers = array('one', 'two');

     // needs to be declared static
     static function isValid($number) {
         return in_array($number, static::$invalidNumbers);
     }
}

Note that, if you add

| E_STRICT

to your error_reporting in php.ini you would see a message like:

Strict standards: Non-static method stat::isValid() should not be called statically, assuming $this from incompatible context in ...

2 Comments

I was aware of the notice but wasn't aware that it made this difference. Thanks.
It makes the difference ;)
2

Declare static method properly

Replace

 function isValid($number) {

With

public static function isValid($number) {   
         ^--- here  

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.