php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #74198 static (variables) docs do not explain behavior in class methods
Submitted: 2017-03-02 11:40 UTC Modified: 2017-03-10 17:59 UTC
Votes:1
Avg. Score:1.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: cca dot alexk at gmail dot com Assigned:
Status: Verified Package: Variables related
PHP Version: 7.1.2 OS: MacOS/Linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2017-03-02 11:40 UTC] cca dot alexk at gmail dot com
Description:
------------
Steps to reproduce:
1. Create object of class with method with local static variable
2. Assign value to this local variable
3. Create new object of that class
4. Check value of this variable


Test script:
---------------
<?php

class Foo
{
    protected $bar;
    
    public function __construct($bar)
    {
        $this->bar = $bar;
    }
    
    public function bar()
    {
        return $this->foo();
    }
    
    public function foo()
    {
        static $bar;
        if (!$bar) {
            $bar = $this->bar;
        }
        return $bar;
    }
}

var_dump((new Foo(123))->bar());
var_dump((new Foo(456))->bar());

Expected result:
----------------
int(123)
int(456)

Actual result:
--------------
int(123)
int(123)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-03-02 11:48 UTC] requinix@php.net
-Summary: Local static variable not update after create new object of class +Summary: static (variables) docs do not explain behavior in class methods -Type: Bug +Type: Documentation Problem
 [2017-03-02 11:48 UTC] requinix@php.net
This is expected behavior: static variables defined in a class method are shared across all instances of that class. Just like static properties.
The $bar in Foo(123)::foo and Foo(456)::foo are the same variable.

However I don't see this clearly documented - simply that variables don't lose value after leaving scope - and it's not necessarily obvious that Foo::foo is really the same function/method across every instance of Foo.
http://php.net/manual/en/language.variables.scope.php#language.variables.scope.static
 [2017-03-02 12:24 UTC] cca dot alexk at gmail dot com
Thank you for your answer.

For me this is not expected behavior in scope context. I agree with that behavior if I use class static variable instead of method static variable. There are different scopes I think.
 [2017-03-02 12:43 UTC] requinix@php.net
That's why I changed this to a documentation bug.

Every Foo instance gets the same __construct, bar, and foo methods; classes work because they make use of $this, which contains the instance-specific data (like Foo::$bar). Since they're the same methods, the "static $bar" in foo() will be the same $bar everywhere, so in that way a static variable in a class method works exactly like a static variable in a global function.

https://3v4l.org/eUOJq
 [2017-03-10 17:59 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2017-03-10 17:59 UTC] cmb@php.net
> […] static variables defined in a class method are shared across
> all instances of that class. Just like static properties.

However, while static properties are shared for instances of all
child classes, static variables defined in methods are not, see
<https://3v4l.org/eKGWo>.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Sat May 25 00:01:27 2019 UTC