Service类需在composer.json中配置PSR-4自动加载路径为"appservice": "app/service/"并执行composer dump-autoload;构造函数必须用类型提示注入依赖,禁止new或临时make;方法应封装完整业务动作,事务与并发安全需结合分布式锁、消息表和状态机设计。

Service类放哪?为什么use appserviceOrderService会报错
ThinkPHP 6/8 默认不识别 app/service 目录,硬建文件后直接 use appserviceOrderService 必然 Class not found。根本原因是 PSR-4 自动加载没配——不是框架“不支持”,是它压根不知道这个命名空间对应哪条路径。
必须在 composer.json 的 "autoload" → "psr-4" 中追加:
"app\service\": "app/service/"
改完立刻执行 composer dump-autoload,漏这步等于白改。别塞进 app/common 或 app/library:前者语义模糊,后者会被当成通用工具类加载,容易和真正跨项目的 Helper 混淆。
构造函数怎么写?为什么不能在方法里 new 或 make
临时用 app()->make(OrderService::class) 看似省事,实则破坏容器生命周期:单例失效、事务拦截器挂不上、AOP 增强全丢。强依赖必须声明在构造函数里,靠类型提示让容器自动注入:
立即学习“PHP免费学习笔记(深入)”;
public function __construct(
private OrderModel $orderModel,
private StockService $stockService,
private PaymentService $paymentService
) {}
如果某 Service 依赖请求上下文(比如带 session 的缓存实例),默认单例会在并发下共享状态——这时得改用容器绑定策略或工厂模式隔离实例,不能只靠构造注入。
客服回复模板。售前咨询、售后处理、退换货、投诉回复、好评引导、升级处理、行业FAQ、满意度挽回。Customer service reply templates for pre-sale, after-sale, returns, complaints, escalation, FAQ generation, s...
常见错误现象:OrderService 里调 $this->stockService->deduct() 报错找不到方法,大概率是 StockService 没在构造函数声明类型提示,导致注入失败或注入了空实例。
方法命名和职责边界:哪些该放,哪些不该放
Service 不是“万能胶水”,它只管数据访问与事务协调。规则校验、多条件判断、状态流转建议交给独立的 Logic 层;字段过滤、格式转换、响应组装一律交给控制器或视图层。
- ✅ 推荐写法:
createWithStockLock()、cancelAndRefund()、confirmReceipt()—— 动词开头,封装完整业务动作 - ❌ 禁止写法:
getOrderInfo()(模型的事)、renderOrderCard()(视图的事)、$this->redirect()(响应控制) - 事务必须收口:下单含库存扣减 + 订单创建 + 日志记录 + 消息推送,全包在一个方法里,控制器只调一次
参数推荐用数组封装,语义清晰且易扩展:
$orderData = [
'user_id' => $userId,
'items' => $cartItems,
'address' => $address,
];
$result = app()->make(OrderService::class)->createWithStockLock($orderData);
最容易被忽略的一点:事务与并发安全
订单服务常涉及库存扣减、余额变更、日志写入等多步操作,看似用 Db::transaction() 就够了,但真实场景更复杂:
- 跨库操作(如订单库 + 库存库)无法靠单一事务兜底,得用“本地事务 + 消息表 + 定时补偿”
- 高并发下秒杀类订单,单纯数据库行锁可能不够,需结合 Redis 分布式锁预占库存
- 状态流转必须配置化,禁止硬编码 if-else,否则 DRAFT → VOIDED 直跳、APPROVED → DRAFT 回滚等非法路径无法拦截
真正难的不是写完一个 createOrder(),而是让每一次状态变更都自动落 bill_logs、每一张凭证都可反查原始单据、每一个退款都能触发库存回滚且不重复执行——这些细节不提前设计,上线后就是凌晨三点的告警电话。


















