← Back to PHP Course | Chapter 14: Advanced PHP | Lesson 9 of 24

PHP Design Patterns

What are Design Patterns?

Design patterns are named, battle-tested solutions to recurring design problems -- they give developers a shared vocabulary ('just use a Factory here') instead of everyone reinventing similar structures independently.

Example: What are Design Patterns?

php
<?php
echo "A named, reusable solution to a recurring design problem -- like 'use a Factory here'";
?>

The Singleton Pattern

The Singleton pattern guarantees a class can only ever be instantiated once and exposes a single global access point to that instance, commonly used for things like a shared database connection.

Example: The Singleton Pattern

php
<?php
class Database {
    private static $instance = null;
    private function __construct() {}
    static function getInstance() {
        if (self::$instance === null) {
            self::$instance = new self();
        }
        return self::$instance;
    }
}
$db1 = Database::getInstance();
$db2 = Database::getInstance();
var_dump($db1 === $db2);
?>

The Factory Pattern

The Factory pattern hides object creation behind a dedicated method or class, so calling code asks for 'a Shape' without needing to know whether it gets a Circle or a Square -- useful when creation logic is complex or varies by input.

Example: The Factory Pattern

php
<?php
interface Shape {
    function draw();
}
class Circle implements Shape {
    function draw() { echo "Drawing a circle"; }
}
class ShapeFactory {
    static function create($type) {
        if ($type === "circle") return new Circle();
    }
}
$shape = ShapeFactory::create("circle");
$shape->draw();
?>

The Observer Pattern

The Observer pattern lets one subject object notify a list of registered observer objects whenever its state changes, which is the foundation behind most event-listener and pub-sub systems.

Example: The Observer Pattern

php
<?php
class Subject {
    private $observers = [];
    function subscribe($observer) {
        $this->observers[] = $observer;
    }
    function notify($event) {
        foreach ($this->observers as $observer) {
            $observer($event);
        }
    }
}
$subject = new Subject();
$subject->subscribe(function ($event) {
    echo "Observer received: $event";
});
$subject->notify("state changed");
?>

Best Practices for Patterns

Patterns solve real problems but add indirection -- applying a Factory or Observer to a five-line script adds complexity without benefit, so reach for a pattern only once a project's genuine needs justify it.

Example: Best Practices for Patterns

php
<?php
// A five-line script doesn't need a Factory or Observer -- that's added complexity with no benefit
function greet() {
    echo "Hello!";
}
greet();
?>

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.