如何在WordPress中实现类似Laravel的请求类注入与验证
实现Laravel风格的自定义Request类(WordPress版)
1. 定义自定义请求基类
先封装一个通用的基类,兼容WordPress原生请求、处理验证逻辑,同时支持多场景复用:
abstract class BaseCustomRequest { protected WP_REST_Request $wpRequest; protected array $rules = []; protected array $messages = []; protected array $errors = []; // 从WP_REST_Request实例初始化(适配REST API场景) public static function fromWpRequest(WP_REST_Request $request): self { $instance = new static(); $instance->wpRequest = $request; return $instance; } // 自动捕获当前请求(适配非REST场景,比如普通表单提交) public static function capture(): self { $instance = new static(); if (defined('REST_REQUEST') && REST_REQUEST) { $instance->wpRequest = rest_get_current_request(); } else { $instance->wpRequest = new WP_REST_Request(); $instance->wpRequest->set_body_params($_POST); $instance->wpRequest->set_query_params($_GET); } return $instance; } // 验证规则,子类必须重写 abstract protected function rules(): array; // 自定义错误提示,子类可选重写 protected function messages(): array { return []; } // 执行验证逻辑 public function validate(): bool { $this->rules = $this->rules(); $this->messages = $this->messages(); $validator = new WP_Error(); foreach ($this->rules as $field => $rule) { $value = $this->wpRequest->get_param($field); // 实现基础验证规则,可按需扩展 if (str_contains($rule, 'required') && empty($value)) { $validator->add($field, $this->messages["{$field}.required"] ?? ucfirst($field) . '不能为空'); } if (str_contains($rule, 'email') && !is_email($value)) { $validator->add($field, $this->messages["{$field}.email"] ?? ucfirst($field) . '格式无效'); } if (str_contains($rule, 'min:') && strlen($value) < (int)str_replace('min:', '', $rule)) { $min = str_replace('min:', '', $rule); $validator->add($field, $this->messages["{$field}.min"] ?? ucfirst($field) . "不能少于{$min}个字符"); } } if ($validator->has_errors()) { $this->errors = $validator->get_error_messages(); return false; } return true; } // 获取验证错误 public function errors(): array { return $this->errors; } // 兼容Laravel风格的参数获取方法 public function input(string $key, $default = null) { return $this->wpRequest->get_param($key) ?? $default; } // 获取所有请求参数 public function all(): array { return $this->wpRequest->get_params(); } }
2. 定义具体的业务请求类
以注册请求为例,实现专属的验证规则:
class RegisterRequest extends BaseCustomRequest { protected function rules(): array { return [ 'username' => 'required|min:3', 'email' => 'required|email', 'password' => 'required|min:6' ]; } protected function messages(): array { return [ 'username.required' => '用户名不能为空', 'username.min' => '用户名至少3个字符', 'email.required' => '邮箱不能为空', 'email.email' => '请输入有效的邮箱地址', 'password.required' => '密码不能为空', 'password.min' => '密码至少6个字符' ]; } }
3. 解决REST API回调的类型匹配问题
方案一:通用注入包装器(推荐)
封装一个自动注入工具,识别回调参数中的自定义请求类,自动完成转换和验证:
class RequestInjector { public static function wrap(callable $callback): callable { return function(WP_REST_Request $wpRequest) use ($callback) { // 通过反射获取回调的参数类型 $reflection = new ReflectionFunction($callback); $parameters = $reflection->getParameters(); $args = []; foreach ($parameters as $param) { $type = $param->getType(); // 判断是否为自定义请求类的子类 if ($type instanceof ReflectionNamedType && is_subclass_of($type->getName(), BaseCustomRequest::class)) { $customRequest = $type->getName()::fromWpRequest($wpRequest); // 验证失败直接返回错误响应 if (!$customRequest->validate()) { return new WP_REST_Response([ 'success' => false, 'errors' => $customRequest->errors() ], 422); } $args[] = $customRequest; } else { // 其他类型参数直接传递 $args[] = $wpRequest; } } // 执行回调并返回结果 return call_user_func_array($callback, $args); }; } }
注册路由时用包装器包裹回调:
register_rest_route($this->namespace, $this->baseRoute . '/register', [ 'methods' => [WP_REST_Server::CREATABLE], 'callback' => RequestInjector::wrap([$this, 'registerRouteCallback']), ]);
此时回调方法可直接接收自定义请求类:
public function registerRouteCallback(RegisterRequest $request) { // 直接使用自定义请求类的方法 $username = $request->input('username'); $email = $request->input('email'); // 业务逻辑处理... return new WP_REST_Response([ 'success' => true, 'message' => '注册成功' ], 200); }
方案二:路由中间件(按需使用)
如果需要针对单个路由做特殊处理,可以用REST API中间件直接转换请求:
register_rest_route($this->namespace, $this->baseRoute . '/register', [ 'methods' => [WP_REST_Server::CREATABLE], 'callback' => [$this, 'registerRouteCallback'], 'middleware' => [function(WP_REST_Request $request, $handler) { $customRequest = RegisterRequest::fromWpRequest($request); if (!$customRequest->validate()) { return new WP_REST_Response([ 'success' => false, 'errors' => $customRequest->errors() ], 422); } // 把自定义请求传递给回调 return $handler($customRequest); }] ]);
4. 多场景复用(非REST API场景)
在普通页面、短代码或钩子中,直接用capture()方法自动捕获请求:
// 短代码示例:注册表单处理 function register_form_shortcode() { if ($_SERVER['REQUEST_METHOD'] === 'POST') { $request = RegisterRequest::capture(); if ($request->validate()) { // 执行注册逻辑 return '<p style="color:green;">注册成功!</p>'; } else { $errors = implode('<br>', $request->errors()); return "<p style='color:red;'>{$errors}</p>"; } } // 渲染注册表单 return ' <form method="post"> <input type="text" name="username" placeholder="用户名"> <input type="email" name="email" placeholder="邮箱"> <input type="password" name="password" placeholder="密码"> <button type="submit">注册</button> </form> '; } add_shortcode('register_form', 'register_form_shortcode');
内容的提问来源于stack exchange,提问作者Chandler P.
相关产品推荐
相关产品推荐

