Design Patterns in PHP with Examples: From A to Z

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Design Patterns in PHP: From Basics to Advanced Techniques



Design patterns are time-tested solutions to typical problems that arise during software development. For a PHP developer, knowledge of patterns is not just a checkbox on a resume, but a real tool for creating flexible, maintainable, and scalable code. In this article, we will break down three key groups of GoF (Gang of Four) patterns with concrete PHP examples that you can immediately apply in your projects.



1. Creational Patterns

These patterns are responsible for object creation, hiding the instantiation logic and making the system independent of how objects are created and composed.



Singleton

Ensures that a class has only one instance and provides a global point of access to it. A classic example is a database connection.



<?phpclass Database {    private static ?Database $instance = null;    private PDO $pdo;

private function __construct() { $this->pdo = new PDO('mysql:host=localhost;dbname=test', 'root', ''); }

public static function getInstance(): Database { if (self::$instance === null) { self::$instance = new self(); } return self::$instance; }

public function query(string $sql): array { // Query execution logic return $this->pdo->query($sql)->fetchAll(); }

// Prevent cloning and deserialization private function __clone() {} public function __wakeup() { throw new Exception("Cannot unserialize singleton"); }}

// Usage$db = Database::getInstance();$results = $db->query("SELECT * FROM users");?>


Factory Method

Defines an interface for creating an object but allows subclasses to alter the type of object that will be created. It is well-suited for creating families of related objects.



<?phpinterface Logger {    public function log(string $message): void;}

class FileLogger implements Logger { public function log(string $message): void { file_put_contents('app.log', $message . PHP_EOL, FILE_APPEND); }}

class DatabaseLogger implements Logger { public function log(string $message): void { // Save to DB echo "Logged to DB: $message"; }}

abstract class LoggerFactory { abstract public function createLogger(): Logger;

public function logMessage(string $message): void { $logger = $this->createLogger(); $logger->log($message); }}

class FileLoggerFactory extends LoggerFactory { public function createLogger(): Logger { return new FileLogger(); }}

class DatabaseLoggerFactory extends LoggerFactory { public function createLogger(): Logger { return new DatabaseLogger(); }}

// Usage$factory = new FileLoggerFactory();$factory->logMessage("This message will be written to a file");?>


2. Structural Patterns

They define how classes and objects can be combined into larger structures while maintaining flexibility and efficiency.



Adapter

Allows objects with incompatible interfaces to work together. The adapter acts as a wrapper, converting calls from one interface to another.



<?php// Old class with an inconvenient interfaceclass OldPaymentSystem {    public function processPayment(float $amount, string $currency): string {        return "Processing $amount $currency via legacy system";    }}

// New interface we want to useinterface NewPaymentInterface { public function pay(float $amount): string;}

// Adapterclass PaymentAdapter implements NewPayme

Blogs

Book Recommendations