PHP 职责链模式详解
职责链模式(Chain of Responsibility)是一种行为设计模式,允许将请求沿着处理链传递,直到有处理器能够处理它。

基础概念
<?php
// 抽象处理器
abstract class Handler {
protected $nextHandler = null;
public function setNext(Handler $handler): Handler {
$this->nextHandler = $handler;
return $handler;
}
public function handle($request) {
if ($this->nextHandler) {
return $this->nextHandler->handle($request);
}
return null;
}
}
// 具体处理器
class ConcreteHandler1 extends Handler {
public function handle($request) {
if ($request >= 0 && $request < 10) {
return "Handler1 处理了请求: $request";
}
return parent::handle($request);
}
}
class ConcreteHandler2 extends Handler {
public function handle($request) {
if ($request >= 10 && $request < 20) {
return "Handler2 处理了请求: $request";
}
return parent::handle($request);
}
}
class ConcreteHandler3 extends Handler {
public function handle($request) {
if ($request >= 20 && $request < 30) {
return "Handler3 处理了请求: $request";
}
return parent::handle($request);
}
}
// 使用
$handler1 = new ConcreteHandler1();
$handler2 = new ConcreteHandler2();
$handler3 = new ConcreteHandler3();
$handler1->setNext($handler2)->setNext($handler3);
echo $handler1->handle(5); // Handler1 处理了请求: 5
echo $handler1->handle(15); // Handler2 处理了请求: 15
echo $handler1->handle(25); // Handler3 处理了请求: 25
实际应用场景
1 日志记录系统
<?php
abstract class Logger {
const INFO = 1;
const DEBUG = 2;
const ERROR = 3;
protected $level;
protected $nextLogger = null;
public function setNext(Logger $logger): Logger {
$this->nextLogger = $logger;
return $logger;
}
public function log($level, $message) {
if ($this->level <= $level) {
$this->write($message);
}
if ($this->nextLogger) {
$this->nextLogger->log($level, $message);
}
}
abstract protected function write($message);
}
class ConsoleLogger extends Logger {
public function __construct($level) {
$this->level = $level;
}
protected function write($message) {
echo "控制台日志: $message\n";
}
}
class FileLogger extends Logger {
public function __construct($level) {
$this->level = $level;
}
protected function write($message) {
echo "文件日志: $message\n";
}
}
class EmailLogger extends Logger {
public function __construct($level) {
$this->level = $level;
}
protected function write($message) {
echo "邮件日志: $message\n";
}
}
// 使用
$consoleLogger = new ConsoleLogger(Logger::INFO);
$fileLogger = new FileLogger(Logger::DEBUG);
$emailLogger = new EmailLogger(Logger::ERROR);
$consoleLogger->setNext($fileLogger)->setNext($emailLogger);
$consoleLogger->log(Logger::ERROR, "发生严重错误");
// 输出:
// 控制台日志: 发生严重错误
// 文件日志: 发生严重错误
// 邮件日志: 发生严重错误
2 表单验证系统
<?php
abstract class Validator {
protected $nextValidator = null;
public function setNext(Validator $validator): Validator {
$this->nextValidator = $validator;
return $validator;
}
public function validate($data) {
$result = $this->doValidate($data);
if ($result['valid'] && $this->nextValidator) {
return $this->nextValidator->validate($data);
}
return $result;
}
abstract protected function doValidate($data): array;
}
class RequiredValidator extends Validator {
private $field;
public function __construct($field) {
$this->field = $field;
}
protected function doValidate($data): array {
if (empty($data[$this->field])) {
return ['valid' => false, 'message' => "{$this->field} 字段是必填的"];
}
return ['valid' => true];
}
}
class EmailValidator extends Validator {
private $field;
public function __construct($field) {
$this->field = $field;
}
protected function doValidate($data): array {
if (isset($data[$this->field]) && !filter_var($data[$this->field], FILTER_VALIDATE_EMAIL)) {
return ['valid' => false, 'message' => "{$this->field} 格式不正确"];
}
return ['valid' => true];
}
}
class LengthValidator extends Validator {
private $field;
private $min;
private $max;
public function __construct($field, $min, $max) {
$this->field = $field;
$this->min = $min;
$this->max = $max;
}
protected function doValidate($data): array {
if (isset($data[$this->field])) {
$length = strlen($data[$this->field]);
if ($length < $this->min || $length > $this->max) {
return ['valid' => false, 'message' => "{$this->field} 长度必须在 {$this->min}-{$this->max} 之间"];
}
}
return ['valid' => true];
}
}
// 使用
$required = new RequiredValidator('email');
$email = new EmailValidator('email');
$length = new LengthValidator('email', 5, 100);
$required->setNext($email)->setNext($length);
$data = ['email' => 'test@example.com'];
$result = $required->validate($data);
print_r($result); // ['valid' => true]
$data = ['email' => 'invalid'];
$result = $required->validate($data);
print_r($result); // ['valid' => false, 'message' => "email 格式不正确"]
3 权限控制系统
<?php
abstract class AuthorizationHandler {
protected $nextHandler = null;
public function setNext(AuthorizationHandler $handler): AuthorizationHandler {
$this->nextHandler = $handler;
return $handler;
}
public function authorize($user, $action) {
$result = $this->doAuthorize($user, $action);
if ($result['authorized'] && $this->nextHandler) {
return $this->nextHandler->authorize($user, $action);
}
return $result;
}
abstract protected function doAuthorize($user, $action): array;
}
class AuthenticationHandler extends AuthorizationHandler {
protected function doAuthorize($user, $action): array {
if (!$user || !isset($user['id'])) {
return ['authorized' => false, 'message' => '未登录用户'];
}
return ['authorized' => true];
}
}
class RoleCheckHandler extends AuthorizationHandler {
private $allowedRoles;
public function __construct($allowedRoles) {
$this->allowedRoles = $allowedRoles;
}
protected function doAuthorize($user, $action): array {
if (!in_array($user['role'], $this->allowedRoles)) {
return ['authorized' => false, 'message' => '没有权限访问'];
}
return ['authorized' => true];
}
}
class RateLimitHandler extends AuthorizationHandler {
private $limits = [];
protected function doAuthorize($user, $action): array {
$key = "{$user['id']}_{$action}";
$this->limits[$key] = ($this->limits[$key] ?? 0) + 1;
if ($this->limits[$key] > 100) {
return ['authorized' => false, 'message' => '请求过于频繁'];
}
return ['authorized' => true];
}
}
// 使用
$auth = new AuthenticationHandler();
$role = new RoleCheckHandler(['admin', 'manager']);
$rate = new RateLimitHandler();
$auth->setNext($role)->setNext($rate);
$user = ['id' => 1, 'role' => 'admin'];
$result = $auth->authorize($user, 'delete-post');
print_r($result); // ['authorized' => true]
职责链模式的高级应用
1 灵活的中间件系统
<?php
abstract class Middleware {
protected $next = null;
public function setNext(Middleware $middleware): Middleware {
$this->next = $middleware;
return $middleware;
}
public function handle(Request $request): Response {
$response = $this->process($request);
if ($response === null && $this->next) {
return $this->next->handle($request);
}
return $response;
}
abstract protected function process(Request $request): ?Response;
}
class Request {
public $headers = [];
public $body = [];
}
class Response {
public $status = 200;
public $body = '';
public $headers = [];
}
class CorsMiddleware extends Middleware {
protected function process(Request $request): ?Response {
// 处理CORS
if (!isset($request->headers['Origin'])) {
return new Response();
}
$response = new Response();
$response->headers['Access-Control-Allow-Origin'] = '*';
return $response;
}
}
class AuthMiddleware extends Middleware {
protected function process(Request $request): ?Response {
if (!isset($request->headers['Authorization'])) {
$response = new Response();
$response->status = 401;
$response->body = json_encode(['error' => '未授权']);
return $response;
}
// 验证token...
return null; // 继续下一个中间件
}
}
// 使用
$middleware = new CorsMiddleware();
$middleware->setNext(new AuthMiddleware());
// 动态添加中间件
$middleware->setNext(new class extends Middleware {
protected function process(Request $request): ?Response {
// 日志记录
return null;
}
});
最佳实践
- 明确职责边界:每个处理器应该只负责单一职责
- 可选的链结构:允许动态添加或移除处理器
- 默认处理:在链的末端添加默认处理器
- 性能考虑:避免过长的链影响性能
- 异常处理:确保链中的异常能够被适当处理
优缺点
优点:
- 降低耦合度
- 增强灵活性
- 符合开闭原则
- 简化对象职责
缺点:
- 性能影响
- 调试困难
- 可能导致请求被忽略
- 不保证请求一定被处理
职责链模式特别适合处理那些需要多个处理器按顺序处理的场景,如日志系统、验证系统、权限系统等。