本文目录导读:

在PHP中,API参数过滤和解析是安全开发的重要环节,以下是几种常见且推荐的解析方法:
基础过滤方法
使用 filter_var() 和 filter_input()
<?php
// 获取并过滤单个参数
$email = filter_input(INPUT_GET, 'email', FILTER_VALIDATE_EMAIL);
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1, 'max_range' => 120]
]);
// 使用 filter_var 过滤已有变量
$username = $_POST['username'] ?? '';
$username = filter_var($username, FILTER_SANITIZE_STRING);
批量过滤
<?php
$filters = [
'name' => FILTER_SANITIZE_STRING,
'email' => FILTER_VALIDATE_EMAIL,
'age' => [
'filter' => FILTER_VALIDATE_INT,
'options' => ['min_range' => 1, 'max_range' => 150]
],
'website' => FILTER_VALIDATE_URL
];
$result = filter_input_array(INPUT_POST, $filters);
使用自定义过滤函数
<?php
class APIParameterFilter {
/**
* 解析和过滤API参数
*/
public static function parse(array $params, array $rules): array {
$filtered = [];
foreach ($rules as $key => $rule) {
$value = $params[$key] ?? $rule['default'] ?? null;
if ($value === null && ($rule['required'] ?? false)) {
throw new InvalidArgumentException("Missing required parameter: {$key}");
}
if ($value !== null) {
$value = self::applyFilter($value, $rule);
}
$filtered[$key] = $value;
}
return $filtered;
}
private static function applyFilter($value, array $rule) {
switch ($rule['type'] ?? 'string') {
case 'int':
$value = filter_var($value, FILTER_VALIDATE_INT);
if ($value === false && $value !== 0) {
throw new InvalidArgumentException("Invalid integer: {$value}");
}
break;
case 'float':
$value = filter_var($value, FILTER_VALIDATE_FLOAT);
if ($value === false) {
throw new InvalidArgumentException("Invalid float: {$value}");
}
break;
case 'email':
$value = filter_var($value, FILTER_VALIDATE_EMAIL);
if ($value === false) {
throw new InvalidArgumentException("Invalid email: {$value}");
}
break;
case 'url':
$value = filter_var($value, FILTER_VALIDATE_URL);
if ($value === false) {
throw new InvalidArgumentException("Invalid URL: {$value}");
}
break;
case 'string':
default:
// 清理和截断字符串
$value = strip_tags($value);
$maxLength = $rule['max_length'] ?? 255;
$value = mb_substr($value, 0, $maxLength, 'UTF-8');
break;
}
// 应用额外的验证
if (isset($rule['enum']) && !in_array($value, $rule['enum'])) {
throw new InvalidArgumentException("Invalid value for parameter");
}
return $value;
}
}
// 使用示例
try {
$rules = [
'username' => [
'type' => 'string',
'required' => true,
'max_length' => 50,
'pattern' => '/^[a-zA-Z0-9_]+$/'
],
'email' => [
'type' => 'email',
'required' => true
],
'age' => [
'type' => 'int',
'default' => 18,
'min' => 0,
'max' => 150
],
'role' => [
'type' => 'string',
'enum' => ['admin', 'user', 'guest']
]
];
$params = $_POST;
$filteredParams = APIParameterFilter::parse($params, $rules);
} catch (InvalidArgumentException $e) {
http_response_code(400);
echo json_encode(['error' => $e->getMessage()]);
}
使用第三方库
Respect\Validation(推荐)
<?php
require 'vendor/autoload.php';
use Respect\Validation\Validator as v;
// 定义验证规则
$rules = [
'username' => v::alnum()->length(3, 20)->setName('用户名'),
'email' => v::email()->setName('邮箱'),
'age' => v::intVal()->between(1, 150)->setName('年龄'),
'password' => v::stringType()->length(6, 32)->setName('密码')
];
// 验证数据
$input = $_POST;
foreach ($rules as $field => $validator) {
try {
$validator->assert($input[$field] ?? '');
} catch (\Respect\Validation\Exceptions\NestedValidationException $e) {
$errors[] = $e->getMessage();
}
}
if (!empty($errors)) {
http_response_code(400);
echo json_encode(['errors' => $errors]);
}
RESTful API 参数解析
<?php
class RESTParameterParser {
public static function parseRequest(): array {
$method = $_SERVER['REQUEST_METHOD'];
$params = [];
switch ($method) {
case 'GET':
$params = $_GET;
break;
case 'POST':
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
if (strpos($contentType, 'application/json') !== false) {
// JSON body
$body = file_get_contents('php://input');
$params = json_decode($body, true) ?? [];
} else {
// Form data
$params = $_POST;
}
break;
case 'PUT':
case 'PATCH':
case 'DELETE':
$body = file_get_contents('php://input');
// 尝试解析JSON
$params = json_decode($body, true);
// 如果是表单编码
if ($params === null) {
parse_str($body, $params);
}
break;
}
// URL参数覆盖
$params = array_merge($params, $_GET);
return self::sanitizeAll($params);
}
private static function sanitizeAll(array $params): array {
$clean = [];
foreach ($params as $key => $value) {
$clean[$key] = self::sanitizeValue($value);
}
return $clean;
}
private static function sanitizeValue($value) {
if (is_array($value)) {
return array_map([self::class, 'sanitizeValue'], $value);
}
// 移除空字符
$value = str_replace("\0", '', $value);
// HTML实体转义
$value = htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8');
return $value;
}
}
// 使用
$params = RESTParameterParser::parseRequest();
完整的API验证示例
<?php
class APISecurity {
// 允许的HTTP方法
const ALLOWED_METHODS = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'];
// 速率限制
private static $rateLimit = [];
public static function validateRequest(): array {
// 1. 验证HTTP方法
$method = $_SERVER['REQUEST_METHOD'];
if (!in_array($method, self::ALLOWED_METHODS)) {
throw new \Exception('Method not allowed', 405);
}
// 2. 速率限制
self::checkRateLimit();
// 3. CSRF保护(对于POST/PUT/DELETE)
if (in_array($method, ['POST', 'PUT', 'DELETE', 'PATCH'])) {
self::validateCSRF();
}
// 4. 解析和过滤参数
$params = self::parseParameters($method);
// 5. SQL注入防护
$params = self::preventSQLInjection($params);
// 6. XSS防护
$params = self::preventXSS($params);
return $params;
}
private static function checkRateLimit(): void {
$ip = $_SERVER['REMOTE_ADDR'];
$time = time();
$limit = 100; // 每分钟请求数
$window = 60; // 时间窗口(秒)
// 简化示例:实际应该使用Redis或数据库
self::$rateLimit[$ip] = self::$rateLimit[$ip] ?? ['count' => 0, 'start' => $time];
if ($time - self::$rateLimit[$ip]['start'] > $window) {
self::$rateLimit[$ip] = ['count' => 0, 'start' => $time];
}
self::$rateLimit[$ip]['count']++;
if (self::$rateLimit[$ip]['count'] > $limit) {
throw new \Exception('Rate limit exceeded', 429);
}
}
private static function validateCSRF(): void {
$token = $_SERVER['HTTP_X_CSRF_TOKEN'] ?? '';
$sessionToken = $_SESSION['csrf_token'] ?? '';
if (empty($token) || $token !== $sessionToken) {
throw new \Exception('Invalid CSRF token', 403);
}
}
private static function parseParameters(string $method): array {
$params = [];
switch ($method) {
case 'GET':
$params = $_GET;
break;
case 'POST':
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
if (strpos($contentType, 'application/json') !== false) {
$body = file_get_contents('php://input');
$params = json_decode($body, true) ?? [];
} else {
$params = $_POST;
}
break;
default:
$body = file_get_contents('php://input');
$params = json_decode($body, true) ?? [];
// 也解析查询字符串
$params = array_merge($_GET, $params);
}
return $params;
}
private static function preventSQLInjection(array $params): array {
// 使用参数化查询是最好的,这里仅做基本清理
foreach ($params as $key => $value) {
if (is_string($value)) {
// 移除危险的SQL字符
$value = str_replace(
["'", '"', ';', '--', '/*', '*/', 'xp_'],
'',
$value
);
$params[$key] = $value;
}
}
return $params;
}
private static function preventXSS(array $params): array {
array_walk_recursive($params, function(&$value) {
if (is_string($value)) {
$value = htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8');
}
});
return $params;
}
}
// 使用示例
try {
$safeParams = APISecurity::validateRequest();
// 处理业务逻辑...
} catch (\Exception $e) {
http_response_code($e->getCode() ?: 500);
echo json_encode(['error' => $e->getMessage()]);
}
最佳实践建议
- 始终使用白名单验证:只接受预期格式的数据
- 输入验证:验证数据类型、长度、范围
- 输出编码:防止XSS攻击
- 使用参数化查询:防止SQL注入
- 限制请求大小:防止DoS攻击
- 实施速率限制:保护API免受过载
选择哪种方法取决于你的项目需求,对于生产环境,建议使用成熟的第三方库如 Respect\Validation 或 Symfony Validator。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播