針對 Symfony 應(yīng)用中控制器方法參數(shù)自動(dòng)注入實(shí)體時(shí)出現(xiàn)的“no such service exists”錯(cuò)誤,本文將詳細(xì)解析其原因,并提供一種穩(wěn)健的手動(dòng)獲取實(shí)體解決方案。通過將路由參數(shù)直接作為 ID 傳遞,并利用實(shí)體管理器從數(shù)據(jù)庫中顯式查找實(shí)體,可以有效規(guī)避自動(dòng)注入的潛在問題,確保數(shù)據(jù)操作的正確性與應(yīng)用的穩(wěn)定性。
Symfony 框架提供了強(qiáng)大的自動(dòng)注入(Autowiring)機(jī)制,極大地簡化了依賴管理。在控制器方法中,當(dāng)您為參數(shù)進(jìn)行類型提示時(shí),Symfony 會(huì)嘗試自動(dòng)解析并注入相應(yīng)的服務(wù)或?qū)ο?。對?Doctrine 實(shí)體,Symfony 通常通過 ParamConverter 組件實(shí)現(xiàn)實(shí)體自動(dòng)解析:當(dāng)路由參數(shù)與方法參數(shù)的名稱和類型匹配時(shí),ParamConverter 會(huì)自動(dòng)從數(shù)據(jù)庫中查找并注入對應(yīng)的實(shí)體對象。例如,如果路由定義了 {id} 參數(shù),并且控制器方法接受 Category $category 參數(shù),ParamConverter 會(huì)嘗試根據(jù) id 查找 Category 實(shí)體。
然而,在某些情況下,這種自動(dòng)注入機(jī)制可能不會(huì)按預(yù)期工作,導(dǎo)致類似“Cannot autowire argument $category... no such service exists”的錯(cuò)誤。這通常意味著 Symfony 的依賴注入容器嘗試將 App\Entity\Category 作為一個(gè)服務(wù)來注入,而不是通過 ParamConverter 從數(shù)據(jù)庫中解析實(shí)體。
考慮以下 Symfony 控制器中的 deleteCategory 方法:
<?php namespace App\Controller; use App\Entity\Category; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; #[Route('/admin')] class AdminController extends AbstractController { #[Route('/delete-category/{id}', name: 'delete_category')] public function deleteCategory(Category $category): Response { $entityManager = $this->getDoctrine()->getManager(); $entityManager->remove($category); $entityManager->flush(); return $this->redirectToRoute('categories'); } }
上述代碼嘗試直接將 Category $category 作為參數(shù)注入。如果 ParamConverter 未能正確識(shí)別或執(zhí)行,Symfony 容器可能會(huì)嘗試尋找一個(gè)名為 App\Entity\Category 的服務(wù),而通常實(shí)體本身并不會(huì)被注冊為服務(wù),從而引發(fā)“Cannot autowire argument $category... no such service exists”的錯(cuò)誤。
解決此問題最直接且穩(wěn)健的方法是繞過 ParamConverter,手動(dòng)從實(shí)體管理器中獲取實(shí)體。這要求您將路由中的 ID 參數(shù)直接傳遞給控制器方法,然后利用 Doctrine 的倉庫(Repository)來查找實(shí)體。
千面視頻動(dòng)捕是一個(gè)AI視頻動(dòng)捕解決方案,專注于將視頻中的人體關(guān)節(jié)二維信息轉(zhuǎn)化為三維模型動(dòng)作。
以下是修正后的 deleteCategory 方法代碼:
<?php namespace App\Controller; use App\Entity\Category; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; #[Route('/admin')] class AdminController extends AbstractController { #[Route('/delete-category/{id}', name: 'delete_category')] public function deleteCategory(int $id): Response // 將參數(shù)類型從 Category $category 改為 int $id { $entityManager = $this->getDoctrine()->getManager(); // 手動(dòng)通過實(shí)體管理器和倉庫查找 Category 實(shí)體 $category = $entityManager->getRepository(Category::class)->find($id); // 重要的錯(cuò)誤處理:如果實(shí)體未找到,拋出 404 異常 if (!$category) { throw $this->createNotFoundException('未找到指定ID的分類。'); } $entityManager->remove($category); $entityManager->flush(); return $this->redirectToRoute('categories'); } }
代碼解析:
ParamConverter 是 Symfony 框架提供的一個(gè)便利功能,旨在減少樣板代碼,使控制器更專注于業(yè)務(wù)邏輯。當(dāng)它正常工作時(shí),您只需在方法參數(shù)中類型提示實(shí)體,Symfony 就會(huì)自動(dòng)完成從路由參數(shù)到實(shí)體對象的轉(zhuǎn)換。
然而,手動(dòng)獲取實(shí)體作為 ParamConverter 的替代方案,在以下場景中可能更為適用或必要:
// 推薦的依賴注入方式 use Doctrine\ORM\EntityManagerInterface; class AdminController extends AbstractController { private $entityManager; public function __construct(EntityManagerInterface $entityManager) { $this->entityManager = $entityManager; } #[Route('/delete-category/{id}', name: 'delete_category')] public function deleteCategory(int $id): Response { $category = $this->entityManager->getRepository(Category::class)->find($id); if (!$category) { throw $this->createNotFoundException('未找到指定ID的分類。'); } $this->entityManager->remove($category); $this->entityManager->flush(); return $this->redirectToRoute('categories'); } }
當(dāng) Symfony 控制器中出現(xiàn)“Cannot autowire argument... no such service exists”的實(shí)體自動(dòng)注入錯(cuò)誤時(shí),通常意味著框架未能將類型提示的實(shí)體參數(shù)正確地通過 ParamConverter 解析。此時(shí),最可靠的解決方案是放棄自動(dòng)注入,轉(zhuǎn)而采用手動(dòng)方式。通過將實(shí)體 ID 作為控制器方法的參數(shù),并利用 Doctrine 的實(shí)體管理器和倉庫顯式地查找實(shí)體,可以有效解決此類問題,并提供更強(qiáng)的代碼控制力和錯(cuò)誤處理能力。理解 Symfony 的自動(dòng)注入機(jī)制及其替代方案,能夠幫助開發(fā)者構(gòu)建更健壯、更靈活的應(yīng)用程序。
以上就是解決 Symfony 控制器中實(shí)體自動(dòng)注入失敗的問題的詳細(xì)內(nèi)容,更多請關(guān)注php中文網(wǎng)其它相關(guān)文章!
每個(gè)人都需要一臺(tái)速度更快、更穩(wěn)定的 PC。隨著時(shí)間的推移,垃圾文件、舊注冊表數(shù)據(jù)和不必要的后臺(tái)進(jìn)程會(huì)占用資源并降低性能。幸運(yùn)的是,許多工具可以讓 Windows 保持平穩(wěn)運(yùn)行。
微信掃碼
關(guān)注PHP中文網(wǎng)服務(wù)號(hào)
QQ掃碼
加入技術(shù)交流群
Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號(hào)