Symfony配置HTTP请求方法及控制器、API持久化相关问题
问题1:控制器构造方法是否会被调用?
会,Symfony控制器由服务容器统一实例化,你定义的构造方法会在路由匹配到该控制器时自动调用。但你当前的写法存在两处问题需要修正:
- 不要手动new
FahrzeugService,Symfony支持依赖注入,直接把Service作为构造参数传入即可,容器会自动完成初始化:
public function __construct(FahrzeugService $fahrzeugService) { $this->fahrzeugService = $fahrzeugService; }
- 你现有的
FahrzeugService代码存在错误:普通Service类不继承AbstractController,没有getDoctrine()方法,需要通过构造注入依赖获取Repository,同时注意persist/flush/remove方法都属于EntityManager而非Repository,修正后的Service核心逻辑如下:
use Doctrine\ORM\EntityManagerInterface; class FahrzeugService { private FahrzeugRepository $fahrzeugRepository; private EntityManagerInterface $em; public function __construct(EntityManagerInterface $em) { $this->em = $em; $this->fahrzeugRepository = $em->getRepository(Fahrzeug::class); } public function save(Fahrzeug $fahrzeug): Fahrzeug { $this->em->persist($fahrzeug); $this->em->flush(); return $fahrzeug; } public function delete(Fahrzeug $fahrzeug): Fahrzeug { $this->em->remove($fahrzeug); $this->em->flush(); return $fahrzeug; } // 其他原有方法保持不变 }
问题2:如何定义路由允许的HTTP请求方法
在#[Route]注解中添加methods参数即可指定允许的请求方法,同时注意你当前所有路由的name属性都为fahrzeug,路由名称必须唯一否则会触发报错,参考配置如下:
// 查询单条数据 仅允许GET请求 #[Route('/fahrzeug/{id}', name: 'fahrzeug_get', methods: ['GET'])] // 查询列表 仅允许GET请求 #[Route('/fahrzeug', name: 'fahrzeug_list', methods: ['GET'])] // 新增数据 仅允许POST请求 #[Route('/fahrzeug', name: 'fahrzeug_create', methods: ['POST'])] // 修改数据 仅允许PUT请求 #[Route('/fahrzeug/{id}', name: 'fahrzeug_update', methods: ['PUT'])] // 删除数据 仅允许DELETE请求 #[Route('/fahrzeug/{id}', name: 'fahrzeug_delete', methods: ['DELETE'])]
问题3:是否可以直接传递JSON格式对象完成持久化
不能直接在控制器方法参数中声明Fahrzeug $fahrzeug来自动接收JSON数据,这种写法Symfony只会根据路由参数(比如id)自动查询匹配的实体,不会解析请求体的JSON内容。
你需要按以下步骤处理:
- 在控制器方法中注入
Symfony\Component\HttpFoundation\Request对象,获取请求体的JSON内容 - 用Symfony的Serializer组件把JSON反序列化为Fahrzeug实体对象,也可以手动把JSON字段赋值给实体
- 验证数据合法性后调用Service的save方法完成持久化
参考代码:
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\Serializer\SerializerInterface; #[Route('/fahrzeug', name: 'fahrzeug_create', methods: ['POST'])] public function create(Request $request, SerializerInterface $serializer): JsonResponse { $json = $request->getContent(); /** @var Fahrzeug $fahrzeug */ $fahrzeug = $serializer->deserialize($json, Fahrzeug::class, 'json'); // 此处可添加自定义数据验证逻辑 $this->fahrzeugService->save($fahrzeug); return new JsonResponse($fahrzeug, 201); }
另外注意控制器方法不能直接返回实体或者数组,必须返回Response子类(比如JsonResponse),否则会触发报错。
内容的提问来源于stack exchange,提问作者Yll
相关产品推荐
相关产品推荐

