PHP OOP Classes & Objects Tutorial

In this tutorial we learn how to further encapsulate our application's data and behavior into larger, reusable units with classes and instance objects in PHP.


Object Oriented Programming is a notoriously difficult topic for new programmers to understand. It can be tough because of the shift in how we structure our code and how we think about writing our programs.

This section of the tutorial course may take you longer to understand than the others.

Object Oriented Programming

Object Oriented Programming, or OOP for short, is a way to treat data and behavior as single, reusable units. We try to model our application after entities in the real world by encapsulating data and behavior into classes.

So far we’ve learned to wrap our data and program behavior into reusable units called functions.

Example:
<?php

function alertPopUp($user) {
    echo $user . ". You've received an alert via popup box.<br>";
}

function alertText($user) {
    echo $user . ". You've received an alert via text.<br>";
}

function alertMail($user) {
    echo $user . ". You've received an alert via email.<br>";
}

function alertMe($user, $alertType="None") {
    if($alertType == "PopUp")
        alertPopUp($user);
    if($alertType == "Text")
        alertText($user);
    if($alertType == "Email")
        alertMail($user);
}

alertMe("John Wick", "PopUp");
alertMe("James Bond", "Text");
alertMe("Ethan Hunt", "Email");

?>

In the example above, we define some functions that we reuse for each user that wants an alert.

What if we could take all these functions and wrap them together inside another, bigger, unit that we can also easily reuse. That’s essentially what classes allow us to do, among many other things. Where it becomes confusing for new developers is the way that we do it.

Before we go any further, let’s wrap the example above into a class so we can see what it would look like. Don’t worry too much about understanding the code at the moment.

Example:
<?php

class Alert {

    var $user;
    var $alertType;

    function __construct($username, $typeOfAlert) {
        $this->user = $username;
        $this->alertType = $typeOfAlert;
    }

    function alertPopUp() {
        echo $this->user . ". You've received an alert via popup box.<br>";
    }

    function alertText() {
        echo $this->user . ". You've received an alert via text.<br>";
    }

    function alertMail() {
        echo $this->user . ". You've received an alert via email.<br>";
    }

    function alertMe() {
        if($this->alertType == "PopUp")
            $this->alertPopUp();
        if($this->alertType == "Text")
            $this->alertText();
        if($this->alertType == "Email")
            $this->alertMail();
    }
}

$user1 = new Alert("John Wick", "PopUp");
$user1->alertMe();

$user2 = new Alert("James Bond", "Text");
$user2->alertMe();

$user3 = new Alert("Ethan Hunt", "Email");
$user3->alertMe();

?>

If we run the example above, it will do exactly the same as the previous example where the code wasn’t in the class.

You might be wondering why anyone would do this, it just seems like extra steps to accomplish the same thing. Object oriented programming has many advantages over procedural programming, such as maintainability, scalability, reusability etc.

For the moment we won’t worry about that, and instead focus on understanding the concept and implementation of classes and objects.

If we look closer at the examples, we can see an important difference between them. In the class, we no longer have any parameters in the functions. The values are taken from the variables at the top of the class and used directly inside the functions.

Because the functions and variables are inside the same class, the functions have access to the variables directly.

Another important difference is that the functions aren’t called directly, we access them through objects.

Example: access objects
$user1 = new Alert("John Wick", "PopUp");
$user1->alertMe();

$user1 is an object, or instance, of the Alert class. Once we’ve defined an object, the object can use the functions inside the class.

What is a class?

A class is like a recipe, or blueprint, for an object. A class will define everything that an instance of it should contain.

Think of a class as a cookie cutter. It has a predefined shape that creates many cookies with the same shape. Some of those cookies might have icing and some might have chocolate chips, but they will all be the same shape.

If the class is the cookie cutter, the cookies are the objects. As an example, let’s consider a pizza.

Every pizza has:

  • A base
  • A sauce
  • Toppings
  • Cheese

