An Introduction to Object-Oriented PHP

Introduction: Beyond a List of Instructions

Early programming was largely procedural—a list of instructions executed from top to bottom. While effective for simple tasks, this approach becomes difficult to manage as software grows, leading to tangled, unpredictable code. Object-Oriented Programming (OOP) was created to solve this complexity.

The core idea of OOP is to model your application using "objects" that represent real-world concepts. These objects bundle their own data (properties) and the behaviours they can perform (methods) into a single, self-contained unit. The blueprint for creating these objects is called a class. We then create individual objects, which are specific instances of that class, using the new keyword. For example, a Car class acts as a blueprint, defining that all cars have properties like colour and methods like startEngine(). An actual red Ford Fiesta is an object, or a specific instance, created from that blueprint. This article explores the four foundational pillars of OOP that allow us to build robust, maintainable, and scalable applications in PHP.


Pillar 1: Encapsulation (Hiding Complexity)

Encapsulation is the practice of bundling data and the methods that operate on that data into a single unit and restricting direct access to an object's internal state. This creates a protective barrier, or capsule, around the object's core data, ensuring its integrity. PHP uses three access modifier keywords (public, private, and protected) when declaring properties and methods within a class. These modifiers enforce this protective barrier and control the visibility of your object's data and behaviours.

To provide controlled access to private properties, we use public "getter" and "setter" methods. A setter acts as a gatekeeper, allowing you to validate data before a property's value is changed. A getter provides safe, read-only access to a property.

Encapsulation in Practice

An object created from the following Advert class is a perfect example of the principles of encapsulation. The $status and $price properties are private, and their values can only be read or modified through the public getter and setter methods, which enforce the object's business rules.


<?
class Advert
{
private string $status;
private float $price;
public function __construct(float $initialPrice)
{
    $this->status = 'draft';
    $this->setPrice($initialPrice);
}

public function setStatus(string $newStatus): void
{
    $allowedStatuses = ['draft', 'published', 'archived'];
    if (in_array($newStatus, $allowedStatuses)) {
        $this->status = $newStatus;
    }
}

public function getStatus(): string
{
    return $this->status;
}

public function setPrice(float $newPrice): void
{
    if ($newPrice >= 0) {
        $this->price = $newPrice;
    }
}

public function getPrice(): float
{
    return $this->price;
}

}

## Pillar 2: Inheritance (Reusing Code)

>Inheritance is a mechanism that allows a new class (the "child") to be based on an existing class (the "parent"), automatically receiving all of its public and protected properties and methods. This is a powerful tool for code reuse, adhering to the DRY (Don't Repeat Yourself) principle. In PHP, this relationship is established with the extends keyword. A protected property is similar to a private one, but any child class can also access it.

#### Inheritance in Practice

> In this example, PhysicalBook and DigitalDownload both extend the base Product class to inherit its common logic, while also adding their own specific properties.

> ```PHP
<?php
class Product
{
    protected string $name;
    protected float $price;

    public function __construct(string $name, float $price)
    {
        $this->name = $name;
        $this->price = $price;
    }

    public function getDisplayText(): string
    {
        return "{$this->name} - £{$this->price}";
    }
}

Class PhysicalBook extends Product.
{
    private float $weightKg;

    public function __construct(string $name, float $price, float $weightKg)
    {
        parent::__construct($name, $price);
        $this->weightKg = $weightKg;
    }

    public function getShippingWeight(): string
    {
        return "{$this->weightKg} kg";
    }
}

$book = new PhysicalBook('The PHP Blueprint', 49.99, 1.2);
echo $book->getDisplayText(); // Uses method from parent class```

Pillar 3: Polymorphism (Creating Flexibility)

Polymorphism, which means "many shapes," is the ability for objects of different classes to be treated as if they belong to a common type. It allows us to write flexible code that can work with a variety of objects, as long as they all share the same interface. In PHP, we achieve this with an interface. An interface is like a contract that defines a set of public methods that a class must implement.

Polymorphism in Practice

Here, UserReport and SalesReport are different classes, but because they both implement the Exportable interface, they can be used by the same generateExportFile function.

<?php
interface Exportable
{
    public function exportAsCsv(): string;
}

Class UserReport implements Exportable.
{
    public function exportAsCsv(): string
    {
        // ...logic to create a user CSV...
        return "userId,username\n1,Alex\n";
    }
}

Class SalesReport implements Exportable.
{
    public function exportAsCsv(): string
    {
        // ...logic to create a sales CSV...
        return "orderId,amount\n101,99.99\n";
    }
}

function generateExportFile(Exportable $reportObject)
{
    // This function can accept ANY object that implements Exportable.
    $csvData = $reportObject->exportAsCsv();
    file_put_contents('export.csv', $csvData);
}

Pillar 4: Abstraction (Simplifying Reality)

Abstraction is the principle of hiding complex, unnecessary details from the user of an object and only exposing the essential features they need to interact with. It is the result of applying encapsulation and polymorphism effectively. In our PHP code, interfaces and abstract classes are the primary tools for abstraction. When our generateExportFile() function accepts an Exportable object, it is relying on abstraction. It doesn't know or care how each report class generates its CSV data; it only knows that the exportAsCsv() method is guaranteed to exist.

PHP's Full OOP Toolkit

Beyond the four main pillars, modern PHP provides a rich set of features for object-oriented programming.

  1. Classes & Objects: A class is the core blueprint that defines properties and methods. An object is the instance you create from that blueprint using the new keyword (e.g., $advert = new Advert().

  2. Constructors & Destructors: These are "magic methods" that are called automatically. The __construct() method is called when a new object is created, making it the perfect place to set initial properties.

  3. Abstract Classes: An abstract class is a hybrid between a class and an interface. It cannot be instantiated itself, but other classes can extend it.

  4. Traits: A mechanism for code reuse in single-inheritance languages like PHP, allowing you to insert a group of methods into multiple, independent classes.

  5. Static Methods & Properties: These belong to the class itself, not to an individual object instance, and are called using the scope resolution operator (::).

Conclusion: Thinking in Objects

Mastering Object-Oriented Programming is about more than just learning new syntax; it's about learning a new way to think by using the four pillars: Encapsulation, Inheritance, Polymorphism, and Abstraction. We move beyond writing simple scripts and begin architecting robust, scalable, and maintainable applications. This object-oriented foundation is the key to managing the complexity of a large, unified application, allowing us to build a system from a collection of small, independent, and reusable components that work together to create a powerful whole.

Shopping summary

Item

SubTotal: £

Empty Basket

this is a hidden panel

Completed in 33 milliseconds

Completed in 33 milliseconds

This is the top Panel

This is the bottom Panel