PHP self:: vs $this

For people unfamiliar with Object Oriented Programming (OOP), using classes / objects can be a bit of an endeavor your first time through. However, OOP can be extremely powerful in making your code dynamic and helping to minimize your efforts when developing. It's also an excellent method for sort of lumping your code into categories that make sense.

One of the most common mistakes I see, is that people use $this when they should really be using self::. To understand when we should use each, lets create an example.

So lets say that in some PHP script, I want to be able to create some "vehicle" objects. I do this because, I want an easy way to keep track of how many tires each vehicle has, what color paint it has, and I want a function that builds me an array of cars. So my class might look something like this:

<?php
class Vehicle {
    public $numberOfTires = 0;
    public $paintColor = null;

    public function __construct($tires, $color)
    {
        $this->numberOfTires = $tires;
        $this->paintColor = $color;
    }

    public function paint($color)
    {
        $this->paintColor = $color;
    }

    public static function buildCars($amount)
    {
        $cars = array();
        for($i = 0; $i < $amount; $i++)
        {
            $color = self::getRandomVehicleColor();
            $cars[] = new Vehicle(4, $color);
        }

        return $cars;
    }

    public static function getRandomVehicleColor()
    {
        $colors = array('black', 'blue', 'red');
        return $colors[mt_rand(0, count($colors)-1)];
    }
}

So now let's break down what all of that actually does. First we have our __constructor function. This is a kind of magic PHP function that is in every class. Even if you don't define it, it is there, just empty. This is what gets called when you use new Vehicle(4, 'black');. Notice, that inside of the constructor we are setting those public variables, defined at the top of the class typically. This is essentially creating our vehicle object. So that way in our main script we can do things like this:

<?php
$myCar = new Vehicle(4, 'black');
$myBicycle = new Vehicle(2, 'red');

echo $myBicycle->numberOfTires; //echo's the number 2
echo $myCar->paintColor; //echo's the string 'black'

So you noticed that when i used $this inside of the class, I was referring to that specific instance of the object, in this case vehicle. For added re-enforcement I created the paint() function so that I can show you how you can leverage this even further. Say you created your object of $myCar, but now you want to repaint your car. That's easy enough to do by creating a function (albeit a very simple one) and then calling that function on the object you want it to apply to. Like this:

<?php
$myCar = new Vehicle(4, 'black');
echo $myCar->paintColor; //echo's the string 'black'
$myCar->paint('blue');
echo $myCar->paintColor; //echo's the string 'blue' now

So we've covered that $this is used in order to apply functions to the instance of the object. But now we want a function to create us a bunch of instances. This is something that I would still classify as being related to the object, so it makes good sense for me to create a function inside of that class to do that for me. In this case, we want to create us a bunch of cars, which are vehicles with 4 tires. We'll do this by calling a static function we built in our class.

<?php
$cars = Vehicle::buildCars(25); //return an array of 25 vehicle objects;

So, now to talk about self:: You'll notice that inside of our buildCars() function we use self:: to call the getRandomVehicleColor() function. Notice that this is also a static function, in other words, I don't actually have to have a vehicle instance, to pick a random vehicle color. These are the instances when you use self and not $this. Bottom line, $this is referencing the current instance of the object and is applied to non-static functions, self:: is for static functions that are not dependent on having an instance of the object to use or if you want to call a function from the creating class.

Loading Conversation