Зная, что в сети есть много информации об этом, у меня все еще много проблем с тем, чтобы заставить это работать.
Я создал пользовательский сервис:
<?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 в конструктор! Любая помощь очень ценится
Также: $this->em->getDoctrine()->getRepository(...) не будет работать, у EntityManager нет метода с именем getDoctrine. Наверное так и должно быть $this->em->getRepository(...)
попробуйте ввести DoctrineManager вместо интерфейса




Вы используете неправильный сервис для того, что вы хотите сделать. Псевдоним doctrine, который используется, например. в AbstractController при вызове getDoctrine() привязывается к службе 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. Все, что вам нужно сделать, это использовать внедрение зависимостей.
Поэтому удалите строки конфигурации и вызовите свою службу непосредственно в методе контроллера:
<?php
namespace App\Controller;
use App\Service\AvailabilityChecks ;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
class AppController extends AbstractController
{
public function index(AvailabilityChecks $service)
{
...
}
}
Сказав это, я думаю, вам не нужен специальный сервис для выполнения простых операций с базой данных. Вместо этого используйте репозиторий.
Проблема в вашем 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)
{
// ...
}
}
В Symfony 4 вам не нужно создавать его как сервис. Теперь это автоматически. Просто введите зависимости, которые вам нужны, в конструктор. Убедитесь, что у вас есть свойство autowire с истинным значением в services.yml (по умолчанию)
Удалите это из 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;
}
}
}
Можете ли вы опубликовать код с помощью службы (например, BookController)? Похоже, вы пытаетесь создать его самостоятельно?