本文目录导读:

- 基础手动校验(简单场景)
- 使用Validation类库(推荐)
- 使用Symfony Validator(企业级)
- 通用校验基类(自定义封装)
- 针对RESTful API的完整示例
- 使用PHP 8 Attributes(现代PHP)
- 最佳实践建议
在PHP中做接口参数校验,我推荐以下几种方案:
基础手动校验(简单场景)
<?php
class UserController {
public function createUser() {
// 获取参数
$data = json_decode(file_get_contents('php://input'), true);
// 基础校验
$errors = [];
if (empty($data['username'])) {
$errors[] = '用户名不能为空';
} elseif (mb_strlen($data['username']) < 3 || mb_strlen($data['username']) > 20) {
$errors[] = '用户名长度必须在3-20个字符之间';
}
if (empty($data['email'])) {
$errors[] = '邮箱不能为空';
} elseif (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) {
$errors[] = '邮箱格式不正确';
}
if (!empty($errors)) {
http_response_code(400);
echo json_encode(['errors' => $errors]);
return;
}
// 处理业务逻辑...
}
}
使用Validation类库(推荐)
安装PHP Validation库
composer require respect/validation
使用示例
<?php
use Respect\Validation\Validator as v;
class ApiValidator {
public static function validateCreateUser($data) {
$validator = v::key('username', v::stringType()->length(3, 20))
->key('email', v::email())
->key('age', v::intType()->between(18, 100))
->key('gender', v::stringType()->in(['male', 'female']), false);
try {
$validator->assert($data);
return ['valid' => true];
} catch (\Respect\Validation\Exceptions\ValidationException $e) {
return [
'valid' => false,
'errors' => $e->getMessages()
];
}
}
}
使用Symfony Validator(企业级)
<?php
use Symfony\Component\Validator\Validation;
use Symfony\Component\Validator\Constraints as Assert;
class CreateUserRequest {
/**
* @Assert\NotBlank()
* @Assert\Length(min=3, max=20)
*/
public $username;
/**
* @Assert\NotBlank()
* @Assert\Email()
*/
public $email;
/**
* @Assert\Type(type="integer")
* @Assert\Range(min=18, max=100)
*/
public $age;
}
// 使用
$validator = Validation::createValidatorBuilder()
->enableAnnotationMapping()
->getValidator();
$request = new CreateUserRequest();
$request->username = $_POST['username'] ?? '';
$request->email = $_POST['email'] ?? '';
$request->age = $_POST['age'] ?? '';
$errors = $validator->validate($request);
if (count($errors) > 0) {
foreach ($errors as $error) {
echo $error->getPropertyPath() . ': ' . $error->getMessage() . "\n";
}
}
通用校验基类(自定义封装)
<?php
abstract class BaseApiController {
protected function validate(array $rules, array $data) {
$errors = [];
foreach ($rules as $field => $validations) {
$value = $data[$field] ?? null;
foreach ($validations as $rule => $params) {
$method = 'validate' . ucfirst($rule);
if (method_exists($this, $method)) {
$result = $this->$method($value, $params);
if ($result !== true) {
$errors[$field][] = $result;
}
}
}
}
if (!empty($errors)) {
$this->response(['errors' => $errors], 400);
}
return true;
}
protected function validateRequired($value) {
return !empty($value) ? true : '该字段为必填项';
}
protected function validateEmail($value) {
return filter_var($value, FILTER_VALIDATE_EMAIL) !== false
? true : '邮箱格式不正确';
}
protected function validateMinLength($value, $min) {
return strlen($value) >= $min ? true : "长度不能小于{$min}";
}
// 更多校验方法...
protected function response($data, $status = 200) {
http_response_code($status);
echo json_encode($data);
exit;
}
}
// 使用
class OrderController extends BaseApiController {
public function createOrder() {
$params = [
'user_id' => 123,
'amount' => 100.50,
'email' => 'test@example.com'
];
$rules = [
'user_id' => ['required', 'integer'],
'amount' => ['required', 'numeric', 'min:0.01'],
'email' => ['email']
];
$this->validate($rules, $params);
// 业务逻辑...
}
}
针对RESTful API的完整示例
<?php
header('Content-Type: application/json; charset=utf-8');
class ApiValidator {
private $data;
private $errors = [];
public function __construct(array $data) {
$this->data = $data;
}
public function check($field, $rules) {
if (!isset($this->data[$field])) {
if (in_array('required', $rules)) {
$this->errors[$field][] = '字段缺失';
}
return $this;
}
$value = $this->data[$field];
foreach ($rules as $rule) {
// 解析带参数的规则,如: min:3
$parts = explode(':', $rule);
$ruleName = $parts[0];
$params = $parts[1] ?? null;
switch ($ruleName) {
case 'required':
if (empty($value)) {
$this->errors[$field][] = '该字段不能为空';
}
break;
case 'email':
if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
$this->errors[$field][] = '邮箱格式不正确';
}
break;
case 'numeric':
if (!is_numeric($value)) {
$this->errors[$field][] = '必须为数字';
}
break;
case 'int':
if (!filter_var($value, FILTER_VALIDATE_INT)) {
$this->errors[$field][] = '必须为整数';
}
break;
case 'min':
if ($value < $params) {
$this->errors[$field][] = "不能小于{$params}";
}
break;
case 'max':
if ($value > $params) {
$this->errors[$field][] = "不能大于{$params}";
}
break;
case 'string':
if (!is_string($value)) {
$this->errors[$field][] = '必须为字符串';
}
break;
}
}
return $this;
}
public function validate() {
if (!empty($this->errors)) {
http_response_code(422);
echo json_encode([
'success' => false,
'message' => '参数校验失败',
'errors' => $this->errors
]);
exit;
}
return true;
}
}
// 使用
$data = json_decode(file_get_contents('php://input'), true) ?? $_POST;
$validator = new ApiValidator($data);
$validator
->check('username', ['required', 'string', 'min:3', 'max:20'])
->check('email', ['required', 'email'])
->check('age', ['numeric', 'min:18', 'max:100'])
->check('sex', ['string'])
->validate();
echo json_encode(['success' => true, 'data' => $data]);
使用PHP 8 Attributes(现代PHP)
<?php
#[Attribute]
class Validate {
public function __construct(
public string $rule,
public mixed $params = null
) {}
}
class UserRequest {
#[Validate('required')]
#[Validate('minLength', 3)]
public string $name;
#[Validate('required')]
#[Validate('email')]
public string $email;
#[Validate('numeric')]
#[Validate('between', [18, 100])]
public int $age;
}
// 反射验证
class RequestValidator {
public static function validate(object $request): array {
$reflection = new ReflectionClass($request);
$errors = [];
foreach ($reflection->getProperties() as $property) {
$attributes = $property->getAttributes(Validate::class);
$value = $property->getValue($request);
foreach ($attributes as $attribute) {
$validate = $attribute->newInstance();
// 执行对应的验证逻辑...
}
}
return $errors;
}
}
最佳实践建议
- 分层校验:不要把校验逻辑放在业务逻辑中
- 统一错误格式:返回一致的错误结构
- 使用正规库:成熟可靠的库比手写更安全
- 考虑性能:对于高频接口,简单校验可能更合适
- 安全考虑:永远不要信任客户端数据
选择哪个方案取决于你的项目需求、PHP版本和团队熟悉度,对于大多数中小型项目,建议使用方案2(Respect Validation)或方案5(自定义验证器),它们既灵活又易维护。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播