This is our basic recipe (class) that can be used to make a pizza (object). When a baker makes a pizza, they create an object from the recipe.

Each pizza object that’s created will have a base, a sauce, toppings and cheese. The class doesn’t specify which toppings to use, only that some toppings can be used. It’s up to the programmer to decide what they want as ingredients.

The programmer will be able to create many types of pizzas by using only one class and changing individual ingredients.

Class attributes

A class attribute is a variable that is defined within a class. Other than a slightly different definition, it’s the same as any other variable.

They are called attributes instead of variables because we’re trying to model our application after entities in the real world. As an example, let’s consider a database of users.

Every user has attributes like:

  • A name
  • An age
  • An address
  • A profile picture
  • An email
  • A password etc.

Inside our class, normal variables will hold this data. Attributes are simply variables inside a class.

When defining an attribute, we must use the var keyword in front of the variable name.

Syntax: variable definition
 var $variableName;

Class methods

A class method is a function that is defined within a class and is, again, the same as any other function. As an example, let’s consider our database of users.

Every user has functionality available to them, like:

  • Change password
  • Upload profile picture
  • Add to cart
  • Logout etc.

Methods are simply functions inside a class.

When defining a method, we still use the function keyword in front of the method name.

Syntax: method definition
function methodName() {
    // method body
}

The attributes and methods inside a class are known as its members.

How to create a class

A class is created almost like a function, except that there are no parameters in its definition because attributes and methods inside a class are accessed differently.

We write the keyword class , followed by the name of the class, and open and close curly braces to define the scope of the class.

Syntax:
class ClassName {
    // Attributes
    // Methods
}
Example: main.php
<?php
    class Person {
        // Attributes
        var $name = "Unknown";

        // Methods
        function walk() {
            echo "Walking...";
        }
    }
?>

In the example above we have a single attribute called $name, notice the var keyword in front of the name. Other than the var keyword, the attribute is exactly the same as any other variable.

We should be aware of two conventions typically used when naming classes:

  1. We name our classes in the singular. Instead of a class named Cars, we call it Car.
  2. We use Pascal casing. The first letter of the name is uppercase and each new word in the name has its first letter in uppercase. We don’t separate words with underscores.

We don’t have to name our classes this way but it is a good convention to follow. Some employers may require you to follow conventions such as these, or their own. In this tutorial series we will be using this convention.

How to instantiate a class (create an object)

Now that we have our cookie cutter (the class), we can create objects (cookies) from it. This is known as instantiating a class object.

We create a new object by using the new keyword when assigning the class to a variable.

Syntax:
 $variableName = new ClassName();

Similar to a function, we write open and close parentheses after the class name when instantiating an object.

PHP allows us to provide parameters for class constructors between the parentheses, which we will look at a bit later on.

Example: instantiate a class
<?php
    class Person {
        // Attributes
        var $name = "Unknown";

        // Methods
        function walk() {
            echo "Walking...";
        }
    }

    $person1 = new Person();
?>

In the example above, we create a new object called $person1 from the Person class. The $person1 object will now have access to the $name attribute and the walk() method.

How to access data in a class object

When an object is instantiated, it receives all the attributes and methods that the class has. We access these attributes and methods with the arrow (->) operator.

We first write the object name, followed by the -> operator and then the attribute or method that we want to access.

Syntax:
 $object->attribute/method();

When accessing an attribute we do not write the $ symbol in front of the attribute name.

Example: access data with ->
<?php
    class Person {
        // Attributes
        var $name = "Unknown";

        // Methods
        function walk() {
            echo "Walking...";
        }
    }

    $person1 = new Person();

    echo $person1->name;
    echo "<br>";
    $person1->walk();
?>

When we run the example above, it will print out the $name attribute of the $person1 object. We also call the walk() method which will print the text “Walking…”

How to modify attribute values in a class object

When we want to modify the value of an attribute, we simply assign a new value to it.

Syntax:
 $objectName->attribute = "new_value";
