In the previous articles, we’ve seen how we can access the methods inside of the object using the object operator. This is done when an object is instantiated. We’ve already created a Car object and accessed the drive() method. You did this with the object operator, ->, after instantiating the object: $lamborghini->drive();
<?php
Class Car {
public function drive( $is_car_on = false ) {
if ( $is_car_on ) {
echo "I'm driving";
} else {
echo "You gotta turn me on";
}
}
}
$lamborghini = new Car();
$lamborghini->color = "Black";
$lamborghini->make = "Lamborghini";
$lamborghini->model = "Diablo";
$lamborghini->drive();
$lamborghini->drive( true );
PHP — P46: Methods
You should also know that you can instantiate an object inside of another object and reference the other object’s methods the exact same way. But, what happens when you need to reference methods or properties from within the object itself? That’s where $this, the keyword, comes into play. It just means that the object is referencing itself.
If you considered yourself the object, and you wanted to access yourself, you would use the I pronoun. If the object wants to access itself, it uses $this.
Enough explanation; let’s look at an example. The Dog and Car classes just serve so much purpose in explaining basic concepts, so we’ll stick with those.
<?php
class GermanShepherd {
const HAS_HEART = true;
const HAS_TAIL = true;
public $eye_color = "Brown";
public $dob = "January 30, 2017";
public $does_shed = true;
public $kingdom = "Animalia";
public $phylum = "Chordata";
public $class = "Mammalia";
public $order = "Carnivara";
public $family = "Canidae";
public $genus = "Canis";
public $species = "Canis Lupus";
public $subspecies = "Canis Lupus Familiaris";
public $breed = "German Shepherd Dog";
public $fur_color = "Black and Tan";
public function walk() {
echo "I'm walking";
}
public function bark() {
echo "I'm barking";
}
public function sleep( $energy_level = 100 ) {
if ( $energy_level < 40 ) {
echo "I'm sleeping";
} else {
echo "I don't want to sleep";
}
}
}
The code above is the exact same code we ended in the previous article.
If we’re the object, and we’re trying to reference ourselves, I may ask myself what is my eye-color? The object above has the property $eye_color, and it just so happens to be Brown. Let’s create a method called get_eye_color() that returns the value of the $eye_color property.
<?php
class GermanShepherd {
public $eye_color = "Brown";
public function get_eye_color() {
return $this->eye_color;
}
}
$gs_dog = new GermanShepherd();
echo $gs_dog->get_eye_color();
The get_eye_color() method returns the object’s eye color. We were able to access the $eye_color property by prepending $this-> to the $eye_color property within the method. To test it, we instantiate the object and call the get_eye_color() method.
You may be asking yourself why didn’t we just access the $eye_color property directly. Visibility modifiers will be discussed in a later article where the answer to that question will become evident. It’s usually not great practice to leave all of your properties set to public. You want to use methods whenever you access or modify properties of an object. Let’s take a look at another example that might help you visualize this better.
We have a property called $does_shed; it’s currently set to true. For a good user experience, we don’t want to say true when someone asks us if the dog sheds. We want to reply with either yes or no.
To illustrate this, let’s create a method called does_shed(). When we call it, we just want the method to return either yes or no. With the help of the ternary operator, we can return the correct value. We again access the $does_shed property inside of the does_shed() method with the use of $this keyword.
<?php
class GermanShepherd {
public $does_shed = true;
public function does_shed() {
return ( $this->does_shed ) ? "Yes" : "No";
}
}
$gs_dog = new GermanShepherd();
echo "Does the German Shepherd Shed? " . $gs_dog->does_shed() . "<br>";
When we ask the question later, “Does the German Shepherd shed?” our response is simply Yes.
You’re still thinking that you can call the property directly. Got it. Let’s make it annoying. That’s usually when developers start doing things the right way…when they’re annoyed. What if we wanted to return the scientific classification. You would have to return each one of the properties individually if you didn’t want to return it as a method call. With a method, we can return the array of data all at once.
<?php
class GermanShepherd {
public $kingdom = "Animalia";
public $phylum = "Chordata";
public $class = "Mammalia";
public $order = "Carnivara";
public $family = "Canidae";
public $genus = "Canis";
public $species = "Canis Lupus";
public $subspecies = "Canis Lupus Familiaris";
public $breed = "German Shepherd Dog";
public function get_scientific_classification() {
return [
"kingdom" => $this->kingdom,
"phylum" => $this->phylum,
"class" => $this->class,
"order" => $this->order,
"family" => $this->family,
"genus" => $this->genus,
"species" => $this->species,
"subspecies" => $this->subspecies,
"breed" => $this->breed
];
}
}
$gs_dog = new GermanShepherd();
var_dump( $gs_dog->get_scientific_classification() );
One more example should help solidify the concept, even though I think you already got it. Time to talk cars again.
<?php
class Car {
const HAS_HEADLIGHTS = true;
const HAS_TAIL_LIGHTS = true;
const HAS_TURN_SIGNALS = true;
public string $color;
public string $make;
public string $model;
public int $year;
public int $fuel_type = 93;
public int $hp;
public int $tq;
public string $transmission = "6 Speed Manual";
public string $vehicle_type = "Coupe";
public float $exterior_height;
public float $exterior_width;
public float $exterior_length;
public string $exterior_um = "in";
public float $weight;
public string $weight_um = "lbs";
public function turnOn() {
echo "I'm on";
}
public function turnOff() {
echo "I'm off";
}
public function drive( $is_car_on = false ) {
if ( $is_car_on ) {
echo "I'm driving";
} else {
echo "You gotta turn me on";
}
}
}
This first thing that I see that bothers me is the parameter $is_car_on in the drive() method. We want the car to be able to tell us if it’s on, not for us to tell the car that it’s on. The first step is to make that parameter a property. We can then check if the car is on, and if it is, return “I’m driving” otherwise, “You gotta turn me on.”
<?php
class Car {
public bool $car_on = false;
public function drive() {
if ( $this->car_on ) {
return "I'm driving";
} else {
return "You gotta turn me on";
}
}
}
We also have two methods, turnOn() and turnOff(), that can be used to turn the car on and off, or change the $car_on property from true to false and vice-versa. We also want to check and make sure that the car is not already on when we’re trying to turn it on and similarly we want to check if the car is off that we’re not trying to turn it off again.
<?php
class Car {
// ...
public bool $car_on = false;
public function turnOn() {
if ( $this->car_on ) {
return "The car is already on.";
}
$this->car_on = true;
return "The car has been turned on.";
}
public function turnOff() {
if ( $this->car_on ) {
$this->car_on = false;
return "The car has been turned off.";
}
return "The car is already off.";
}
}
Throughout this article, we’ve called various properties, but we can also call other methods within the object using $this keyword. Instead of saying “The car is already on,” let’s use the vehicle’s make and model. Although we could just call the properties from within the method, let’s create a get_make_and_model() helper method that returns a formatted string for us.
<?php
class Car {
public string $make;
public string $model;
public function get_make_and_model() {
return $this->make . " " . $this->model;
}
}
We can then update our turnOn() and turnOff() methods to use the get_make_and_model() method and replace the generic “car” string with the actual make and model of the object.
<?php
class Car {
public string $make;
public string $model;
public bool $car_on = false;
public function turnOn() {
if ( $this->car_on ) {
return "The " . $this->get_make_and_model() . " is already on.";
}
$this->car_on = true;
return $this->get_make_and_model() . " has been turned on.";
}
public function turnOff() {
if ( $this->car_on ) {
$this->car_on = false;
return "The " . $this->get_make_and_model() . " has been turned off.";
}
return "The " . $this->get_make_and_model() . " is already off.";
}
public function get_make_and_model() {
return $this->make . " " . $this->model;
}
}
Finally, let’s do some testing. Instantiate the object and set the make and model of your vehicle. Go through the various options, such as turning the vehicle on and off before-and-after driving it.
<?php
$subaru = new Car();
$subaru->make = "Subaru";
$subaru->model = "WRX STi";
echo "Car: " . $subaru->get_make_and_model() . "<br>";
echo "Drive: " . $subaru->drive() . "<br>";
echo "Turn On: " . $subaru->turnOn() . "<br>";
echo "Drive: " . $subaru->drive() . "<br>";
echo "Turn On: " . $subaru->turnOn() . "<br>";
echo "Turn Off: " . $subaru->turnOff() . "<br>";
echo "Drive: " . $subaru->drive() . "<br>";
echo "Turn Off: " . $subaru->turnOff() . "<br>";
The output above should be pretty fun. You’ll be reminded that you need to turn the car on before you can drive it. That’s it for $this. It’s a concept that’s actually pretty straightforward but is approached like it’s difficult. Once you get the hang of it, you’ll quickly realize that it’s nothing to stress about.