So what exactly is this static self in PHP?

Michal Tuček
5 min readFeb 15, 2021

Using references in PHP can be sometimes confusing especially if you don’t exactly understand their purpose. Let’s take a look at $this, self and static references using simple examples to explain their usage in an easy to understand way.

$this

Let’s start by taking a look at the following example:

Executing the script above will result in echoing:

0
1

There’s no doubt about it since $this always refers to the instance itself on which the method is called (or the attribute accessed).

Since there’s no multiple inheritance in PHP (yet) you can imagine it simply as a queue of classes where it flows as the inheritance goes from the foremost child to rearmost parent.

When it comes to $this think of it as a reference to the first class in the line:

What the first class says (specifies/defines) goes and has the highest priority in the hierarchy no matter what the other classes say.

In the example above there’s a method getAttribute() defined in the ParentClass.

Calling this method on an instance of the ParentClass will give us 0 since that’s the value defined for the attribute inside the ParentClass.

Calling this method on an instance of the ChildClass will give us 1. You could argue that the method getAttribute() is defined in the ParentClass which is true but as we said earlier “what the first class in line says goes” and as we can see, ChildClass has changed the definition of the attribute.

self

When you come around the self reference you can make a wrong assumption that self is just a $this but in a static scope. Let’s try to prove that assumption on the following example:

If self would really be just a $this but in a static scope we would expect the script to echo:

0
1
2

But when we really execute the script it will result in echoing:

0
1
1

As we can see we proved that our initial assumption was wrong but that still doesn’t answer the question of what exactly is self reference?

For starters let’s stick with the definition we’ve used when talking about $this that “you can imagine it simply as a queue of classes where it flows as the inheritance goes from the foremost child to rearmost parent”.

The main difference here is the part “what the first class says (specifies/defines) goes” as we’ve seen earlier. No matter the overriding of theattribute where we’ve set a different value we’ll still get the result from the class where the method was defined. But there are two classes that define the same method where ChildClass is overriding the ParrentClass. So what really matters is the last definition od the called method.

With that in mind, we could say the following about the self reference:

Starting from the foremost child the first class with the occurrence of the called method is also the scope in wich we will execute the called method.

As we go along the inheritance chain we’re searching the definition of the called method and as we find the first occurrence we don’t care if the later classes have their occurrences. Calling the found method will use it’s class values instead of the one that we’ve specified in the instance on which we were calling the method in the first place.

static

Remember how we’ve assumed that self is just a $this in the static scope? Even though we were wrong there really is a variation of $this reference in the static and it’s (surprisingly) called static.

Let’s dive right into an example:

Executing the script above will result in echoing:

0
1
2

Even though the method getAttribute() is defined in the ParentClass we’re using the static reference by which we’re basically saying:

Whatever class will call this method in an inheritance chain (in the case that no other class will override it along the way) it’ll be executed it in the scope of that class using its own definitions.

This is also a common practice when working with abstract classes that forces their children to implement some attribute or method which the abstract class is counting on in some other method using a static reference as shown in the following example:

Executing the script above will result in echoing:

0
1
1

GrandChildClass is not forced to implement the abstract method getAttribute() since one of his ancestors has already done so. Thanks to the implementation of the static reference in the AbstractClass we’re able to call the method getAttribute() in the scope of its children instead of its on scope.

Summary

Since there’s no multiple inheritance in PHP (yet) you can imagine it simply as a queue of classes where it flows as the inheritance goes from the foremost child to rearmost parent.

When it comes to $this

What the first class says (specifies/defines) goes and has the highest priority in the hierarchy no matter what the other classes say.

When it comes to self

Starting from the foremost child the first class with the occurrence of the called method is also the scope in wich we will execute the called method.

When it comes to static

Whichever class will call this method in an inheritance chain (in the case that no other class will override it along the way) it’ll be executed it in the scope of that class using its own definitions.

You might be wondering why $this uses a $ sing where self and static don’t. The reason behind it is quite self-explanatory since $this (hence the $ sign) is on an instance level but self and static don’t necessarily need an instance in order to be called.

Sources

--

--