In-depth understanding of self and this in PHP

understanding of self and $this in PHP

This is the most interesting and most commonly confusing topic among developers while working on any project. In this tutorial, we’ll start understanding of self and this in PHP & will see when to use self and $this in PHP while development & will understand how can we use self & $this in various situations.

So, the basic question comes in mind, what is self? and what is $this?

As we know that when we create any class then that class contains constants, variables aka “properties”, and functions aka “methods”.

In OOP, to access these class components, we can use either $this OR self in PHP. It means, in PHP only we can use these ways to get control over different class components. This may differ based on the programming languages you use.

What is self:: in PHP?

A class may contain an amalgamation of static & non-static members. To access static members of the class, we use self along with scope resolution operator ::. This Scope Resolution Operator is also called Paamayim Nekudotayim (means double-colon in Hebrew) or in simpler words, a double colon. Static methods are also specified as namespaced global functions.

Static functions and variables are associated with the class itself. It means whatever the value static variables hold, it will be shared among all the other created objects.

In simple words, suppose we update static variable using $objBooks, and then using $newObjBook we again tried to access the same static variable then we’ll get the same value and vice-versa.

Let’s see code in action-

<?php

class books
{

  public static $bookId = 0;


  public function updateBookInfo($id)
  {
    self::$bookId = $id;
  }

  public function getBookId()
  {
    return self::$bookId;
  }

}
// object 1
// before update
$objBooks = new books;
$objBooks->updateBookInfo(1);

echo $objBooks->getBookId();

// object 2
$newObjBook = new books;
echo $newObjBook->getBookId();
$newObjBook->updateBookInfo(2);

// after update
echo $objBooks->getBookId();
echo $newObjBook->getBookId();
// OUTPUT

1
1
2
2

Okay, so in this example, we have created a book class in which we have defined one static variable ($bookId) and to access it, we have defined getBookId() method. Now, first of all, we have created a book object and assign value to a static variable $bookId using updateBookInfo() method.

This method uses self:: syntax to update a class variable $bookId. Once assigned, it can now be available for use inside and outside of the class.

We can access this value using getBookId() method from inside or outside of the class OR directly using a class (book::$bookId) from outside of the class.

Next, we have defined another object $newObjBook. Now, we will get the same value of $bookId using this object as well because of the property of the class-level variable.

Once, we update the value of this static variable using updateBookInfo() e.g., 2 in our case, then that value becomes available to all the objects (including current, next, and previous objects).

So, $objBooks->getBookId(); & $newObjBooks->getBookId(); will give same value i.e., 2

How can we access static members of the class?

So, we have seen a basic understanding of how to define static variables, how we can access it and how all instances of a class share the same static variable.

There are different ways with which we can access static variable.

So, static variables & functions are accessed via self::variableName & self::functionName() respectively (from inside of the class). In the example shown above, a static variable is accessed using self::$bookId when we are inside of the class.

But from outside of the class, we need to use book::$bookId because static variables are class level variables. So there is no need to create a class object to access its static variables. We can directly access it via className then scope resolution operator ( :: ) followed by a variable name.

Sometimes we also see parent:: keyword whose task is to access parent class methods. This syntax is usually found inside the method like __construct(){} where we include it at the very first line inside a function to inherit all the parent class constructor data. We can also use parent:: in other methods as well. But the truth is there is no such relation between self:: & parent::.

What is $this in PHP?

$this represents the reference to the current object of the class. $this is the pseudo-variable created as soon the object of the class is created and is available to use once that class method is called from within an object context.

Let’s understand the $this using basic example-

<?php

class books
{
  public $bookId = 0;
  
  public function setBookId($id)
  {
    $this->bookId = $id;
  }
  public function getBookId()
  {
    return $this->bookId;
  }
}

$objBook = new books;
$objBook->setBookId(123);
echo $objBook->getBookId();
// OUTPUT

123

As we can see, we’ve defined two methods in class books and one is used to set bookId and another is used to get the bookId. For this, we used $this variable because we are inside of the class and we are dealing with class non-static variables from within the object context.

