php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #61084 incorrect work with class variable (declared as static)
Submitted: 2012-02-14 15:19 UTC Modified: 2012-02-15 09:37 UTC
From: lx at webactives dot ru Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: 5.3.10 OS: Windows
Private report: No CVE-ID: None
 [2012-02-14 15:19 UTC] lx at webactives dot ru
Description:
------------
All configuration standard.


Test script:
---------------
<?
error_reporting(E_ALL);
class A {
    static $v = '123';
    function m(){
        echo 'var is '.(static::$v);
    }
}
class C {
    function test(){
        A::m();
    }
}
$test = new C();
$test->test();
?>

Expected result:
----------------
PHP Fatal error: Access to undeclared static method: A::m() in test.php on line 11
OR
STRICT CLASSIC ERROR ONLY

Actual result:
--------------
PHP Fatal error: Access to undeclared static property: C::$v in test.php on line 6

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-02-14 16:24 UTC] rasmus@php.net
-Status: Open +Status: Not a bug
 [2012-02-14 16:24 UTC] rasmus@php.net
In PHP 5.3 E_STRICT is not included in E_ALL. Your code does give you an 
E_STRICT. Use error_reporting(-1); at the top.
 [2012-02-14 17:01 UTC] lx at webactives dot ru
I'm known it, but error message incorrect.  You can see it on this code:
<?
error_reporting(E_ALL);
class A {
    static $v = 'A';
    function m(){
        echo 'var is '.(static::$v);
    }
}
class C {
    static $v = 'C';
    function test(){
        A::m();
    }
}
$test = new C();
$test->test(); //display incorrect "var is C" without any error.
?>
 [2012-02-14 17:19 UTC] rasmus@php.net
I still don't see what is wrong. Forget the fact that you are calling a non-
static method statically. That has nothing to do with the inner access to the 
static property. Because of Late-Static-Binding (see http://php.net/lsb) 
static::$v will be late-bound to class C so you get the static value from C. 
This is perfectly correct. If you use self::$v you will be early-bound to A 
instead. 

Other than the E_STRICT about calling a non-static method statically, you should 
get no errors here because you are accessing a static property statically 
correctly.
 [2012-02-14 17:44 UTC] rasmus@php.net
Sorry, slightly misleading explanation there, I guess. But the clue is in the 
E_STRICT you get:

Strict Standards: Non-static method A::m() should not be called statically, 
assuming $this from incompatible context...

See the "assuming $this" there? Since you have instantiated class C and you are 
calling methods non-statically it assumes the non-static context. In the non-
static context var is going to be C because of LSB.
 [2012-02-14 17:44 UTC] lx at webactives dot ru
yes, i'm use Late-Static-Binding, but why engine bind variable to class C in 
context of class A? I'm not extend C from A. I can modify my code for 
demonstrate necessity late binding:

<?
error_reporting(E_ALL);
class A {
    static $v = 'A';
    function m(){
        echo 'var is '.(static::$v);
    }
}

class B extends A{ // for use Late-Static-Binding
    static $v = 'B';
}

class C {
    static $v = 'C';
    function test(){
        B::m();
    }
}
$test = new C();
$test->test();
?>

Of course, I'm can correctly use static keyword before method m() and problem 
have solved. But current engine behavior make work logic unpredictable.

In doc I have read: "In case of static method calls, this is the class 
explicitly named (usually the one on the left of the :: operator);" Why PHP 
engine bind  variable context for object caller class and not for class method 
owner?
 [2012-02-14 17:51 UTC] rasmus@php.net
Because you have written weird code, so we give you an E_STRICT telling you that 
your code is inconsistent and informing you which assumption we made to run your 
bad code. In most simple cases the end-result will be correct. In more complex 
cases, it won't, but that's why we point it out with the error.
 [2012-02-15 09:37 UTC] lx at webactives dot ru
thanks.
We have found this: 
http://ru.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.this

(static::) link some like ($this->) and not like (self::), but it is unexpectedly
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 12:01:27 2024 UTC