php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #66627 Static variables in inherited classes not explained
Submitted: 2014-02-02 23:52 UTC Modified: 2021-03-03 18:18 UTC
From: kulakov74 at yandex dot ru Assigned:
Status: Verified Package: Documentation problem
PHP Version: 5.4.24 OS: Any
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: kulakov74 at yandex dot ru
New email:
PHP Version: OS:

 

 [2014-02-02 23:52 UTC] 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; 


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-03-03 18:18 UTC] cmb@php.net
-Status: Open +Status: Verified
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 19:01:28 2024 UTC