Backend Development 8 min read

Common Design Patterns in PHP Web Service Development

This article introduces essential design patterns for PHP web service development, such as Factory, Singleton, Observer, Strategy, and Dependency Injection, explains their implementation with code examples, discusses their benefits for code reuse, maintainability, and scalability, and offers guidance on selecting appropriate patterns in modern PHP frameworks.

php中文网 Courses
php中文网 Courses
php中文网 Courses
Common Design Patterns in PHP Web Service Development

Design patterns are typical solutions to recurring software design problems; applying them in PHP web services can improve code reuse, lower coupling, enhance maintainability, and facilitate team collaboration.

1. Factory Pattern

The factory pattern creates objects without specifying concrete classes, making it suitable for scenarios where different conditions require different objects.

interface Logger {
    public function log($message);
}

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

class DatabaseLogger implements Logger {
    public function log($message) {
        // database logging implementation
    }
}

class LoggerFactory {
    public static function createLogger($type): Logger {
        switch ($type) {
            case 'file':
                return new FileLogger();
            case 'database':
                return new DatabaseLogger();
            default:
                throw new InvalidArgumentException("未知的日志类型");
        }
    }
}

$logger = LoggerFactory::createLogger('file');
$logger->log('这是一条日志信息');

2. Singleton Pattern

The singleton pattern guarantees a single instance of a class and provides a global access point, commonly used for resource‑intensive objects such as database connections.

class DatabaseConnection {
    private static $instance = null;
    private $connection;

    private function __construct() {
        $this->connection = new PDO("mysql:host=localhost;dbname=test", "username", "password");
    }

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

    public function getConnection() {
        return $this->connection;
    }

    private function __clone() {}
    private function __wakeup() {}
}

$db = DatabaseConnection::getInstance();
$conn = $db->getConnection();

3. Observer Pattern

The observer pattern defines a one‑to‑many dependency so that when the subject’s state changes, all dependent observers are automatically notified and updated.

interface Observer {
    public function update($data);
}

interface Subject {
    public function attach(Observer $observer);
    public function detach(Observer $observer);
    public function notify();
}

class Order implements Subject {
    private $observers = [];
    private $orderStatus;

    public function attach(Observer $observer) { $this->observers[] = $observer; }
    public function detach(Observer $observer) {
        $key = array_search($observer, $this->observers, true);
        if ($key !== false) { unset($this->observers[$key]); }
    }
    public function notify() {
        foreach ($this->observers as $observer) {
            $observer->update($this->orderStatus);
        }
    }
    public function setStatus($status) {
        $this->orderStatus = $status;
        $this->notify();
    }
}

class EmailNotifier implements Observer {
    public function update($data) {
        echo "发送邮件通知: 订单状态已更新为 {$data}\n";
    }
}

class SMSNotifier implements Observer {
    public function update($data) {
        echo "发送短信通知: 订单状态已更新为 {$data}\n";
    }
}

$order = new Order();
$order->attach(new EmailNotifier());
$order->attach(new SMSNotifier());
$order->setStatus('processing');
$order->setStatus('completed');

4. Strategy Pattern

The strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable, allowing the algorithm to vary independently from the client.

interface PaymentStrategy {
    public function pay($amount);
}

class CreditCardPayment implements PaymentStrategy {
    public function pay($amount) { echo "使用信用卡支付 {$amount} 元\n"; }
}

class AlipayPayment implements PaymentStrategy {
    public function pay($amount) { echo "使用支付宝支付 {$amount} 元\n"; }
}

class WechatPayment implements PaymentStrategy {
    public function pay($amount) { echo "使用微信支付 {$amount} 元\n"; }
}

class PaymentContext {
    private $strategy;
    public function __construct(PaymentStrategy $strategy) { $this->strategy = $strategy; }
    public function executePayment($amount) { $this->strategy->pay($amount); }
}

$payment = new PaymentContext(new CreditCardPayment());
$payment->executePayment(100);
$payment = new PaymentContext(new AlipayPayment());
$payment->executePayment(200);

5. Dependency Injection & IoC

Although not a formal pattern, dependency injection is widely used in modern PHP frameworks (e.g., Laravel, Symfony) to decouple components and improve testability.

interface MailerInterface {
    public function send($to, $subject, $body);
}

class SmtpMailer implements MailerInterface {
    public function send($to, $subject, $body) {
        echo "通过SMTP发送邮件给 {$to}: {$subject}\n";
    }
}

class UserService {
    private $mailer;
    public function __construct(MailerInterface $mailer) { $this->mailer = $mailer; }
    public function register($email, $password) {
        // user registration logic
        $this->mailer->send($email, '欢迎注册', '感谢您的注册!');
    }
}

$mailer = new SmtpMailer();
$userService = new UserService($mailer);
$userService->register('[email protected]', 'password');

Design Pattern Usage in PHP Frameworks

Modern PHP frameworks heavily employ design patterns:

Laravel – service container (DI), Facade (Facade pattern), event system (Observer).

Symfony – dependency‑injection container, event dispatcher (Observer), form builder (Builder).

Zend Framework – plugin manager (Factory), MVC architecture (combination of patterns).

Choosing the Right Pattern

When selecting a pattern, consider project size and complexity, team familiarity, performance requirements, and future extensibility. Overusing patterns can make code overly complex, while not using any can lead to hard‑to‑maintain code; balance is key.

Conclusion

Design patterns are powerful tools for PHP web service development. By mastering patterns such as Factory, Singleton, Observer, Strategy, and Dependency Injection, developers can build flexible, maintainable applications. Remember that patterns are means to an end—choose the ones that best solve the concrete problem at hand.

design patternsbackend developmentPHPdependency injectionFactory PatternsingletonStrategyObserver
php中文网 Courses
Written by

php中文网 Courses

php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.