Close

January 16, 2014

Starting OOP in PHP, Part 2

In the first part, we discussed the bare basics of what a class is in PHP and how visibility works. In this part, we will be covering the some “magic” methods and inheritance. After the article, you should have enough to get you up and running with object orientated programming in PHP.

Magic in the code…

On the classes that we create their are some special functions that will make the use of the classes much easier, these methods are referred to as magic methods.  The first we will cover is the __construct() method. You will notice the double underscore in front of the name of the method, this is what magic methods within PHP classes are identified with.

<?php
class Task
{
    public $name;

    public function __construct($name = "DefaultTask")
    {
        echo "Task name set to: " . $name;
        $this->name = $name;
    }

    public function printName()
    {
        return "The task name is : " . $this->name;
    }
}

$task = new Task("MyTask");
echo $task->printName();
$task2 = new Task();
echo $task2->printName();

In the code above, we see the construct method in action. The construct method is called every time a new instance (object) of a class in created. If you have something you need to do on each and every object of that class, as it is created, the construct method is the place to do it.

On the line where we instantiate (create) the new Task object, we now pass a parameter with the name of the task, which is set to the name property of the object. We also echo out a line to see that the method is run. On the constructor, the parameter we pass through has a default value which allows us to to create a task object without passing through a parameter.

The __destruct() method is the opposite of the __construct method, and, you guessed it, it is run when the object/instance is destroyed or the script has run its course.

<?php
class Task
{
    public $name;

    public function __construct($name = "DefaultTask")
    {
        echo "Task name set to: " . $name;
        $this->name = $name;
    }

    public function __destruct()
    {
        echo "Task with name: " . $this->name . " was destroyed";
    }

    public function printName()
    {
        return "The task name is : " . $this->name;
    }
}

$task = new Task("MyTask");
echo $task->printName();
$task2 = new Task();
$task2->name = "SomeTask";
echo $task2->printName();

If you run the code you will see that the object is destroyed if reaches the end of the script. The output should look like below:

Task name set to: MyTask
The task name is : MyTask
Task name set to: DefaultTask
The task name is : SomeTask;
Task with name: MyTask was destroyed
Task with name: SomeTask was destroyed

To destroy the object before or at any given time, we use the unset() function which will destroy the given object.

<?php
class Task
{
    public $name;

    public function __construct($name = "DefaultTask")
    {
        echo "Task name set to: " . $name;
        $this->name = $name;
    }

    public function __destruct()
    {
        echo "Task with name: " . $this->name . " was destroyed";
    }

    public function printName()
    {
        return "The task name is : " . $this->name;
    }
}

$task = new Task("MyTask");
echo $task->printName();
unset($task);
$task2 = new Task();
$task2->name = "SomeTask";
echo $task2->printName();

The output should look like:

Task name set to: MyTask
The task name is : MyTask
Task with name: MyTask was destroyed
Task name set to: DefaultTask
The task name is : SomeTask;
Task with name: SomeTask was destroyed

Echoing an object directly will result in an fatal catchable error that states that the object could not be converted to string. To solve this we can use another magic method, __toString(). If an object is to be echoed, PHP looks for this method on the object to see if it can be converted and echoed out.

<?php
class Task
{
    public $name;

    public function __construct($name = "DefaultTask")
    {
        echo "Task name set to: " . $name;
        $this->name = $name;
    }

    public function __destruct()
    {
        echo "Task with name: " . $this->name . " was destroyed";
    }

    public function __toString()
    {
        return "Task details: Name is set to" . $this->name;
    }

    public function printName()
    {
        return "The task name is : " . $this->name;
    }

}

$task = new Task("MyTask");
echo $task->printName();
$task2 = new Task();
$task2->name = "SomeTask";
echo $task2->printName();
echo $task;
echo $task2;

We can see above that the toString method is used to output the class in a readable fashion. One thing to remember is that the toString method must return a string so it can be output.

There are a couple more magic methods, but these 3 will get you started real nicely.

Inheriting from the parent

Inheritance plays a big part in OOP and PHP does have an implementation of this. What inheritance means is that any child class will have all the methods and properties of the parent class unless they are specified as private, and unless they are overridden in the child (sub) class, the methods will retain their same functionality.

To make a class a sub class of a class, we use the extends keyword, so we will be extending the functionality of the parent class in the sub class.

<?php

class Task
{
    public $name;
    public $duedate;

    public function printName()
    {
        return "Task Name: " . $this->name;
    }
}

class OverdueTask extends Task
{
    public $overdue = "not";

    public function determineOverdue()
    {
        $date = new DateTime();
        $interval = $date->diff($this->duedate);
        if ($interval->invert < 1) {
           $this->overdue = $interval->format('due in %a days');
        } else {
           $this->overdue = $interval->format('overdue by %a days');
       }
   }
}

$task = new OverdueTask();
$task->name = "ThisTask";
$task->duedate = new DateTime('2021-01-01');
echo $task->printName() . PHP_EOL;
$task->determineOverdue();
echo "The task is " . $task->overdue . PHP_EOL;

 

We extend the Task class with the OverdueTask sub class to extend the functionality to determine if the task is overdue. When we instantiate the OverdueTask object, it also has the properties and methods of the Task parent class, as demonstrated by assigning values to properties that are part of the parent class. Why is this handy? You can now group all similar methods and properties on a class and then just extend it, no need for code duplication in each and every class.

I hope that these 2 short articles give a very basic but necessary first glance at how to start in PHP with OOP. I will be covering more OOP related topics going forward and hope to cover the stuff needed to get you on the road to use OO in PHP. If you have any comments, please post them below.

Leave a Reply

Your email address will not be published. Required fields are marked *