本文目录导读:

我来帮你详细介绍PHP Symfony框架中Serializer组件的使用和配置。
基础安装
composer require symfony/serializer symfony/property-access symfony/property-info
核心组件配置
基本配置
// config/packages/framework.yaml
framework:
serializer:
enabled: true
enable_annotations: true
name_converter: 'serializer.name_converter.camel_case_to_snake_case'
mapping:
paths:
- '%kernel.project_dir%/config/serializer'
在服务中配置
// config/services.yaml
services:
App\Serializer\CustomNormalizer:
tags:
- { name: serializer.normalizer, priority: 64 }
实体类配置
使用注解
<?php
namespace App\Entity;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Serializer\Annotation\MaxDepth;
use Symfony\Component\Serializer\Annotation\Ignore;
class User
{
/**
* @Groups({"user:read", "user:write", "list"})
*/
private int $id;
/**
* @Groups({"user:read", "user:write", "list"})
*/
private string $username;
/**
* @Groups({"user:write"})
*/
private string $password;
/**
* @Groups({"user:read", "detail"})
* @MaxDepth(1)
*/
private array $roles;
/**
* @Groups({"user:read", "detail"})
* @Ignore()
*/
private string $internalNotes;
// getters/setters...
}
使用YAML配置
# config/serializer/App.Entity.User.yaml
App\Entity\User:
attributes:
id:
groups: ['user:read', 'user:write', 'list']
username:
groups: ['user:read', 'user:write', 'list']
password:
groups: ['user:write']
email:
groups: ['user:read', 'detail']
createdAt:
serialized_name: created_at
groups: ['user:read', 'detail']
高级用法
自定义Normalizer
<?php
namespace App\Serializer;
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
class UserNormalizer implements ContextAwareNormalizerInterface, NormalizerAwareInterface
{
use NormalizerAwareTrait;
public function supportsNormalization($data, string $format = null, array $context = []): bool
{
return $data instanceof \App\Entity\User;
}
public function normalize($object, string $format = null, array $context = []): array
{
$data = [
'id' => $object->getId(),
'username' => $object->getUsername(),
'email' => $object->getEmail(),
];
// 添加额外字段
if (in_array('detail', $context['groups'] ?? [])) {
$data['roles'] = $object->getRoles();
$data['created_at'] = $object->getCreatedAt()->format('Y-m-d H:i:s');
}
return $data;
}
}
自定义Denormalizer
<?php
namespace App\Serializer;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use App\Entity\User;
class UserDenormalizer implements DenormalizerInterface
{
public function denormalize($data, string $type, string $format = null, array $context = []): User
{
$user = new User();
$user->setUsername($data['username']);
$user->setEmail($data['email'] ?? null);
if (isset($data['password'])) {
$user->setPassword(password_hash($data['password'], PASSWORD_BCRYPT));
}
return $user;
}
public function supportsDenormalization($data, string $type, string $format = null, array $context = []): bool
{
return $type === User::class;
}
}
控制器中使用
基础使用
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
class UserController extends AbstractController
{
public function show(int $id, SerializerInterface $serializer): JsonResponse
{
$user = $this->getDoctrine()->getRepository(User::class)->find($id);
// 序列化为JSON
$json = $serializer->serialize($user, 'json', [
'groups' => ['user:read', 'detail'],
'circular_reference_handler' => function ($object) {
return $object->getId();
}
]);
return new JsonResponse($json, 200, [], true);
}
public function create(Request $request, SerializerInterface $serializer): JsonResponse
{
$data = $request->getContent();
// 反序列化
$user = $serializer->deserialize($data, User::class, 'json', [
'groups' => ['user:write']
]);
// 保存到数据库
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
return new JsonResponse(['status' => 'created'], 201);
}
}
使用对象规范化
<?php
namespace App\Controller;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\SerializerInterface;
class ApiController extends AbstractController
{
public function list(SerializerInterface $serializer): JsonResponse
{
$users = $this->getDoctrine()->getRepository(User::class)->findAll();
$data = $serializer->normalize($users, null, [
'groups' => ['list'],
ObjectNormalizer::ENABLE_MAX_DEPTH => true,
ObjectNormalizer::CIRCULAR_REFERENCE_LIMIT => 1,
AbstractNormalizer::CALLBACKS => [
'password' => function ($value) {
return null; // 隐藏密码
}
]
]);
return $this->json($data);
}
}
复杂场景处理
递归引用处理
// 配置循环引用处理器
$context = [
'circular_reference_handler' => function ($object) {
return $object->getId();
},
'circular_reference_limit' => 2,
];
// 或者使用特定的处理器
$normalizer = new ObjectNormalizer();
$normalizer->setCircularReferenceHandler(function ($object) {
return $object->getId();
});
自定义属性忽略
$context = [
AbstractNormalizer::IGNORED_ATTRIBUTES => ['password', 'salt', 'internalNotes'],
AbstractNormalizer::ATTRIBUTES => ['id', 'username', 'email', 'createdAt'],
];
属性重命名
$context = [
AbstractNormalizer::ATTRIBUTES => [
'id',
'username',
'email' => 'email_address', // 重命名属性
'createdAt' => 'created_at', // 下划线命名
],
];
与API Platform集成
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ApiResource(
* normalizationContext={"groups"={"user:read"}},
* denormalizationContext={"groups"={"user:write"}},
* itemOperations={
* "get"={"method"="GET", "normalization_context"={"groups"={"detail"}}},
* "put"={"method"="PUT", "denormalization_context"={"groups"={"user:write"}}}
* }
* )
*/
class User
{
// ... entity definition
}
性能优化
缓存配置
// config/packages/framework.yaml
framework:
serializer:
cache: serializer.mapping.cache.symfony
使用指定编码器
// 只为特定格式配置 $encoders = [new JsonEncoder()]; $normalizers = [new ObjectNormalizer()]; $serializer = new Serializer($normalizers, $encoders);
Symfony Serializer组件提供了强大的序列化/反序列化功能,通过组概念可以精细控制数据展示,配合自定义Normalizer可以处理复杂的业务逻辑,合理使用这些功能可以大大提高API开发的效率和灵活性。