[英]Access Doctrine within a custom service in Symfony4
意識到網上有很多與此有關的信息,我仍然很難將其工作。
我創建了一個定制服務:
<?php
namespace App\Service;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\AccommodationType;
use App\Entity\Night;
class AvailabilityChecks {
private $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
public function nightAvailable(string $RoomCode, string $NightDate) {
$GetRoom = $this->em->getDoctrine()->getRepository(AccommodationType::class)->findOneBy([
'RoomCode' => $RoomCode
]);
$RoomQnt = $GetRoom->getNightlyQnt();
$GetNight = $this->em->getDoctrine()->getRepository(Night::class)->findOneBy([
'RoomCode' => $RoomCode,
'NightDate' => $NightDate
]);
$NumberOfNights = $GetNight->count();
if($NumberOfNights<$RoomQnt) {
return true;
}
else {
return false;
}
}
}
並將其放在services.yaml中:
AvailabilityChecks.service:
class: App\Service\AvailabilityChecks
arguments: ['@doctrine.orm.entity_manager']
因此,當我嘗試在控制器中使用它時,出現以下錯誤:
Too few arguments to function App\Service\AvailabilityChecks::__construct(), 0 passed in /mypath/src/Controller/BookController.php on line 40 and exactly 1 expected
我只是想不出為什么沒有將ORM注入到構造函數中! 任何幫助,不勝感激
問題出在您的BookController
。 即使您沒有發布其代碼,我也可以假設您在其中創建了new AvailabilityChecks
(第40行)。
在Symfony中,每個服務都由服務容器實例化。 您永遠不要自己使服務對象實例化。 相反, BookController
必須向服務容器詢問AvailabilityChecks
服務。 應該怎么做?
在<3.3的Symfony中,我們通常使用:
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class MyController extends Controller
{
public function myAction()
{
$em = $this->get('doctrine.orm.entity_manager');
// ...
}
}
如今,可以使用自動裝配將服務注入控制器中,這更容易:
use Doctrine\ORM\EntityManagerInterface;
class MyController extends Controller
{
public function myAction(EntityManagerInterface $em)
{
// ...
}
}
您要使用的服務使用了錯誤的服務。 例如,在調用getDoctrine()
時在AbstractController中使用的別名doctrine
已綁定到服務Doctrine\\Common\\Persistence\\ManagerRegistry
。
因此,您編寫的代碼更適合該代碼,您應該在服務定義中添加@doctrine
或@Doctrine\\Common\\Persistence\\ManagerRegistry
。
無論是當前配置還是更改后的配置,都不必調用$this->em->getDoctrine()
,因為$this->em
已等效於控制器中的$this->getDoctrine()
。 相反,您可以創建一個(私有)方法,使其看起來更像該代碼,例如:
private function getDoctrine()
{
return $this->em;
}
然后,您可以調用$this->getDoctrine()->getRepository(...)
或直接使用$this->em->getRepository(...)
。
在SF4中,您不再需要在service.yaml文件中指定自定義服務所需的依賴項。 您要做的就是使用依賴注入。
因此,刪除配置行,然后直接在controller方法中調用您的服務:
<?php
namespace App\Controller;
use App\Service\AvailabilityChecks ;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class AppController extends AbstractController
{
public function index(AvailabilityChecks $service)
{
...
}
}
話雖如此,我認為您不需要自定義服務即可對數據庫進行簡單的操作。 請改用存儲庫。
在Symfony 4中,您無需將其創建為服務。 現在是自動的。 只需在構造函數中注入所需的依賴項即可。 確保在services.yml中具有具有真值的autowire屬性(默認情況下)
從services.yml中刪除它:
AvailabilityChecks.service:
class: App\Service\AvailabilityChecks
arguments: ['@doctrine.orm.entity_manager']
您不需要EntityManagerInterface,因為您沒有持久化任何東西,因此僅注入存儲庫。
<?php
namespace App\Service;
use App\Entity\AccommodationType;
use App\Entity\Night;
use App\Repository\AccommodationTypeRepository;
use App\Repository\NightRepository;
class AvailabilityChecks {
private $accommodationTypeRepository;
private $nightRepository
public function __construct(
AcommodationTypeRepository $acommodationTypeRepository,
NightRepository $nightRepository
)
{
$this->acommodationTypeRepository = $acommodationTypeRepository;
$this->nightRepository = $nightRepository;
}
public function nightAvailable(string $RoomCode, string $NightDate) {
$GetRoom = $this->acommodationTypeRepository->findOneBy([
'RoomCode' => $RoomCode
]);
$RoomQnt = $GetRoom->getNightlyQnt();
$GetNight = $this->nightRepository->findOneBy([
'RoomCode' => $RoomCode,
'NightDate' => $NightDate
]);
$NumberOfNights = $GetNight->count();
if($NumberOfNights<$RoomQnt) {
return true;
}
else {
return false;
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.