服务基础 #
一、服务容器概述 #
1.1 什么是服务 #
服务是执行特定任务的PHP对象,例如发送邮件、处理数据库操作等。
text
┌─────────────────────────────────────────────────────┐
│ 服务容器作用 │
├─────────────────────────────────────────────────────┤
│ • 管理服务生命周期 │
│ • 自动依赖注入 │
│ • 服务配置和参数化 │
│ • 延迟加载 │
│ • 服务标签 │
└─────────────────────────────────────────────────────┘
1.2 服务容器结构 #
text
服务容器
├── 服务定义
│ ├── 类名
│ ├── 参数
│ └── 标签
├── 参数
│ ├── 字符串
│ ├── 数字
│ └── 数组
└── 别名
二、创建服务 #
2.1 创建服务类 #
php
<?php
namespace App\Service;
use App\Repository\UserRepository;
use Doctrine\ORM\EntityManagerInterface;
class UserService
{
public function __construct(
private EntityManagerInterface $entityManager,
private UserRepository $userRepository
) {}
public function getAllUsers(): array
{
return $this->userRepository->findAll();
}
public function getUserById(int $id): ?User
{
return $this->userRepository->find($id);
}
public function createUser(array $data): User
{
$user = new User();
$user->setName($data['name']);
$user->setEmail($data['email']);
$this->entityManager->persist($user);
$this->entityManager->flush();
return $user;
}
}
2.2 自动装配 #
Symfony默认启用自动装配,服务会自动注册:
yaml
# config/services.yaml
services:
_defaults:
autowire: true
autoconfigure: true
App\:
resource: '../src/'
exclude:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'
2.3 使用服务 #
php
<?php
namespace App\Controller;
use App\Service\UserService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class UserController extends AbstractController
{
public function list(UserService $userService)
{
$users = $userService->getAllUsers();
return $this->render('user/list.html.twig', [
'users' => $users,
]);
}
}
三、服务配置 #
3.1 YAML配置 #
yaml
# config/services.yaml
services:
App\Service\UserService:
arguments:
$userRepository: '@App\Repository\UserRepository'
calls:
- method: setLogger
arguments:
- '@logger'
tags:
- { name: 'app.service' }
App\Service\EmailService:
arguments:
$mailer: '@mailer.mailer'
$fromEmail: '%env(MAILER_FROM_EMAIL)%'
3.2 PHP属性配置 #
php
<?php
namespace App\Service;
use Psr\Log\LoggerInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Contracts\Service\Attribute\Required;
class EmailService
{
private MailerInterface $mailer;
private LoggerInterface $logger;
private string $fromEmail;
public function __construct(
MailerInterface $mailer,
string $fromEmail
) {
$this->mailer = $mailer;
$this->fromEmail = $fromEmail;
}
#[Required]
public function setLogger(LoggerInterface $logger): void
{
$this->logger = $logger;
}
}
3.3 服务别名 #
yaml
# config/services.yaml
services:
App\Service\UserServiceInterface: '@App\Service\UserService'
app.user_service:
alias: App\Service\UserService
public: true
四、服务参数 #
4.1 定义参数 #
yaml
# config/services.yaml
parameters:
app.site_name: 'My Symfony App'
app.items_per_page: 20
app.supported_locales: ['en', 'zh', 'ja']
services:
App\Service\ConfigService:
arguments:
$siteName: '%app.site_name%'
$itemsPerPage: '%app.items_per_page%'
$supportedLocales: '%app.supported_locales%'
4.2 环境变量参数 #
yaml
# config/services.yaml
services:
App\Service\ApiService:
arguments:
$apiKey: '%env(API_KEY)%'
$apiUrl: '%env(API_URL)%'
$debug: '%env(bool:APP_DEBUG)%'
$timeout: '%env(int:API_TIMEOUT)%'
4.3 在服务中使用参数 #
php
<?php
namespace App\Service;
class ConfigService
{
public function __construct(
private string $siteName,
private int $itemsPerPage,
private array $supportedLocales
) {}
public function getSiteName(): string
{
return $this->siteName;
}
public function getItemsPerPage(): int
{
return $this->itemsPerPage;
}
public function getSupportedLocales(): array
{
return $this->supportedLocales;
}
}
五、服务作用域 #
5.1 单例服务(默认) #
yaml
# config/services.yaml
services:
App\Service\UserService:
shared: true # 默认值
5.2 非共享服务 #
yaml
# config/services.yaml
services:
App\Service\TempService:
shared: false
5.3 原型服务 #
yaml
# config/services.yaml
services:
App\Service\PrototypeService:
shared: false
六、服务标签 #
6.1 定义标签 #
yaml
# config/services.yaml
services:
App\Handler\FirstHandler:
tags:
- { name: 'app.handler', priority: 10 }
App\Handler\SecondHandler:
tags:
- { name: 'app.handler', priority: 5 }
6.2 收集标签服务 #
php
<?php
namespace App\Service;
use Symfony\Component\DependencyInjection\Attribute\TaggedIterator;
class HandlerService
{
public function __construct(
#[TaggedIterator('app.handler')]
private iterable $handlers
) {}
public function process(): void
{
foreach ($this->handlers as $handler) {
$handler->handle();
}
}
}
6.3 常用标签 #
| 标签 | 说明 |
|---|---|
| controller.service_arguments | 控制器服务参数 |
| twig.extension | Twig扩展 |
| form.type | 表单类型 |
| validator.constraint_validator | 验证器 |
| kernel.event_subscriber | 事件订阅者 |
七、服务工厂 #
7.1 工厂服务 #
php
<?php
namespace App\Factory;
use App\Service\ApiClient;
use Symfony\Contracts\HttpClient\HttpClientInterface;
class ApiClientFactory
{
public static function create(HttpClientInterface $httpClient, string $baseUrl): ApiClient
{
return new ApiClient($httpClient, $baseUrl);
}
}
7.2 配置工厂 #
yaml
# config/services.yaml
services:
App\Service\ApiClient:
factory: [App\Factory\ApiClientFactory, 'create']
arguments:
- '@http_client'
- '%env(API_BASE_URL)%'
八、服务装饰 #
8.1 装饰器模式 #
php
<?php
namespace App\Decorator;
use App\Service\LoggerInterface;
use App\Service\FileLogger;
class JsonLoggerDecorator implements LoggerInterface
{
public function __construct(
private LoggerInterface $decorated
) {}
public function log(string $message): void
{
$jsonMessage = json_encode([
'message' => $message,
'timestamp' => time(),
]);
$this->decorated->log($jsonMessage);
}
}
8.2 配置装饰器 #
yaml
# config/services.yaml
services:
App\Service\LoggerInterface: '@App\Service\FileLogger'
App\Service\FileLogger:
class: App\Service\FileLogger
App\Decorator\JsonLoggerDecorator:
decorates: App\Service\FileLogger
arguments: ['@App\Decorator\JsonLoggerDecorator.inner']
九、服务调试 #
9.1 查看服务 #
bash
# 查看所有服务
php bin/console debug:container
# 查看特定服务
php bin/console debug:container App\Service\UserService
# 查看自动装配
php bin/console debug:autowiring
# 查看服务标签
php bin/console debug:container --tag=twig.extension
9.2 服务信息 #
bash
php bin/console debug:container App\Service\UserService
# 输出示例
+---------------+---------------------------------------------------------+
| Option | Value |
+---------------+---------------------------------------------------------+
| Service ID | App\Service\UserService |
| Class | App\Service\UserService |
| Tags | app.service |
| Public | no |
| Synthetic | no |
| Lazy | no |
| Shared | yes |
| Abstract | no |
| Autowired | yes |
| Autoconfigured| yes |
+---------------+---------------------------------------------------------+
十、最佳实践 #
10.1 服务设计原则 #
text
服务设计原则:
├── 单一职责:每个服务只做一件事
├── 接口编程:面向接口而非实现
├── 依赖注入:避免在服务中使用new
├── 避免服务定位器:使用依赖注入
├── 合理使用标签:组织相关服务
└── 配置外部化:使用参数和环境变量
10.2 命名规范 #
text
服务命名规范:
├── 类名:{Name}Service
├── 接口:{Name}Interface
├── 工厂:{Name}Factory
├── 装饰器:{Name}Decorator
└── 订阅者:{Name}Subscriber
十一、总结 #
本章学习了:
- 服务容器概述
- 创建和使用服务
- 服务配置方式
- 服务参数
- 服务作用域
- 服务标签
- 服务工厂
- 服务装饰器
- 服务调试
下一章将学习 依赖注入。
最后更新:2026-03-28