11

So I recently ran across a code segment like this:

private static function FOO() {
        static $c = null;
        if ($c == null) {
            $c = new ParentClass_InnerClass();
        }
        return $c;
    }

So what is up with this code? How is this different from:

private static $C;

//other methods and fields    

private static function FOO() {
    if(!$self::c) {
        $self::c = new ParentClass_InnerClass();
    }
    return $self::c;
}

Or are they even the same concept?

7
  • 2
    The second example is technically not correct. It should be self::$c or static::$c. Commented Oct 24, 2013 at 15:17
  • Read more at PHP: Variable scope - Manual about static local variables Commented Oct 24, 2013 at 15:17
  • 1
    @ComFreek Whoops, yep. Commented Oct 24, 2013 at 15:18
  • $c == null and !$c is not entirely the same thing, is it? Commented Oct 24, 2013 at 15:19
  • @SimonAndréForsberg How do you mean in this case? It's not like $c is ever going to be a boolean false. You are really nitpicking at a piece of code that is irrelevant to the question. Commented Oct 24, 2013 at 15:22

3 Answers 3

9

They are, essentially, the same concept, though the scope is different:

class Foobar
{
    private static $c = null;
    public static function FOO()
    {
        if (self::$c === null)
        {
            self::$c = new stdClass;
        }
        return self::$c;
    }
    public static function checkC()
    {
        if (self::$c === null)
        {
            return false;
        }
        return self::$c;
    }
}

Foobar::checkC();//returns false, as $c is null
//function checkC has access to $c
$returned = Foobar::FOO();//returns object
if ($returned === Foobar::checkC())
{//will be true, both reference the same variable
    echo 'The same';
}

Whereas, if we were to change the code to:

class Foobar
{
    public static function FOO()
    {
        static $c = null;
        if ($c === null)
        {
            $c = new stdClass;
        }
        return $c;
    }
    public static function checkC()
    {
        if ($c === null)
        {
            return false;
        }
        return $c;
    }
}

We will get a notice when calling checkC: undefined variable. the static variable $c is only accessible from within the FOO scope. A private property is scoped within the entire class. That's it really.
But really, do yourself a favour: only use statics if you need them (they're shared between instances, too). And in PHP, it's very rare you'll actually need a static.

Sign up to request clarification or add additional context in comments.

3 Comments

Hi! I get the difference, but I have to ask how come it doesn't reset $c = null on every call to FOO()? Thanks in advance
@sale108 Haven't used PHP in 5 years, but a variable in a function declared as static creates a zval in memory with whatever value you assign to it in the declaration/initialisation statement. Whatever happens to that zval next updated the same object in memory. Essentially, think of static $c = null; as something that is executed once, and then skipped in subsequent calls
Thanks! That's enough for me to investigate on my own :)
7

They're the same concept, except that in the first code block, the static variable is local to the function, and such a static variable could be used in any function, even outside the context of a class:

function test() {
    static $counter = 0;
    return $counter++;
}

echo test(); // 0
echo test(); // 1

3 Comments

How? Its a private function. You mean another public function could pass the variable out?
No, this kind of variable is local to the function and cannot be used outside of it. I mean that you could use a static variable in any function, even if it's not a class method.
I updated my answer with an example in a simple function, outside of a class.
1

In the top example you can access $c only from the local scope (FOO()) and in the bottom example you can access $c from the entire class, so not only form FOO().

2 Comments

So its forcing the singleton pattern for a private variable, but since its forcing you to go through FOO() you are guaranteeing it is initialized?
@thatidiotguy: yes, but forcing a class to be initialized can be done using the Factory pattern, too, aswel as by using a constructor, and the new keyword Don't use singletons

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.