意识到网上周围有很多信息,我仍然有很多麻烦。
我创建了一个自定义服务:
<?php
namespace AppService;
use DoctrineORMEntityManagerInterface;
use AppEntityAccommodationType;
use AppEntityNight;
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: AppServiceAvailabilityChecks
arguments: ['@doctrine.orm.entity_manager']
因此,当我尝试在控制器中使用它时,我会得到此错误:
Too few arguments to function AppServiceAvailabilityChecks::__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&lt; 3.3中,我们通常使用:
use SymfonyBundleFrameworkBundleControllerController;
class MyController extends Controller
{
public function myAction()
{
$em = $this->get('doctrine.orm.entity_manager');
// ...
}
}
如今,可以使用AutowRiring在控制器中注入服务,这很容易:
use DoctrineORMEntityManagerInterface;
class MyController extends Controller
{
public function myAction(EntityManagerInterface $em)
{
// ...
}
}
您正在使用错误的服务来做什么。使用的别名doctrine
,例如在呼叫getDoctrine()
时,在AbstractController中绑定到服务DoctrineCommonPersistenceManagerRegistry
。
因此,您编写的代码与此更适合,您应该将@doctrine
或@DoctrineCommonPersistenceManagerRegistry
添加到服务定义。
无论是当前配置还是更改的配置,您都不必致电$this->em->getDoctrine()
,因为$this->em
已经从控制器上等同于$this->getDoctrine()
。相反,您可以创建一个(私有)方法,使其看起来更像是该代码,例如:
private function getDoctrine()
{
return $this->em;
}
然后您可以致电$this->getDoctrine()->getRepository(...)
或直接使用$this->em->getRepository(...)
。
在Symfony 4中,您无需将其创建为服务。现在是自动的。只需在构造函数中注入依赖项即可。确保您拥有services.yml中具有真实价值的Autowire属性(默认情况下是)
从services.yml中删除此:
AvailabilityChecks.service:
class: AppServiceAvailabilityChecks
arguments: ['@doctrine.orm.entity_manager']
您不需要EntityManagerInterface,因为您不持续任何东西,因此仅注入存储库。
<?php
namespace AppService;
use AppEntityAccommodationType;
use AppEntityNight;
use AppRepositoryAccommodationTypeRepository;
use AppRepositoryNightRepository;
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 AppController;
use AppServiceAvailabilityChecks ;
use SymfonyBundleFrameworkBundleControllerAbstractController;
class AppController extends AbstractController
{
public function index(AvailabilityChecks $service)
{
...
}
}
话虽如此,我认为您不需要自定义服务就可以在数据库上进行简单操作。改用存储库。