0

知道网上有很多关于这个的信息,我仍然很难让它工作。

我创建了一个自定义服务:

<?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 东西注入构造函数!非常感谢任何帮助

4

4 回答 4

2

问题出在你的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');
        // ...
    }
}

现在可以使用自动装配将服务注入控制器,这更容易:

use Doctrine\ORM\EntityManagerInterface;

class MyController extends Controller 
{
    public function myAction(EntityManagerInterface $em) 
    {
        // ...
    }
}
于 2019-02-25T09:01:39.500 回答
0

在 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)
    {
        ...
    }
}

话虽如此,我认为您不需要自定义服务来对数据库进行简单的操作。请改用存储库。

于 2019-02-25T07:45:03.067 回答
0

您正在使用错误的服务来执行您想做的事情。使用的别名doctrine,例如,当您调用时在 AbstractControllergetDoctrine()中绑定到服务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(...)

于 2019-02-25T06:14:23.433 回答
0

在 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;
        }

    }
}
于 2019-02-25T09:04:37.283 回答