So, what does $this contains?
$this contains all the properties available within the class. There may be a misconception that when we print $this then it will give a list of all the members within the scope of the class.

But this is NOT true. $this will print all the existing and new variables associated with the class itself.

Yes, that’s true. We can also add new variable(s) dynamically for temporary use to the class. You may be confused now because we’ve seen so many examples which contains use of properties defined within class.

Let’s use the same example of book class and define dynamic variables defined outside of the class.

<?php

class books
{
  public $bookId = 0;
  
  public function setBookId($id)
  {
    $this->bookId = $id;
  }
  public function getBookId()
  {
    return $this->bookId;
  }
  public function getCurrentObjInfo() {
      print_r($this);
  }
}

$objBook = new books;
$objBook->setBookId(123);
$objBook->name = "Jack";
echo $objBook->getCurrentObjInfo();
// OUTPUT

books Object 
( 
   [bookId] => 123 
   [name] => Jack 
)

We’ve defined a new method getCurrentObjInfo() and inside it, we have printed current object by passing $this parameter. At line number 22, we have defined a new variable and assigned it to object $objBook.

So, when we called this new method getCurrentObjInfo() then it will not only print existing variables but also newly defined dynamic variables as well.

Now, let’s discuss the main topic.

When to use self:: in PHP?

This the biggest question everyone faced while developing any software. Which class methods / properties should be static and WHY?

In the above, we’ve seen that $this represents the reference to the current object of the class, whereas self refers to the current class itself.

To understand this let’s create a person class and then we will see how using static properties/methods can be useful.

<?php

class Person
{
  private $name = '';
  private $age  = '';
  private $address = '';
  private $familyMembers = '';

  public static $votingAge = 18;

  public function __construct($name, $age, $address, $familyMembers)
  {
    $this->name   = $name;
    $this->age    = $age;
    $this->height = $address;
    $this->weight = $familyMembers;
  }

  public function get_name()
  {
    return $this->name;
  }

  public function get_age()
  {
    return $this->age;
  }

  public function get_address()
  {
    return $this->address;
  }

  public function get_family_members()
  {
    return $this->familyMembers;
  }

  public static function set_voting_age($age)
  {
    self::$votingAge = $age;
  }

  public static function get_voting_age()
  {
    return self::$votingAge;
  }
}

So, basically we have defined Person class and also added four properties name, age, address & familyMembers.

We then created static variable votingAge because declaring votingAge static, we are making sure that every object created using Person class should contain the same static votingAge value.

This was we make sure that even if we created as many objects of person class as possible but all the objects will share the same votingAge.

Another advantage of creating static property OR making get_voting_age() method as static is that we do not need to create a Person class object to access the default value of votingAge. We can directly access it by using Person::get_voting_age()

When to use $this in PHP?

In contrast to when to use self:: in PHP, using $this only useful when we actually need to create an object of the class to define and access the non-static members of the class.

$this is using inside the class methods only. So once object of class (e.g., Person) is created then to access all the members we need to use $this pseudo-variable.

<?php

class Person
{
  private $name = '';

  public function __construct($name)
  {
    $this->name   = $name;
  }

  public function get_name()
  {
    return $this->name;
  }

We have reduced above example and just used get_name() function to access name of the person. As this property name can have different name depending upon the value passed to the constructor.

So, to access this property we need to use $this variable.

In a nutshell, lets see the difference between self:: and $this.

Difference in self and $this in PHP

self $this
self refers to the current class itself $this represents the reference to the current object of the class
Do not need to instantiate an object to access static members Needs object creation to access methods and variables
self:: is used to access static variables/method of the class $this is used to access non-static variables/method of the class

Conclusion:

We have seen in-depth understanding of self and $this in PHP. So, basically, we need to make sure that while creating any class, what is the purpose of this class and how different components of the class will help in making that class complete. Once we made our decision final then we can use appropriately when to use self and when to use $this.