意识到网络上有很多关于此的信息,我仍然很难让这个工作。
我创建了一个自定义服务:
<?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
服务。应该怎么做?
在Symfony <3.3中,我们通常使用:
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class MyController extends Controller
{
public function myAction()
{
$em = $this->get('doctrine.orm.entity_manager');
// ...
}
}
现在服务可以使用autowiring注入控制器,这更容易:
use Doctrine\ORM\EntityManagerInterface;
class MyController extends Controller
{
public function myAction(EntityManagerInterface $em)
{
// ...
}
}
您正在使用错误的服务来执行您想要的操作。使用的别名doctrine
,例如在您调用getDoctrine()
时,在AbstractController中绑定服务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(...)
。
在Symfony 4中,您不需要将其创建为服务。这是自动的。只需在构造函数中注入所需的依赖项。确保您在services.yml中具有true值的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;
}
}
}
在SF4中,您不再需要在service.yaml文件中指定自定义服务所需的依赖项。您所要做的就是使用依赖注入。
因此,删除配置行,并直接在控制器方法中调用您的服务:
<?php
namespace App\Controller;
use App\Service\AvailabilityChecks ;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class AppController extends AbstractController
{
public function index(AvailabilityChecks $service)
{
...
}
}
话虽如此,我认为你不需要自定义服务来对数据库进行简单的操作。请改用存储库。