rspec/rules/S2037/php/rule.adoc

115 lines
2.9 KiB
Plaintext
Raw Permalink Normal View History

== Why is this an issue?
2021-04-28 16:49:39 +02:00
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
2021-04-28 16:49:39 +02:00
2022-02-04 17:28:24 +01:00
[source,php]
2021-04-28 16:49:39 +02:00
----
<?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
2021-04-28 16:49:39 +02:00
2022-02-04 17:28:24 +01:00
[source,php]
2021-04-28 16:49:39 +02:00
----
<?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
2021-04-28 16:49:39 +02:00
No issue is raised when ``++self++`` is used on a constant field, a private field or a private method.
[source,php]
2021-04-28 16:49:39 +02:00
----
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[]
'''
== Implementation Specification
(visible only on this page)
=== Message
Use "static" keyword instead of "self".
'''
== Comments And Links
(visible only on this page)
=== on 12 Oct 2014, 17:00:01 Freddy Mallet wrote:
@Ann, when discovering this rule it was not obvious for me to understand if there was or not a difference between self:: or static:: prefixes to access static functions of fields.
If my understanding is correct, there is no difference but obviously it's better to use static:: to prevent any misunderstanding.
If this is the case, I would associate this rule to the SQALE characteristic Maintainability > Understandability and to the tag pitfal
=== on 14 Oct 2014, 14:43:05 Ann Campbell wrote:
\[~freddy.mallet] I disagree about SQALE - the point of the rule is that when you use ``++self::++`` you're going to get the superclass' version, not the override - i.e. you won't get what you think you will.
=== on 21 Oct 2014, 20:29:24 Ann Campbell wrote:
\[~linda.martin] LGTM
endif::env-github,rspecator-view[]