服务配置 #

一、配置方式概述 #

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