PHP中的SOLID原则:从A到Z的理论与实践

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么SOLID是高质量PHP代码的基础

每个PHP开发者迟早都会遇到这样的情况:一个小项目变成了“意大利面条式代码”。类变得臃肿,系统中一个部分的修改破坏了另一部分,测试变成了一场噩梦。正是为了解决这些问题,罗伯特·马丁(鲍勃大叔)提出了SOLID五项原则。这些原则不是抽象的理论,而是实用的工具,帮助您创建灵活、可维护且可测试的PHP代码。

在本文中,我们将逐一剖析每个SOLID原则:从理论到PHP 8.x上的实际示例。您将了解如何在日常开发中应用它们,以及应该避免哪些反模式。



1. 单一职责原则(SRP)

理论

该原则指出:一个类应该只有一个引起变化的原因。这意味着每个类应该只负责一个特定的功能或业务逻辑。

反模式(违反SRP)

<?phpclass OrderProcessor {    public function process(Order $order): void {        // 1. 验证订单        if (empty($order->getItems())) {            throw new \\InvalidArgumentException('Order has no items');        }                // 2. 保存到数据库        $db = new \\PDO('mysql:host=localhost;dbname=shop', 'user', 'pass');        $stmt = $db->prepare('INSERT INTO orders ...');        $stmt->execute([...]);                // 3. 发送邮件        mail($order->getCustomerEmail(), '订单已确认', '...');                // 4. 记录日志        file_put_contents('/var/log/orders.log', 'Order processed: '.$order->getId());    }}?>

这里的OrderProcessor类做了太多事情:验证、操作数据库、发送邮件、记录日志。违反SRP会导致修改邮件发送逻辑时需要修改负责订单处理的类。

遵循SRP的重构

<?phpclass OrderValidator {    public function validate(Order $order): void {        if (empty($order->getItems())) {            throw new \\InvalidArgumentException('Order has no items');        }    }}

class OrderRepository { public function save(Order $order): void { // 保存到数据库的逻辑 }}

class EmailNotifier { public function sendOrderConfirmation(Order $order): void { // 发送邮件的逻辑 }}

class Logger { public function log(string $message): void { // 日志记录 }}

class OrderProcessor { public function __construct( private OrderValidator $validator, private OrderRepository $repository, private EmailNotifier $notifier, private Logger $logger ) {} public function process(Order $order): void { $this->validator->validate($order); $this->repository->save($order); $this->notifier->sendOrderConfirmation($order); $this->logger->log('Order processed: '.$order->getId()); }}?>

现在每个类都有单一的职责。修改邮件逻辑不会影响数据库操作。



2. 开闭原则(OCP)

理论

软件实体应该对扩展开放,对修改关闭。换句话说,您应该能够在不修改现有代码的情况下添加新功能。

反模式

<?phpclass PaymentProcessor {    public function process(string $type, float $amount): void {        if ($type === 'credit_card') {            // 处理信用卡        } elseif ($type === 'paypal') {            // 处理PayPal                

博客

书籍推荐