本文目录导读:

在PHP项目中实现订单详情查询,通常涉及数据库查询、安全防护(防止SQL注入、越权访问)以及数据展示,以下是完整的实现思路和代码示例。
基础开发流程
- 数据库设计:订单表 + 订单商品表(一对多关系)
- 接收参数:通过URL获取订单ID(
?order_id=xxx) - 验证权限:确保当前用户只能查看自己的订单(或后台管理员可查看所有)
- 安全查询:使用预编译语句防SQL注入
- 获取数据:联表查询订单基本信息 + 商品列表
- 数据展示:渲染到HTML页面或返回JSON
数据库表结构示例
-- 订单主表 CREATE TABLE `orders` ( `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `order_no` VARCHAR(32) NOT NULL COMMENT '订单号', `user_id` INT UNSIGNED NOT NULL COMMENT '用户ID', `total_amount` DECIMAL(10,2) NOT NULL COMMENT '总金额', `status` TINYINT NOT NULL DEFAULT 0 COMMENT '订单状态 0待支付 1已支付 2已发货 3已完成', `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; -- 订单商品表 CREATE TABLE `order_items` ( `id` INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, `order_id` INT UNSIGNED NOT NULL, `product_name` VARCHAR(200) NOT NULL, `price` DECIMAL(10,2) NOT NULL, `quantity` INT NOT NULL, FOREIGN KEY (`order_id`) REFERENCES `orders`(`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
PHP代码实现(面向过程+PDO,清晰易懂)
基础查询逻辑(订单详情 + 商品列表)
<?php
// 1. 连接数据库(使用PDO,更安全)
try {
$pdo = new PDO('mysql:host=localhost;dbname=your_db;charset=utf8mb4', 'username', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die('数据库连接失败: ' . $e->getMessage());
}
// 2. 获取并验证订单ID
$order_id = isset($_GET['order_id']) ? (int)$_GET['order_id'] : 0;
if ($order_id <= 0) {
die('无效的订单ID');
}
// 3. (可选)身份验证:确保用户只能看自己的订单
session_start();
$user_id = $_SESSION['user_id'] ?? 0; // 假设登录时保存了user_id
// 4. 查询订单主信息 + 同时验证权限
$sql = "SELECT * FROM orders WHERE id = :id AND user_id = :user_id";
$stmt = $pdo->prepare($sql);
$stmt->execute([
':id' => $order_id,
':user_id' => $user_id
]);
$order = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$order) {
die('订单不存在或无权访问');
}
// 5. 查询该订单下的商品列表
$sql_items = "SELECT * FROM order_items WHERE order_id = :order_id";
$stmt_items = $pdo->prepare($sql_items);
$stmt_items->execute([':order_id' => $order_id]);
$items = $stmt_items->fetchAll(PDO::FETCH_ASSOC);
// 6. 输出HTML展示(或返回JSON)
?>
<!DOCTYPE html>
<html>
<head><title>订单详情</title></head>
<body>
<h1>订单详情</h1>
<p>订单号: <?= htmlspecialchars($order['order_no']) ?></p>
<p>总金额: ¥<?= number_format($order['total_amount'], 2) ?></p>
<p>状态: <?= ['待支付','已支付','已发货','已完成'][$order['status']] ?></p>
<p>下单时间: <?= $order['created_at'] ?></p>
<h2>商品列表</h2>
<table border="1">
<tr><th>商品名</th><th>单价</th><th>数量</th><th>小计</th></tr>
<?php foreach ($items as $item): ?>
<tr>
<td><?= htmlspecialchars($item['product_name']) ?></td>
<td>¥<?= number_format($item['price'], 2) ?></td>
<td><?= $item['quantity'] ?></td>
<td>¥<?= number_format($item['price'] * $item['quantity'], 2) ?></td>
</tr>
<?php endforeach; ?>
</table>
</body>
</html>
返回JSON格式(适用于Ajax或API接口)
// 将上面第6步改为返回JSON
header('Content-Type: application/json; charset=utf-8');
echo json_encode([
'code' => 0,
'data' => [
'order' => $order,
'items' => $items
]
]);
安全与规范要点
| 关注点 | 做法 |
|---|---|
| SQL注入 | 使用PDO预处理(id占位符),禁止拼接字符串 |
| 越权访问 | 查询时必须加上user_id条件(或通过角色校验,如管理员可查看所有) |
| XSS攻击 | 输出到HTML时使用htmlspecialchars()转义 |
| 输入校验 | 强制转整数 (int)$_GET['order_id'],避免非数字输入 |
| 数据完整性 | 联表查询时注意索引,小数据量可分别查询,大数据量用JOIN |
| 敏感字段保护 | 如支付密码、支付流水号等不返回到前端 |
扩展场景
- 分页查询列表:使用
LIMIT+OFFSET,但订单详情一般不分页 - 增加缓存:对于高频访问的订单详情,可加Redis缓存(订单状态变更时同步清除)
- 动态字段:如果订单详情包含收货地址、物流信息,联查对应表即可
- 后台管理:去掉
user_id限制,增加管理员权限判断(如$_SESSION['role'] === 'admin')
完整项目结构建议
project/
├── config/
│ └── database.php # 数据库连接配置
├── public/
│ └── order_detail.php # 订单详情页面(上述代码所在)
├── includes/
│ ├── auth.php # 登录检测函数
│ └── functions.php # 公共函数
└── services/
└── OrderService.php # 订单查询业务逻辑类(推荐封装)
使用类的版本(OrderService) 更好维护:
class OrderService {
private PDO $pdo;
public function getDetail(int $orderId, int $userId): array {
$stmt = $this->pdo->prepare("SELECT * FROM orders WHERE id = ? AND user_id = ?");
$stmt->execute([$orderId, $userId]);
$order = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$order) throw new Exception('订单不存在或无权访问');
$stmt = $this->pdo->prepare("SELECT * FROM order_items WHERE order_id = ?");
$stmt->execute([$orderId]);
$order['items'] = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $order;
}
}
就是从基础到进阶的订单详情查询实现方案,核心在于安全查询 + 权限校验 + 清晰的数据展示,根据你的项目是单体页面还是API接口,选择对应的输出格式即可。