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;
}
});
最佳实践
- 明确职责边界:每个处理器应该只负责单一职责
- 可选的链结构:允许动态添加或移除处理器
- 默认处理:在链的末端添加默认处理器
- 性能考虑:避免过长的链影响性能
- 异常处理:确保链中的异常能够被适当处理
优缺点
优点:
- 降低耦合度
- 增强灵活性
- 符合开闭原则
- 简化对象职责
缺点:
- 性能影响
- 调试困难
- 可能导致请求被忽略
- 不保证请求一定被处理
职责链模式特别适合处理那些需要多个处理器按顺序处理的场景,如日志系统、验证系统、权限系统等。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播