本文目录导读:

在 PHP 中,API 数据的排序和过滤通常通过 SQL 查询或数组操作实现,以下是几种常见的实现方式:
数据库查询方式(推荐)
基本实现
<?php
// api/products.php
// 获取请求参数
$sort = $_GET['sort'] ?? 'id'; // 排序字段
$order = $_GET['order'] ?? 'asc'; // 排序方向
$filter = $_GET['filter'] ?? []; // 过滤条件
$page = $_GET['page'] ?? 1;
$limit = $_GET['limit'] ?? 10;
// 安全验证 - 白名单机制
$allowedSortFields = ['id', 'name', 'price', 'created_at'];
$sort = in_array($sort, $allowedSortFields) ? $sort : 'id';
$order = strtolower($order) === 'desc' ? 'DESC' : 'ASC';
// 构建查询
$query = "SELECT * FROM products WHERE 1=1";
// 添加过滤条件
if (!empty($filter['category'])) {
$category = mysqli_real_escape_string($conn, $filter['category']);
$query .= " AND category = '$category'";
}
if (!empty($filter['price_min'])) {
$price_min = (float)$filter['price_min'];
$query .= " AND price >= $price_min";
}
if (!empty($filter['price_max'])) {
$price_max = (float)$filter['price_max'];
$query .= " AND price <= $price_max";
}
if (!empty($filter['search'])) {
$search = mysqli_real_escape_string($conn, $filter['search']);
$query .= " AND (name LIKE '%$search%' OR description LIKE '%$search%')";
}
// 添加排序
$query .= " ORDER BY $sort $order";
// 分页
$offset = ($page - 1) * $limit;
$query .= " LIMIT $limit OFFSET $offset";
// 执行查询
$result = mysqli_query($conn, $query);
$products = mysqli_fetch_all($result, MYSQLI_ASSOC);
// 返回JSON
header('Content-Type: application/json');
echo json_encode([
'success' => true,
'data' => $products,
'page' => $page,
'limit' => $limit
]);
?>
使用 API 框架(Laravel 示例)
<?php
// app/Http/Controllers/ProductController.php
namespace App\Http\Controllers;
use App\Models\Product;
use Illuminate\Http\Request;
class ProductController extends Controller
{
public function index(Request $request)
{
$query = Product::query();
// 过滤条件
if ($request->filled('category')) {
$query->where('category', $request->category);
}
if ($request->filled('price_range')) {
$range = explode(',', $request->price_range);
$query->whereBetween('price', [$range[0], $range[1] ?? PHP_INT_MAX]);
}
if ($request->filled('search')) {
$search = $request->search;
$query->where(function($q) use ($search) {
$q->where('name', 'like', "%{$search}%")
->orWhere('description', 'like', "%{$search}%");
});
}
// 排序
$sortField = $request->input('sort', 'id');
$sortOrder = $request->input('order', 'asc');
// 白名单验证
$allowed = ['id', 'name', 'price', 'created_at'];
if (in_array($sortField, $allowed)) {
$query->orderBy($sortField, $sortOrder === 'desc' ? 'desc' : 'asc');
}
// 分页
$perPage = $request->input('per_page', 15);
$products = $query->paginate($perPage);
return response()->json($products);
}
}
数组操作方式(小数据量)
<?php
function apiSortFilter($data, $params) {
// 过滤
if (!empty($params['filter'])) {
$data = array_filter($data, function($item) use ($params) {
foreach ($params['filter'] as $field => $value) {
if (isset($item[$field])) {
if (is_string($item[$field]) && stripos($item[$field], $value) === false) {
return false;
}
if (is_numeric($item[$field]) && $item[$field] != $value) {
return false;
}
}
}
return true;
});
}
// 排序
if (!empty($params['sort'])) {
$field = $params['sort'];
$order = ($params['order'] ?? 'asc') === 'asc' ? SORT_ASC : SORT_DESC;
array_multisort(
array_column($data, $field),
$order,
$data
);
}
return array_values($data);
}
// 使用示例
$products = [
['id' => 1, 'name' => 'Product A', 'price' => 100, 'category' => 'Electronics'],
['id' => 2, 'name' => 'Product B', 'price' => 50, 'category' => 'Clothing'],
// ...
];
$params = [
'filter' => ['category' => 'Electronics', 'price_min' => 50],
'sort' => 'price',
'order' => 'desc'
];
$result = apiSortFilter($products, $params);
echo json_encode($result);
?>
安全最佳实践
<?php
class APISorter {
private $allowedSortFields = [];
private $allowedFilterFields = [];
public function __construct($allowedSortFields, $allowedFilterFields) {
$this->allowedSortFields = $allowedSortFields;
$this->allowedFilterFields = $allowedFilterFields;
}
public function validateSort($sort, $order) {
// 验证排序字段
if (!in_array($sort, $this->allowedSortFields)) {
$sort = $this->allowedSortFields[0] ?? 'id';
}
// 验证排序方向
$order = strtolower($order);
if (!in_array($order, ['asc', 'desc'])) {
$order = 'asc';
}
return [$sort, $order];
}
public function validateFilters($filters) {
$validated = [];
foreach ($filters as $field => $value) {
// 只允许预定义的过滤字段
if (in_array($field, $this->allowedFilterFields)) {
// 类型转换和清理
$validated[$field] = $this->sanitizeValue($field, $value);
}
}
return $validated;
}
private function sanitizeValue($field, $value) {
// 根据字段类型清理数据
if (in_array($field, ['price', 'quantity'])) {
return (float) $value;
}
if (in_array($field, ['id', 'status'])) {
return (int) $value;
}
return htmlspecialchars(strip_tags($value), ENT_QUOTES, 'UTF-8');
}
}
// 使用
$sorter = new APISorter(
['id', 'name', 'price', 'created_at'],
['category', 'price_min', 'price_max', 'search']
);
list($sort, $order) = $sorter->validateSort(
$_GET['sort'] ?? 'id',
$_GET['order'] ?? 'asc'
);
$filters = $sorter->validateFilters($_GET['filter'] ?? []);
?>
完整的 API 端点示例
<?php
// api/endpoint.php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
// 配置
$config = [
'allowed_sorts' => ['id', 'name', 'price', 'date'],
'allowed_filters' => ['category', 'status', 'price_min', 'price_max'],
'default_per_page' => 20,
'max_per_page' => 100
];
try {
// 获取并验证参数
$page = max(1, (int)($_GET['page'] ?? 1));
$perPage = min($config['max_per_page'], max(1, (int)($_GET['per_page'] ?? $config['default_per_page'])));
$sorter = new APISorter($config['allowed_sorts'], $config['allowed_filters']);
list($sort, $order) = $sorter->validateSort($_GET['sort'] ?? 'id', $_GET['order'] ?? 'asc');
$filters = $sorter->validateFilters($_GET['filter'] ?? []);
// 查询数据库
$pdo = new PDO("mysql:host=localhost;dbname=test", "user", "pass");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$query = "SELECT * FROM products WHERE 1=1";
$params = [];
// 添加过滤条件(使用预处理语句)
if (!empty($filters['category'])) {
$query .= " AND category = :category";
$params[':category'] = $filters['category'];
}
if (!empty($filters['price_min'])) {
$query .= " AND price >= :price_min";
$params[':price_min'] = $filters['price_min'];
}
// 排序
$query .= " ORDER BY $sort $order";
// 分页
$query .= " LIMIT :limit OFFSET :offset";
$params[':limit'] = $perPage;
$params[':offset'] = ($page - 1) * $perPage;
$stmt = $pdo->prepare($query);
$stmt->execute($params);
$products = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 获取总数
$countStmt = $pdo->prepare("SELECT COUNT(*) FROM products WHERE 1=1");
$countStmt->execute();
$total = $countStmt->fetchColumn();
// 返回结果
echo json_encode([
'success' => true,
'data' => $products,
'pagination' => [
'current_page' => $page,
'per_page' => $perPage,
'total' => $total,
'last_page' => ceil($total / $perPage)
],
'sort' => [
'field' => $sort,
'order' => $order
],
'filters' => $filters
]);
} catch (Exception $e) {
http_response_code(500);
echo json_encode([
'success' => false,
'error' => 'Internal server error'
]);
}
?>
这些实现方式提供了灵活的排序和过滤功能,同时确保了安全性,选择哪种方式取决于你的项目规模、数据量和使用的框架。
版权声明: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直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播