php实现订单状态
订单状态的基本设计
在PHP中实现订单状态管理,通常需要结合数据库设计和状态机逻辑。订单状态通常包括待支付、已支付、已发货、已完成、已取消等。
数据库表设计示例:
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT,
order_number VARCHAR(50),
total_amount DECIMAL(10,2),
status ENUM('pending', 'paid', 'shipped', 'completed', 'cancelled') DEFAULT 'pending',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
状态变更方法实现
创建订单状态处理类,封装状态变更逻辑:

class OrderStatus {
private $orderId;
private $db;
public function __construct($orderId, $dbConnection) {
$this->orderId = $orderId;
$this->db = $dbConnection;
}
public function pay() {
$this->updateStatus('paid');
}
public function ship() {
$this->updateStatus('shipped');
}
public function complete() {
$this->updateStatus('completed');
}
public function cancel() {
$this->updateStatus('cancelled');
}
private function updateStatus($newStatus) {
$stmt = $this->db->prepare("UPDATE orders SET status = ? WHERE id = ?");
$stmt->execute([$newStatus, $this->orderId]);
}
}
状态机验证逻辑
添加状态转换验证,确保只有合法的状态变更才能执行:
private $allowedTransitions = [
'pending' => ['paid', 'cancelled'],
'paid' => ['shipped', 'cancelled'],
'shipped' => ['completed'],
'completed' => [],
'cancelled' => []
];
private function updateStatus($newStatus) {
$currentStatus = $this->getCurrentStatus();
if (!in_array($newStatus, $this->allowedTransitions[$currentStatus])) {
throw new Exception("Invalid status transition from $currentStatus to $newStatus");
}
$stmt = $this->db->prepare("UPDATE orders SET status = ? WHERE id = ?");
$stmt->execute([$newStatus, $this->orderId]);
}
private function getCurrentStatus() {
$stmt = $this->db->prepare("SELECT status FROM orders WHERE id = ?");
$stmt->execute([$this->orderId]);
return $stmt->fetchColumn();
}
订单状态历史记录
创建订单状态变更历史表,记录所有状态变更:

CREATE TABLE order_status_history (
id INT AUTO_INCREMENT PRIMARY KEY,
order_id INT,
from_status VARCHAR(20),
to_status VARCHAR(20),
changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
changed_by INT,
FOREIGN KEY (order_id) REFERENCES orders(id)
);
更新状态变更方法,同时记录历史:
private function updateStatus($newStatus) {
$currentStatus = $this->getCurrentStatus();
if (!in_array($newStatus, $this->allowedTransitions[$currentStatus])) {
throw new Exception("Invalid status transition from $currentStatus to $newStatus");
}
$this->db->beginTransaction();
try {
$stmt = $this->db->prepare("UPDATE orders SET status = ? WHERE id = ?");
$stmt->execute([$newStatus, $this->orderId]);
$historyStmt = $this->db->prepare("
INSERT INTO order_status_history
(order_id, from_status, to_status, changed_by)
VALUES (?, ?, ?, ?)
");
$historyStmt->execute([
$this->orderId,
$currentStatus,
$newStatus,
$_SESSION['user_id'] ?? null
]);
$this->db->commit();
} catch (Exception $e) {
$this->db->rollBack();
throw $e;
}
}
状态变更事件处理
使用观察者模式处理状态变更后的相关操作:
class OrderStatusNotifier {
private $observers = [];
public function attach(OrderStatusObserver $observer) {
$this->observers[] = $observer;
}
public function notify($orderId, $fromStatus, $toStatus) {
foreach ($this->observers as $observer) {
$observer->update($orderId, $fromStatus, $toStatus);
}
}
}
interface OrderStatusObserver {
public function update($orderId, $fromStatus, $toStatus);
}
class EmailNotification implements OrderStatusObserver {
public function update($orderId, $fromStatus, $toStatus) {
if ($toStatus === 'shipped') {
// 发送发货通知邮件
}
}
}






