in PHP, what is the difference between self and $this?

In very general terms, we can say that $this is used to reference the current object, whereas self is used to access the current class itself. But, there are more specific details we will discuss below that you should definitely know about. Since we believe strongly in examples as a teaching aid, take a look at the examples we have come up with below. In the examples below, we have a class called Animal and a derived class called Tiger. The Tiger class overrides the whichClass() function – which is also very important to note for the discussion that follows. Here is some code where we use the $this pointer:

class Animal {

     public function whichClass() {
        echo "I am an Animal!";
    }

   /*  Note that this method uses the $this keyword  so
       the calling object's class type (Tiger) will be 
       recognized and the Tiger class version of the
       whichClass method will be called.
   */

    public function sayClassName() {
       $this->whichClass();
    }
}

class Tiger extends Animal {

    public function whichClass() {
        echo "I am a Tiger!";
    }

}

$tigerObj = new Tiger();
$tigerObj->sayClassName();

Running the code above will output this:

I am a Tiger!

In the code above, we create an object of the Tiger class and call it $tigerObj. And, inside the Animal class’s version of the sayClassName() function, you can see the call to $this->whichClass(). Because the $this pointer always references the current object, and we are dealing with an object of the Tiger class above, the version of whichClass() that gets called is the one defined in the Tiger class. This is a valid example of polymorphism in PHP.

Using “self” instead

Now, if we change the “sayClassName()” function to use the self keyword instead of the $this variable, we would get a different result. So, suppose our code now looks like this – the only change we made is highlighted in red, everything else is exactly the same:


class Animal {

     public function whichClass() {
        echo "I am an Animal!";
    }

   /* This method has been changed to use the 
       self keyword instead of $this
   */

    public function sayClassName() {
       self::whichClass();
    }

}

class Tiger extends Animal {

    public function whichClass() {
        echo "I am a Tiger!";
    }

}

$tigerObj = new Tiger();
$tigerObj->sayClassName();

Running the code above will output this:

I am an Animal!

Using self in PHP can turn off polymorphic behavior and bypasses the vtable

So, what exactly is going on when we change the code to use “self” instead? When self is used, it automatically just calls the version of sayClassName() that is in the same class – so since self is being used within the Animal class, the version of sayClassName() that get’s called is the one that belongs to the Animal class. If we compare self to $this, then we can see that the $this keyword will just call the version of sayClassName() that belongs to the same class type as the calling object. Remember the $this variable is basically a reference to the current object, which in this case is of type Tiger. So, when the $this variable is used to call the sayClassName, it chooses to use the version that is in the Tiger class.

In the example above, self is essentially turning off polymorphic behavior by bypassing the vtable. If that is confusing you can (and probably should) read more about vtables over here: Vtables.

$this versus self when used inside a static function

Let’s say you try to use the $this pointer inside a static method. So, let’s say you have some code that looks like this:


class Animal {

    public static $name; 
	
   //trying to use $this in a static function:
	
    public static function nameChange()
    {
        $this->name = "Programmer Interview";
    }

}

$animalObj = new Animal();
$animalObj->nameChange();

What actually happens when you run the code above is that you will end up with this error: “Fatal error: Using $this when not in object context…”. Why do we get this error? Well, think about what you are doing here – you are using the $this pointer inside a static function. And, static functions can actually be called without using an object of the same class – you can call the nameChange function directly just using the class name like this:


Animal::nameChange();

If the static nameChange function is ever called directly by just using the Animal class name, then the $this variable really has no meaning because $this is meant to be used to reference the current object – and there is no object in the scenario presented above. And that is exactly why you get that error message.

Now, what if we try to use the self variable inside the static nameChange function instead? So our code now looks like this:

class Animal {

    public static $name; 
	
   //trying to use self in a static function:
	
    public static function nameChange()
    {
        self::$name = "Programmer Interview";
    }

}
$animalObj = new Animal();
$animalObj->nameChange();

The code above runs just fine, without error. And, this is actually a big reason why self is used – to access static members of the class. Now, just for the sake of showing you something else that is interesting, let’s make a small change so that $name is no longer a static member variable:


class Animal {

    //$name is no longer a static variable..
    public $name;  
	
   //trying to use self in a static function:
	
    public static function nameChange()
    {
        self::$name = "Programmer Interview";
    }

}

$animalObj = new Animal();
$animalObj->nameChange();

Now that $name is no longer a static variable, running the code above gives us an error: “Fatal error: Access to undeclared static property: Animal::$name”. What is the reason we get this error now?

Explanation of the “Fatal error: Access to undeclared static property” error

The reason we get that error is because we are not allowed to try to access non-static member variables inside a static function. This makes sense because static functions can be called without using an object – and because non-static member variables are meant to be used by objects this makes no sense. You can read more about this here (even though it’s in the context of C++, the same concept applies to PHP): Accessing non static members from a static function

$this vs self when accessing static members and calling static functions

Let’s see how $this and self behave when either trying to access static members or call static functions. Let’s start with the self keyword:

class Animal {

     public static function whichClass() {
        echo "I am an Animal!";
    }

    public function sayClassName() {
       self::whichClass();
    }
}

