services.yaml中arguments和@service_id不可混用:传服务对象必须用@logger,传字符串参数必须用%app.timeout%;@开头仅用于已注册服务,%包裹仅用于参数;setter注入必须显式写在calls中。

services.yaml 里 arguments 和 @service_id 别混用
传服务对象必须用 @logger,传字符串参数必须用 %app.timeout%。写成 %logger% 或 @app.timeout 会导致构造函数收到字符串而非实例,报错类似 Argument 1 passed to __construct() must be an instance of LoggerInterface, string given。
-
@开头的只用于已注册的服务(如@logger、@cache.app) -
%包裹的只用于参数(如%kernel.environment%、%env(DATABASE_URL)%) - 数组类参数(如 mime 类型列表)定义在
parameters:下,引用时仍用%app.allowed_types%
setter 注入必须写在 calls 里,不能靠 autowire 自动触发
即使开了 autowire: true,setLogger() 这类 setter 也不会自动调用——除非方法有类型提示且容器中该接口唯一注册。但更稳妥的做法是显式写 calls:
App\Service\NotificationService:
class: App\Service\NotificationService
arguments: ['@mailer']
calls:
- ['setLogger', ['@logger']]
- ['setRetryDelay', ['%app.retry_delay%']]
- 方法名必须是 public,且以
set开头(如setCachePool) - 参数列表里支持
@、%、表达式@=,但不能省略中括号 - 如果存在多个
LoggerInterface实现,自动注入会失败,必须用calls明确指定
autowire 要生效,得配齐三样东西
光在服务定义里写 autowire: true 不够,整个配置块得先启用基础规则:
客服回复模板。售前咨询、售后处理、退换货、投诉回复、好评引导、升级处理、行业FAQ、满意度挽回。Customer service reply templates for pre-sale, after-sale, returns, complaints, escalation, FAQ generation, s...
services:
_defaults:
autowire: true
autoconfigure: true
public: false
<pre class="brush:php;toolbar:false;">App\: # 扫描 src/ 下所有 App\ 命名空间类
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
-
_defaults是全局开关,不是每个服务单独设 -
resource路径必须匹配实际文件位置,Windows 下路径分隔符不用转义 -
autoconfigure: true让框架自动加标签(比如monolog.logger),否则某些扩展功能不触发
工厂服务不能 inline 写,必须拆成两步
Symfony YAML 不支持 XML 那种 <factory service="..." method="..."></factory> 的嵌套写法。要用工厂创建服务,得分两步定义:
oldapp.factory:
class: App\OldAppServiceFactory
<p>App\OldAppRepository:
factory: ['@oldapp.factory', 'create']
arguments: ['App\Repository\UserRepository']</p>
- 工厂本身得先注册为一个普通服务(用
@引用) -
factory键值必须是数组:['@service_id', 'method_name'],不能写成字符串 - 工厂方法返回值类型要和目标服务一致,否则类型推导失败
复杂点在于参数和依赖的语义边界:一个 % 少了,整个服务构造就崩;一个 @ 多了,运行时才报错且堆栈深。建议改完 services.yaml 后,立刻跑 php bin/console debug:container --types 确认服务是否注册成功,再用 debug:container ServiceName 看依赖树是否符合预期。