Example: modify attribute values
<?php
    class Person {
        // Attributes
        var $name = "Unknown";

        // Methods
        function walk() {
            echo "Walking...";
        }
    }

    $person1 = new Person();

    $person1->name = "John";
    echo $person1->name;
?>

When we run the example above, the $name attribute of the $person1 object is changed to “John”.

When we change the value of an attribute, the change is local, which means that only the $person1 object is affected. The Person class and any other objects will not be affected by the change.

How to refer to class members without instantiating an object (::)

Often, we want to refer to data in a class without creating an object for it first.

To do this, we have to use the scope resolution operator, more commonly known as the double colon (::), instead of the arrow (->).

Syntax: double colon
 ClassName::method();
Example: access class member with double colon
<?php

    class Person {
        // Attributes
        var $name = "Unknown";

        // Methods
        function walk() {
            echo "Walking...";
        }
    }

    echo Person::walk();

?>

In the example above, we access the walk() method without instantiating an object first.

If we were to try and use the arrow to access the method directly, PHP would raise a Parse Error.

Example:
<?php

    class Person {
        // Attributes
        var $name = "Unknown";

        // Methods
        function walk() {
            echo "Walking...";
        }
    }

    echo Person->walk();

?>
Output:
 Parse error: syntax error, unexpected '->' (T_OBJECT_OPERATOR), expecting ',' or ';' in C:\xampp\htdocs\PHPProjects\main.php on line 13

How to access a constant in a class with the double colon (::)

If our class variable is a constant, we must access it with a scope resolution operator.

Syntax:
class ClassName {
    const constantName = constant_value;
}

// Direct access
echo ClassName::constantName;

// Dynamic access through object
$obj = new ClassName();
$obj::constantName;

Remember, when defining a constant, we do not use the $ symbol as a prefix.

Example:
<?php

    class Person {
        // Attributes
        const name = "Unknown";

        // Methods
        function walk() {
            echo "Walking...";
        }
    }

    // Direct access
    echo Person::name;
    echo "<br>";

    // Dynamic access through object
    $person1 = new Person();
    echo $person1::name;

?>

In the example above, we access the constant name with a double colon in both access cases.

If we were to replace the double colon with the arrow operator, the interpreter would raise an error.

Example:
<?php

    class Person {
        // Attributes
        const name = "Unknown";

        // Methods
        function walk() {
            echo "Walking...";
        }
    }

    // Dynamic access through object
    $person1 = new Person();
    echo $person1->name;

?>
Output:
 Notice: Undefined property: Person::$name in C:\xampp\htdocs\PHPProjects\main.php on line 15

Because the constant isn’t accessed with the correct operator, the interpreter doesn’t recognize it and raises the error.

Multiple instances of a class

The whole purpose of a class is to use it to create many different instances of it.

To create another instance object of the class we simply instantiate the class into another variable.

Example: multiple objects
<?php
    class Person {
        // Attributes
        var $name = "Unknown";

        // Methods
        function walk() {
            echo "Walking...";
        }
    }

    $person1 = new Person();
    $person1->name = "John";
    echo $person1->name;
    echo "<br>";

    $person2 = new Person();
    $person2->name = "Jane";
    echo $person2->name;
?>

When we run the example above, it will create a second instance of the class called $person2. We can have as many of these instances as we want.

Summary: Points to remember

  • A class defines everything that an instance object of will contain. A class can be thought of as a cookie cutter, and objects as the cookies.
  • An attribute is a data container such as a variable, or array. An attribute is available to the class scope and is defined, or instantiated, with the var keyword.
  • A method is a function inside a class that is available to its scope. A method is still defined with the function keyword.
  • An object is instantiated from a class by using the new keyword.
  • Class members (attributes and methods) can be accessed through the object with the -> operator. And, when accessing members, we do not use the $ symbol as a prefix.
  • When accessing a class member directly, without instantiating an object, we use the scope resolution operator (double colon - ::).
  • Class members defined as const or static must be accessed with the scope resolution operator.