$animalObj = new Animal();
$animalObj ->sayClassName();

The code above uses the self keyword to invoke a static function – and it runs just fine without giving any errors. Now, let’s change it to use the $this variable instead of self:

class Animal {

     public static function whichClass() {
        echo "I am an Animal!";
    }

    public function sayClassName() {
       $this->whichClass();
    }
}

$animalObj = new Animal();
$animalObj ->sayClassName();

The code above actually runs just fine and returns “I am an Animal”. So, invoking a static function with the $this variable is not a problem. And that actually makes sense because static functions do not even need an object in order to be invoked.

Example of calling static member variable with $this

Invoking a static member variable with the $this pointer does not return an error, but is not recommended. Let’s take a look at an example to help clarify. Suppose you try to run the following code – note the use of $this to access the $name member variable:

class Animal {

    public static $name;

     public static function whichClass() {
        echo "I am an Animal!";
    }

    public function sayClassName() {
      $this->name = "My name is Animal";
    }
}

$animalObj = new Animal();
$animalObj ->sayClassName();

So, in the code above, we create an instance of the Animal class in $animalObj, and then we call the method sayClassName, which uses the $this pointer to access the static member variable $name. Running the code above runs without error. It is perfectly fine to access a static variable via the $this pointer. But, you should know that any change to that static variable will only affect the current instance/object, which isn’t really what you would expect if you change a static member variable. Confused? Well, check out this example:

class Animal {

    public static $name;

  
    public function setClassName() {

      $this->name = "My name is Animal";
      //echo $this->name;
    }
}

$animalObj = new Animal();

$animalObj2 = new Animal();


$animalObj->setClassName();


echo $animalObj->name;

echo $animalObj2->name;  //what happens here?

Note that we set the $name static variable for the $animalObj object by calling the setClassName method, but we do not set that variable for the $animalObj2 object. What do you think will happen when we try to output the value of the $name static variable in $animalObj2 (in this line: echo $animalObj2->name; )?

Well, if you guessed that it would output “My name is Animal” then you are actually wrong! You can verify this for yourself by running the simple code above. Yes, “echo $animalObj->name;” will output the text “My name is Animal”, but when a static member variable is set in one object using the $this pointer, that value does NOT transfer to other instances of the same class, even though it’s a static member variable and that behavior may be exactly what you would expect. It seems that it’s not even setting the static variable at all, and it’s just creating another non-static variable called $name that only belongs to that particular object. You can confirm this fact by trying to output the value of the static variable using the correct syntax: “echo Animal::$name;” – keep in mind that in PHP, static properties cannot be accessed through the object using the arrow operator ->.

You will see that nothing is output for the code above when you try “echo Animal::$name;”, even after setting what you may think is the static variable $name using $this. For this exact reason, in PHP, you should not use the $this pointer to set a static member variable – instead, you should just use the $self variable, which you can see an example of below.

Example of using self to access static member variable

Now, let’s say that we use the self keyword in the same example:

class Animal {

    public static $name;

     public static function whichClass() {
        echo "I am an Animal!";
    }

    public function sayClassName() {
      self::$name = "My name is Animal";
    }
}

$animalObj = new Animal();
$animalObj ->sayClassName();

Now, this code also runs just fine as well – self is accessing the static $name member variable that belongs to the Animal class, and that makes sense because no objects are involved or implied. If we try to output the value of the $name static member variable using the code “echo Animal::$name;”, then it will output just fine – because we correctly used the self keyword to set the static member variable. So, in PHP, it is always necessary to always refer to static variables using a static context (e.g by using self, or the class name).

Accessing a variable with same name as static member variable inside a function

But, another interesting question is what would happen if self is not used, and we just used the $name by itself like in this example:

class Animal {

    public static $name;

     public static function whichClass() {
        echo "I am an Animal!";
    }

    public function sayClassName() {
      $name = "My name is Animal";
    }
}

$animalObj = new Animal();
$animalObj ->sayClassName();

Well, in this scenario, the $name variable used in the sayClassName function is actually a local variable that is created inside the sayClassName function, and that is not the same static $name variable that belongs to the class as a whole. So, you would actually have to use the self variable if you want to reference the static member variable that belongs to the class as a whole.

Summary of the differences between self and $this

Finally, we are done. Let’s now go through a quick summary of the differences between self and $this that we covered in our examples above:

-self refers to the current class
-self can be used to call static functions and reference static
  member variables
-self can be used inside static functions
-self can also turn off polymorphic behavior by bypassing 
  the vtable
-$this refers to the current object
-$this can be used to call static functions
-$this should not be used to call static member
 variables.  Use self instead.
-$this can not be used inside static functions

Hiring? Job Hunting? Post a JOB or your RESUME on our JOB BOARD >>

Subscribe to our newsletter for more free interview questions.



FOLLOW Varoon Sahgal, Author of ProgrammerInterviewon

  • primo

    In the section entitled "Example of calling static member variable with $this", it is stated: "Note that we set the $name static variable for the $animalObj object by calling the setClassName method, but we do not set that variable for the $animalObj2 object."

    This is not actually correct. The static variable $name remains unaltered. It is a non-static variable – also named $name – which is changed.