php 7.4+ 应坚持 private 属性 + 显式 getter/setter 控制订单字段,如 private string $status 和 private int $totalcents,配合 setstatus() 校验状态迁移合法性、settotal() 转换为分单位整数,避免 float 精度丢失和裸赋值绕过业务规则;订单状态变更须封装为 pay()/ship()/cancel() 等原子方法,内含校验、更新与副作用触发,并返回布尔值或抛异常;order 类仅负责数据与状态逻辑,创建、存储、通知应交由工厂、仓储和事件服务解耦。

用 private 属性 + 显式 getter/setter 控制订单字段访问
直接暴露 $status 或 $total 为 public,后续加校验、日志、格式转换时就得改所有调用点。PHP 7.4+ 强类型 + private 是底线。
常见错误:把金额设成 float 类型导致精度丢失;状态赋值跳过合法性检查(比如从 pending 直接到 completed)。
-
private string $status;配合setStatus()方法,内部校验迁移是否合法(比如只允许pending → paid,禁止paid → pending) -
private int $totalCents;存储分单位整数,避免浮点运算;getTotal(): float返回元单位值,setTotal(float $value)自动乘 100 并取整 - 构造函数不接受原始数组,而是强制传必要参数(如
$userId,$items),避免空对象或半初始化状态
把状态变更逻辑抽成方法,别裸写赋值
订单状态不是普通字段——它是业务规则的载体。裸写 $order->status = 'shipped'; 绕过了所有约束,也掩盖了“发货”背后要做的动作(扣库存、生成运单、通知物流)。
使用场景:支付成功回调、后台人工操作、定时任务触发履约。
- 每个状态变更封装为一个方法,如
pay()、ship()、cancel(),方法内做原子校验 + 状态更新 + 副作用触发 - 方法返回布尔值或抛出明确异常(如
InvalidStatusTransitionException),而不是静默失败 - 避免在方法里直接调用外部服务(如发短信),用观察者或事件解耦;但状态变更本身必须是同步、可回滚的
用 PHP 8.4 Accessors 简化简单字段,但别替代业务方法
Accessors(get/set 属性语法)适合格式化、过滤类逻辑,比如邮箱小写、日期字符串转 DateTimeImmutable。但它不能替代 ship() 这种带流程的状态方法。
容易踩的坑:ORM 框架(Doctrine/Eloquent)目前不自动识别 Accessors 的元数据,需手动配置映射,否则 $order->status 读写会绕过你的 get/set 逻辑。
- 仅对无副作用、纯转换的字段用 Accessors,例如:
public string $email { get => strtolower($this->_email); set => $this->_email = filter_var($value, FILTER_SANITIZE_EMAIL); } - 涉及数据库持久化、状态校验、外部调用的字段,仍走传统方法,确保 ORM 和业务逻辑行为一致
- 若用 Doctrine,需在实体注解中显式声明字段名(如
@Column(name="email")),并确认代理类生成未破坏 Accessor 行为
订单类不该承担创建、存储、通知职责
一个类塞进 createOrder()、saveToDb()、sendEmail(),就违背了单一职责。维护时你永远分不清哪段是领域逻辑,哪段是基础设施胶水。
性能影响:每次修改通知逻辑都要重测整个订单类;缓存订单对象时,混入的 DB 连接或邮件客户端会导致序列化失败。
-
Order类只管自身数据和状态规则,不依赖PDO、Mailer、Cache - 创建交给工厂(
OrderFactory::fromCart($cart))或应用服务(OrderService::createForUser()) - 持久化交给仓储(
OrderRepository::save($order)),它才知道用 Doctrine 还是原生 SQL - 通知交给独立服务或事件监听器,订单类只负责触发
OrderShipped::from($order)事件
ship(),出问题时只能翻日志拼凑。订单类本身不存审计字段,但封装时要预留钩子(比如 onShipped(Closure $hook)),让上层能注入记录逻辑。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











