服务配置 #
一、配置方式概述 #
1.1 配置方式对比 #
| 方式 | 优点 | 缺点 |
|---|---|---|
| YAML | 简洁易读 | 复杂结构不直观 |
| XML | 功能完整、IDE支持 | 冗长 |
| PHP | 灵活、动态配置 | 不够直观 |
| 属性 | 代码即配置 | PHP 8+ |
1.2 默认配置文件 #
yaml
# config/services.yaml
services:
_defaults:
autowire: true
autoconfigure: true
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
二、YAML配置 #
2.1 基本服务定义 #
yaml
# config/services.yaml
services:
App\Service\UserService:
class: App\Service\UserService
arguments:
- '@App\Repository\UserRepository'
- '@logger'
calls:
- method: setEnabled
arguments: [true]
tags:
- { name: 'app.service' }
2.2 参数引用 #
yaml
# config/services.yaml
parameters:
app.site_name: 'My App'
app.items_per_page: 20
services:
App\Service\ConfigService:
arguments:
$siteName: '%app.site_name%'
$itemsPerPage: '%app.items_per_page%'
2.3 服务引用 #
yaml
# config/services.yaml
services:
App\Service\OrderService:
arguments:
$userRepository: '@App\Repository\UserRepository'
$logger: '@logger'
$entityManager: '@doctrine.orm.entity_manager'
2.4 环境变量 #
yaml
# config/services.yaml
services:
App\Service\ApiService:
arguments:
$apiKey: '%env(API_KEY)%'
$apiUrl: '%env(API_URL)%'
$debug: '%env(bool:APP_DEBUG)%'
2.5 集合注入 #
yaml
# config/services.yaml
services:
App\Service\HandlerChain:
arguments:
$handlers:
- '@App\Handler\FirstHandler'
- '@App\Handler\SecondHandler'
- '@App\Handler\ThirdHandler'
2.6 工厂服务 #
yaml
# config/services.yaml
services:
App\Service\ApiClient:
factory: ['@App\Factory\ApiClientFactory', 'create']
arguments:
- '%env(API_BASE_URL)%'
三、XML配置 #
3.1 基本XML配置 #
xml
<!-- config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services
https://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<defaults autowire="true" autoconfigure="true"/>
<prototype namespace="App\" resource="../src/*" exclude="../src/{DependencyInjection,Entity,Kernel.php}"/>
<service id="App\Service\UserService">
<argument type="service" id="App\Repository\UserRepository"/>
<argument type="service" id="logger"/>
<call method="setEnabled">
<argument>true</argument>
</call>
<tag name="app.service"/>
</service>
</services>
</container>
3.2 参数定义 #
xml
<parameters>
<parameter key="app.site_name">My App</parameter>
<parameter key="app.items_per_page" type="integer">20</parameter>
<parameter key="app.supported_locales" type="collection">
<parameter>en</parameter>
<parameter>zh</parameter>
<parameter>ja</parameter>
</parameter>
</parameters>
3.3 服务定义 #
xml
<services>
<service id="App\Service\ConfigService">
<argument key="$siteName">%app.site_name%</argument>
<argument key="$itemsPerPage">%app.items_per_page%</argument>
</service>
<service id="App\Service\ApiService">
<argument key="$apiKey" type="string">%env(API_KEY)%</argument>
<argument key="$apiUrl" type="string">%env(API_URL)%</argument>
</service>
</services>
四、PHP配置 #
4.1 基本PHP配置 #
php
<?php
namespace App\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $container) {
$services = $container->services()
->defaults()
->autowire()
->autoconfigure();
$services->load('App\\', '../src/*')
->exclude('../src/{DependencyInjection,Entity,Kernel.php}');
$services->set(UserService::class)
->args([
new Reference(UserRepository::class),
new Reference('logger'),
])
->tag('app.service');
};
4.2 使用ContainerBuilder #
php
<?php
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Definition;
$container = new ContainerBuilder();
$definition = new Definition(UserService::class);
$definition->setArguments([
new Reference(UserRepository::class),
new Reference('logger'),
]);
$definition->addTag('app.service');
$definition->addMethodCall('setEnabled', [true]);
$container->setDefinition(UserService::class, $definition);
4.3 动态配置 #
php
<?php
return static function (ContainerConfigurator $container) {
$services = $container->services();
if ($_ENV['APP_ENV'] === 'production') {
$services->set(CacheService::class)
->args([
new Reference('cache.adapter.redis'),
]);
} else {
$services->set(CacheService::class)
->args([
new Reference('cache.adapter.filesystem'),
]);
}
};
五、属性配置 #
5.1 #[Autoconfigure]属性 #
php
<?php
namespace App\Service;
use Symfony\Component\DependencyInjection\Attribute\Autoconfigure;
#[Autoconfigure(
tags: ['app.service'],
calls: [['setEnabled', [true]]],
lazy: true,
public: false,
shared: true
)]
class UserService
{
}
5.2 #[Autowire]属性 #
php
<?php
namespace App\Service;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Psr\Log\LoggerInterface;
class EmailService
{
public function __construct(
#[Autowire(service: 'monolog.logger.email')]
private LoggerInterface $logger,
#[Autowire('%app.from_email%')]
private string $fromEmail,
#[Autowire(env: 'MAILER_DSN')]
private string $mailerDsn
) {}
}
5.3 #[When]属性 #
php
<?php
use Symfony\Component\DependencyInjection\Attribute\When;
#[When(env: 'dev')]
class DevEmailService implements EmailServiceInterface
{
}
#[When(env: 'prod')]
class ProdEmailService implements EmailServiceInterface
{
}
六、导入配置 #
6.1 导入其他配置文件 #
yaml
# config/services.yaml
imports:
- { resource: 'services/user.yaml' }
- { resource: 'services/order.yaml' }
- { resource: 'services/api.yaml' }
6.2 条件导入 #
yaml
# config/services.yaml
imports:
- { resource: 'services/dev.yaml', ignore_errors: not_found }
6.3 按环境导入 #
yaml
# config/services.yaml
imports:
- { resource: 'services/' }
- { resource: 'services/dev/', type: glob }
七、服务定义选项 #
7.1 完整服务定义 #
yaml
services:
App\Service\UserService:
class: App\Service\UserService
arguments:
$repository: '@App\Repository\UserRepository'
properties:
enabled: true
calls:
- [setLogger, ['@logger']]
- [setEnabled, [true]]
tags:
- { name: 'app.service', priority: 10 }
configurator: ['@App\Configurator\ServiceConfigurator', 'configure']
factory: ['@App\Factory\ServiceFactory', 'create']
lazy: true
public: false
shared: true
abstract: false
decorates: 'App\Service\OriginalService'
decoration_inner_name: 'App\Service\UserService.inner'
decoration_on_invalid: 'ignore'
autowire: true
autoconfigure: true
bind:
$projectDir: '%kernel.project_dir%'
7.2 选项说明 #
| 选项 | 说明 |
|---|---|
| class | 服务类名 |
| arguments | 构造函数参数 |
| properties | 属性设置 |
| calls | 方法调用 |
| tags | 服务标签 |
| factory | 工厂方法 |
| lazy | 惰性加载 |
| public | 是否公开 |
| shared | 是否共享 |
| abstract | 是否抽象 |
| decorates | 装饰的服务 |
| autowire | 自动装配 |
| autoconfigure | 自动配置 |
| bind | 参数绑定 |
八、环境特定配置 #
8.1 开发环境配置 #
yaml
# config/services_dev.yaml
services:
App\Service\EmailService:
arguments:
$fromEmail: 'dev@example.com'
$debug: true
8.2 生产环境配置 #
yaml
# config/services_prod.yaml
services:
App\Service\EmailService:
arguments:
$fromEmail: 'noreply@example.com'
$debug: false
8.3 测试环境配置 #
yaml
# config/services_test.yaml
services:
App\Service\EmailService:
arguments:
$fromEmail: 'test@example.com'
$debug: true
九、最佳实践 #
9.1 配置组织 #
text
config/
├── services.yaml # 主配置
├── services_dev.yaml # 开发环境
├── services_prod.yaml # 生产环境
├── services_test.yaml # 测试环境
└── services/ # 分模块配置
├── user.yaml
├── order.yaml
└── api.yaml
9.2 配置建议 #
text
配置建议:
├── 优先使用自动装配
├── 使用属性配置简单服务
├── 复杂配置使用YAML
├── 环境特定配置单独文件
├── 参数使用环境变量
└── 避免过度配置
十、总结 #
本章学习了:
- 配置方式对比
- YAML配置
- XML配置
- PHP配置
- 属性配置
- 导入配置
- 服务定义选项
- 环境特定配置
- 最佳实践
下一章将学习 安全基础。
最后更新:2026-03-28