Doc #66627 [Opn->Ver]: Static variables in inherited classes not explained
| From: | cmb@php.net | Date: | Wed, 03 Mar 2021 18:18:39 +0000 |
| Subject: | Doc #66627 [Opn->Ver]: Static variables in inherited classes not explained | ||
| References: | 1 | Groups: | php.doc.bugs |
| Request: | Send a blank email to doc-bugs+get-18616@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=66627&edit=1
ID: 66627
Updated by: cmb@php.net
Reported by: kulakov74 at yandex dot ru
Summary: Static variables in inherited classes not explained
-Status: Open
+Status: Verified
Type: Documentation Problem
Package: Documentation problem
Operating System: Any
PHP Version: 5.4.24
Block user comment: N
Private report: N
New Comment:
For reference:
<https://wiki.php.net/rfc/static_variable_inheritance>.
Previous Comments:
------------------------------------------------------------------------
[2014-02-02 23:52:22] kulakov74 at yandex dot ru
Description:
------------
Studying Traits (php.net/traits), I found the example (#9) with static variables which produced
different results from what I expected, that is the static variable $c was not shared in the 2
classes using the trait Counter. I tried some tests with traits and classes and came to the
conclusion that the behaviour is correct but not documented well in the case of class inheritance.
Static variables are really tied to the function they are declared in but if the function is a class
method and the class is inherited from, the method may be internally duplicated (I believe it's
implemented this way) to the child class where it actually becomes a different (albeit identical)
method hence it holds its own copy of the same static variable. By duplicating I mean the resulting
behavior is just like the methods are really declared in the child.
In my tests I found out the following:
-A static variable in a class method acts just like one in a global function (that's almost
obvious).
-If the class is extended then all its methods except the constructor (& destructor) and the
private methods are internally duplicated to the child. Public and protected methods can be called
in the child hence they need to be duplicated in it. Constructors and privates are specific to the
base class hence their static vars are shared between all children.
Traits exhibit similar behavior. This is my understanding of the behavior, it may be wrong but
anyway the behavior should explained in more detail in the manual.
Related bugs:
https://bugs.php.net/bug.php?id=39713
https://bugs.php.net/bug.php?id=62547
https://bugs.php.net/bug.php?id=63454
Test script:
---------------
class B{
function __construct(){static $con=0; $con++; echo(get_class($this)."::con:$con; ");}
function pub(){static $pub=0; $pub++; echo(get_class($this)."::pub:$pub; ");}
function test(){$this->prv(); $this->prot();}
private function prv(){static $prv=0; $prv++; echo(get_class($this)."::prv:$prv; ");}
protected function prot(){static $prot=0; $prot++; echo(get_class($this)."::prot:$prot;
");}
}
class C1 extends B{} class C2 extends B{}
$B1=new B; $B2=new B; $C1=new C1; $C2=new C2; echo("\n");
$B1->pub(); $B2->pub(); $B1->pub(); $B2->pub(); echo("\n");
$C1->pub(); $C1->pub(); $C2->pub(); $C2->pub(); echo("\n");
$B1->test(); $B2->test(); echo("\n");
$C1->test(); $C1->test(); $C2->test(); $C2->test(); echo("\n");
Expected result:
----------------
---
Actual result:
--------------
B::con:1; B::con:2; C1::con:3; C2::con:4;
B::pub:1; B::pub:2; B::pub:3; B::pub:4;
C1::pub:1; C1::pub:2; C2::pub:1; C2::pub:2;
B::prv:1; B::prot:1; B::prv:2; B::prot:2;
C1::prv:3; C1::prot:1; C1::prv:4; C1::prot:2; C2::prv:5; C2::prot:1; C2::prv:6; C2::prot:2;
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=66627&edit=1