Req #77537 [Ver->Csd]: Unexpected behavior, when using static in constructor
| From: | nikic@php.net | Date: | Fri, 23 Jul 2021 07:39:41 +0000 |
| Subject: | Req #77537 [Ver->Csd]: Unexpected behavior, when using static in constructor | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-235273@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=77537&edit=1
ID: 77537
Updated by: nikic@php.net
Reported by: dirk dot gerigk at atraveo dot com
Summary: Unexpected behavior, when using static in
constructor
-Status: Verified
+Status: Closed
Type: Feature/Change Request
Package: Class/Object related
Operating System: Windows 10
PHP Version: 7.2.14
-Assigned To:
+Assigned To: nikic
Block user comment: N
Private report: N
New Comment:
I did end up writing that proposal (https://wiki.php.net/rfc/static_variable_inheritance). This
means that as of PHP 8.1 the result will be as written in the "expected result".
Previous Comments:
------------------------------------------------------------------------
[2021-02-18 16:58:19] nikic@php.net
The problem is that we're caching the constructor (and a few magic methods) in the class entry,
but end up storing the parent constructor there -- which is always going to be the same unless it
uses static variables, thus nobody noticed.
This is a bug, though I'm also increasingly tempted to write a proposal that changes the way we
handle static variables in methods, and not use a separate static variable scope on inheritance.
------------------------------------------------------------------------
[2021-02-18 16:03:58] dirk dot gerigk at atraveo dot com
I have tested in another way
class A {
public function test(){
static $test = 0;
print (++$test);
}
public function __construct(){
$this->test();
}
}
class B extends A {
public function __construct(){
parent::__construct();
}
}
class C extends A {}
$a = new A;
$a->__construct();
$b = new B;
$b->__construct();
$c = new C;
$c->__construct();
and the result is 121212
So, for now i will keep in mind:
* dont mess with the constuctor of a class
* do not use static variables in a constructor
Thanks for the time and work
------------------------------------------------------------------------
[2021-02-18 16:02:33] nikic@php.net
Oh, I missed that "new C" and "$c->__construct()" produce different results.
Agree that this doesn't seem right.
------------------------------------------------------------------------
[2021-02-18 15:50:42] dirk dot gerigk at atraveo dot com
Hi,
what i dont get is the different behavior of the twice call
$c = new C;
$c->__construct();
the first line calles A::__construct and shows 5
the second lines calls then the method with a separate static and shows 1
So this statement is not valid here:
"if the method is inherited, then it also gets separate static variables"
If this statement is right, then the two calls have to have 1 and 2 as result, no 5 and 1, or?
Normaly u dont call $c->__construct() on an existing object,
but why is direct call of __construct so different?
But thanks, for the reply.
------------------------------------------------------------------------
[2021-02-18 11:01:26] nikic@php.net
In PHP, static variables are bound to a specific method -- if the method is inherited, then it also
gets separate static variables. This means that C::__construct() has static variables independent of
A::__construct().
I'm going to close this as a duplicate of bug #74198, because the behavior of static variables
in methods and their interaction with inheritance is currently not documented.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=77537
--
Edit this bug report at https://bugs.php.net/bug.php?id=77537&edit=1