thinkphp 图书商城可在创建订单时复制收货地址,存入订单的地址快照字段。先按当前用户校验地址归属,再把当时用于配送的字段写入订单。
准备订单地址快照字段
下面用 ThinkPHP 5.1 维护项目演示。字段名称按实际迁移调整。
ALTER TABLE orders ADD COLUMN shipping_address_json TEXT NULL;

已有订单缺少快照时保持未知,避免用当前地址冒充历史地址。
只从当前用户的地址簿复制字段
在已有认证的订单创建事务内调用下面方法。示例使用 PHP 7.3 及以上,输入地址 ID 已验证。
private function addressSnapshot(int $userId, int $addressId): string
{
$address = \think\Db::name('addresses')
->field('recipient,phone,detail')
->where('id', $addressId)
->where('user_id', $userId)
->find();
if (!$address) {
throw new \InvalidArgumentException('收货地址不存在或不可使用');
}
return json_encode($address, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
}

将结果写入 shipping_address_json 后,与订单其他字段一起保存。详情页应按用户或配送角色权限读取,日志里无需记录地址正文。
修改地址簿后验证旧订单
下面用虚构字段展示订单快照形态。先下单,再修改地址簿。
{
"recipient": "测试收货人",
"phone": "示例号码",
"detail": "测试地址 A"
}
旧订单应仍显示测试地址 A,新订单使用更新后的地址。尝试用另一账号的地址 ID 下单应被拒绝。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











