PHP 完全指南 / 第 27 章 — 最佳实践
第 27 章 — 最佳实践:PSR 规范、代码风格与项目结构
27.1 PSR 规范
| PSR | 名称 | 说明 |
|---|
| PSR-1 | 基础编码标准 | 文件格式、命名空间、类名 |
| PSR-4 | 自动加载 | 命名空间与文件路径映射 |
| PSR-3 | 日志接口 | LoggerInterface |
| PSR-7 | HTTP 消息 | 请求/响应接口 |
| PSR-11 | 容器接口 | ContainerInterface |
| PSR-12 | 扩展编码风格 | 代码格式化标准 |
| PSR-14 | 事件调度 | EventDispatcherInterface |
| PSR-15 | HTTP 服务器处理器 | MiddlewareInterface |
| PSR-16 | 缓存接口 | SimpleCacheInterface |
| PSR-17 | HTTP 工厂 | 各种工厂接口 |
| PSR-18 | HTTP 客户端 | ClientInterface |
| PSR-20 | 时钟接口 | ClockInterface |
PSR-12 编码风格要点
<?php
declare(strict_types=1);
namespace Vendor\Package;
use Vendor\Package\SomeClass;
use Vendor\Package\AnotherClass;
use function Vendor\Package\someFunction;
use const Vendor\Package\SOME_CONSTANT;
/**
* 类的文档注释
*/
class ClassName extends ParentClass implements InterfaceName
{
// 常量大写 + 下划线
public const CONSTANT_NAME = 'value';
// 属性声明
private string $privateProperty;
protected int $protectedProperty;
// 构造器
public function __construct(
string $parameter1,
string $parameter2,
) {
$this->privateProperty = $parameter1;
$this->protectedProperty = (int) $parameter2;
}
// 方法名 camelCase
public function doSomething(): void
{
// 4 空格缩进
if ($condition) {
// ...
}
}
// 链式调用
public function setOption(string $key, mixed $value): static
{
$this->options[$key] = $value;
return $this;
}
}
27.2 SOLID 原则
| 原则 | 说明 | 示例 |
|---|
| S 单一职责 | 一个类只做一件事 | UserService 只处理用户逻辑 |
| O 开闭原则 | 对扩展开放,对修改关闭 | 使用接口和策略模式 |
| L 里氏替换 | 子类可以替换父类 | 不改变方法语义 |
| I 接口隔离 | 接口应该小而专 | 分离 Readable 和 Writable |
| D 依赖倒置 | 依赖抽象而非具体 | 注入接口而非实现 |
<?php
// ❌ 违反单一职责
class UserManager
{
public function create() {}
public function sendEmail() {}
public function generateReport() {}
public function exportCSV() {}
}
// ✅ 遵循单一职责
class UserService { public function create() {} }
class UserMailer { public function sendWelcome() {} }
class UserReport { public function generate() {} }
class UserExporter { public function toCSV() {} }
27.3 推荐项目结构
my-project/
├── app/
│ ├── Console/ # Artisan 命令
│ ├── Http/
│ │ ├── Controllers/
│ │ ├── Middleware/
│ │ ├── Requests/ # 表单请求验证
│ │ └── Resources/ # API Resources
│ ├── Models/
│ ├── Services/ # 业务逻辑
│ ├── Repositories/ # 数据访问层
│ ├── Events/
│ ├── Listeners/
│ ├── Jobs/ # 队列任务
│ ├── Mail/
│ └── Exceptions/
├── config/
├── database/
│ ├── migrations/
│ └── seeders/
├── resources/
│ └── views/
├── routes/
├── storage/
├── tests/
│ ├── Unit/
│ └── Feature/
├── docker/
│ ├── nginx/
│ └── php/
├── .env.example
├── .gitignore
├── composer.json
├── docker-compose.yml
└── README.md
27.4 设计模式
27.4.1 仓库模式(Repository Pattern)
<?php
interface UserRepositoryInterface
{
public function findById(int $id): ?User;
public function save(User $user): bool;
}
class EloquentUserRepository implements UserRepositoryInterface
{
public function findById(int $id): ?User
{
return User::find($id);
}
public function save(User $user): bool
{
return $user->save();
}
}
27.4.2 策略模式(Strategy Pattern)
<?php
interface PaymentStrategy
{
public function pay(float $amount): bool;
}
class AlipayStrategy implements PaymentStrategy
{
public function pay(float $amount): bool
{
// 支付宝支付逻辑
return true;
}
}
class WechatPayStrategy implements PaymentStrategy
{
public function pay(float $amount): bool
{
// 微信支付逻辑
return true;
}
}
class PaymentService
{
public function process(PaymentStrategy $strategy, float $amount): bool
{
return $strategy->pay($amount);
}
}
27.4.3 观察者模式(Observer Pattern)
<?php
class UserRegisteredEvent
{
public function __construct(
public readonly User $user,
) {}
}
class SendWelcomeEmailListener
{
public function handle(UserRegisteredEvent $event): void
{
// 发送欢迎邮件
}
}
class AssignDefaultRoleListener
{
public function handle(UserRegisteredEvent $event): void
{
// 分配默认角色
}
}
27.5 代码审查清单
27.6 性能检查清单
27.7 扩展阅读
上一章:第 26 章 — CI/CD
下一章:第 28 章 — 实战项目