Doc #66627 [Opn->Ver]: Static variables in inherited classes not explained

From: 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

« previous php.doc.bugs (#18616) next »