References in a class to static class members (fields or methods) can be made using either ``++self::$var++`` or ``++static::$var++`` (introduced in 5.3). The difference between the two is one of scope. Confusingly, in subclasses, the use of ``++self::++`` references the original definition of the member, i.e. the superclass version, rather than any override at the subclass level. ``++static::++``, on the other hand, references the class that was called at runtime.


== Noncompliant Code Example

----
<?php

class Toy {

    public static function status() {
        self::getStatus();  // Noncompliant; will always print "Sticks are fun!" even when called from a subclass which overrides this method;
    }

    protected static function getStatus() {
        echo "Sticks are fun!";
    }
}

class Ball extends Toy {

    protected static function getStatus() {  // Doesn't actually get called
        echo "Balls are fun!";
    }
}

$myBall = new Ball();
$myBall::status();  // Prints "Sticks are fun!"
----


== Compliant Solution

----
<?php

class Toy {

    public static function status() {
        static::getStatus();  // Compliant
    }

    protected static function getStatus() {
        echo "Sticks are fun!";
    }
}

class Ball extends Toy {

    protected static function getStatus() {
        echo "Balls are fun!";
    }
}

$myBall = new Ball();
$myBall::status();  // Prints "Balls are fun!"
----


== Exceptions

No issue is raised when ``++self++`` is used on a constant field, a private field or a private method.

----
class A
{
    private static $somevar = "hello";
    const CONSTANT = 42;

    private static function foo()
    {
        $var = self::$somevar . self::CONSTANT;  // Should be OK
        self::foo();                               // Should be OK
    }
}
----


ifdef::env-github,rspecator-view[]
'''
== Comments And Links
(visible only on this page)

include::comments-and-links.adoc[]
endif::env-github,rspecator-view[]
