Doctrine - 传递给 __construct 的参数必须是一个数组
Doctrine - Argument passed to __construct must be an array
当我发现这个错误时,我正在尝试创建一个新服务。当我尝试列出可用的学说命令时,它显示了下一个错误:
Doctrine\ORM\Mapping\OneToMany::__construct() 必须是数组或 null 类型,给定的字符串,在 /var/www/html/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php
中调用
我尝试重置对其负责的实体,但没有结果。这是所有跟踪:
TypeError {#478
#message: "Argument 3 passed to Doctrine\ORM\Mapping\OneToMany::__construct() must be of the type array or null, string given, called in /var/www/html/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php on line 971"
#code: 0
#file: "./vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OneToMany.php"
#line: 44
trace: {
./vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OneToMany.php:44 { …}
./vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php:971 { …}
./vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php:719 { …}
./vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php:376 { …}
./vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php:178 { …}
./vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/PsrCachedReader.php:155 { …}
./vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/PsrCachedReader.php:88 { …}
./vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/PsrCachedReader.php:98 { …}
./vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php:331 { …}
./vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/MappingDriverChain.php:79 { …}
./vendor/doctrine/doctrine-bundle/Mapping/MappingDriver.php:45 { …}
./vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:134 { …}
./vendor/doctrine/doctrine-bundle/Mapping/ClassMetadataFactory.php:19 { …}
./vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php:382 { …}
./vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php:251 { …}
./vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:303 { …}
./var/cache/dev/ContainerX9n3NQZ/EntityManager_9a5be93.php:94 {
ContainerX9n3NQZ\EntityManager_9a5be93->getClassMetadata($className)^
›
› return $this->valueHolderda610->getClassMetadata($className);
› }
arguments: {
$className: "App\Entity\App\City"
}
}
./vendor/doctrine/doctrine-bundle/Repository/ServiceEntityRepository.php:45 { …}
./src/Repository/App/CityRepository.php:26 { …}
./var/cache/dev/ContainerX9n3NQZ/getCityRepositoryService.php:27 { …}
./var/cache/dev/ContainerX9n3NQZ/App_KernelDevDebugContainer.php:525 { …}
./var/cache/dev/ContainerX9n3NQZ/getCityServiceService.php:23 { …}
./var/cache/dev/ContainerX9n3NQZ/App_KernelDevDebugContainer.php:525 { …}
./var/cache/dev/ContainerX9n3NQZ/getDoctrine_FixturesLoadCommandService.php:43 { …}
./var/cache/dev/ContainerX9n3NQZ/App_KernelDevDebugContainer.php:525 { …}
./vendor/symfony/dependency-injection/Container.php:422 { …}
./vendor/symfony/dependency-injection/Argument/ServiceLocator.php:42 { …}
./vendor/symfony/console/CommandLoader/ContainerCommandLoader.php:45 { …}
./vendor/symfony/console/Application.php:551 { …}
./vendor/symfony/console/Application.php:519 { …}
./vendor/symfony/framework-bundle/Console/Application.php:126 { …}
./vendor/symfony/console/Application.php:664 { …}
Symfony\Component\Console\Application->Symfony\Component\Console\{closure}() {}
./vendor/symfony/console/Application.php:665 { …}
./vendor/symfony/framework-bundle/Console/Application.php:116 { …}
./vendor/symfony/console/Application.php:254 { …}
./vendor/symfony/framework-bundle/Console/Application.php:82 { …}
./vendor/symfony/console/Application.php:166 { …}
./bin/console:43 { …}
}
}
这是城市实体:
<?php
namespace App\Entity\App;
use App\DBAL\Types\Geolocation\Point;
use App\Entity\App\Graveyard;
use App\Repository\App\CityRepository;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* @ORM\Entity(repositoryClass=CityRepository::class)
* @ORM\Table (name="location", schema="app")
*/
class City
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column (type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255, nullable=false)
*/
private $name;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $country;
/**
* @ORM\OneToMany(targetEntity=Company::class, mappedBy="city", cascade="persist")
*/
private $companies;
/**
* @ORM\OneToMany(targetEntity=Graveyard::class, mappedBy="city", cascade="persist")
*/
private $graveyards;
/**
* @ORM\OneToMany(targetEntity=FuneralParlor::class, mappedBy="city", cascade="persist")
*/
private $funeralParlors;
/**
* @ORM\OneToMany(targetEntity=AdvertisementTransfer::class, mappedBy="city")
*/
private $advertisementTransfers;
/**
* @ORM\OneToMany(targetEntity=Crematorium::class, mappedBy="city")
*/
private $crematoria;
/**
* @ORM\Column(type="point")
*/
private $coordinate;
/**
* @ORM\Column(type="string", length=255, nullable=true, options={"default" : null})
*/
private $province;
public function __construct()
{
$this->companies = new ArrayCollection();
$this->graveyards = new ArrayCollection();
$this->funeralParlors = new ArrayCollection();
$this->advertisementTransfers = new ArrayCollection();
$this->crematoria = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getCountry(): ?string
{
return $this->country;
}
public function setCountry(?string $country): self
{
$this->country = $country;
return $this;
}
/**
* @return Collection|Company[]
*/
public function getCompanies(): Collection
{
return $this->companies;
}
public function addCompany(Company $company): self
{
if (!$this->companies->contains($company)) {
$this->companies[] = $company;
$company->setCity($this);
}
return $this;
}
public function removeCompany(Company $company): self
{
if ($this->companies->removeElement($company)) {
// set the owning side to null (unless already changed)
if ($company->getCity() === $this) {
$company->setCity(null);
}
}
return $this;
}
/**
* @return Collection|Graveyard[]
*/
public function getGraveyards(): Collection
{
return $this->graveyards;
}
public function addGraveyard(Graveyard $graveyard): self
{
if (!$this->graveyards->contains($graveyard)) {
$this->graveyards[] = $graveyard;
$graveyard->setCity($this);
}
return $this;
}
public function removeGraveyard(Graveyard $graveyard): self
{
if ($this->graveyards->removeElement($graveyard)) {
// set the owning side to null (unless already changed)
if ($graveyard->getCity() === $this) {
$graveyard->setCity(null);
}
}
return $this;
}
/**
* @return Collection|FuneralParlor[]
*/
public function getFuneralParlors(): Collection
{
return $this->funeralParlors;
}
public function addFuneralParlor(FuneralParlor $funeralParlor): self
{
if (!$this->funeralParlors->contains($funeralParlor)) {
$this->funeralParlors[] = $funeralParlor;
$funeralParlor->setCity($this);
}
return $this;
}
public function removeFuneralParlor(FuneralParlor $funeralParlor): self
{
if ($this->funeralParlors->removeElement($funeralParlor)) {
// set the owning side to null (unless already changed)
if ($funeralParlor->getCity() === $this) {
$funeralParlor->setCity(null);
}
}
return $this;
}
/**
* @return Collection|AdvertisementTransfer[]
*/
public function getAdvertisementTransfers(): Collection
{
return $this->advertisementTransfers;
}
public function addAdvertisementTransfer(AdvertisementTransfer $advertisementTransfer): self
{
if (!$this->advertisementTransfers->contains($advertisementTransfer)) {
$this->advertisementTransfers[] = $advertisementTransfer;
$advertisementTransfer->setCity($this);
}
return $this;
}
public function removeAdvertisementTransfer(AdvertisementTransfer $advertisementTransfer): self
{
if ($this->advertisementTransfers->removeElement($advertisementTransfer)) {
// set the owning side to null (unless already changed)
if ($advertisementTransfer->getCity() === $this) {
$advertisementTransfer->setCity(null);
}
}
return $this;
}
/**
* @return Collection|Crematorium[]
*/
public function getCrematoria(): Collection
{
return $this->crematoria;
}
public function addCrematorium(Crematorium $crematorium): self
{
if (!$this->crematoria->contains($crematorium)) {
$this->crematoria[] = $crematorium;
$crematorium->setCity($this);
}
return $this;
}
public function removeCrematorium(Crematorium $crematorium): self
{
if ($this->crematoria->removeElement($crematorium)) {
// set the owning side to null (unless already changed)
if ($crematorium->getCity() === $this) {
$crematorium->setCity(null);
}
}
return $this;
}
public function getCoordinate(): Point
{
return $this->coordinate;
}
public function setCoordinate($coordinate): self
{
$this->coordinate = $coordinate;
return $this;
}
public function toJsonArray(): array
{
$coordinate = $this->getCoordinate();
return [
"id" => $this->getId(),
"name" => $this->getName(),
"country" => $this->getCountry(),
"coordinate" => $coordinate->toJsonArray()
];
}
public function getProvince(): ?string
{
return $this->province;
}
public function setProvince(?string $province): self
{
$this->province = $province;
return $this;
}
}
城市资料库:
<?php
namespace App\Repository\App;
use App\DBAL\Types\Geolocation\Point;
use App\Entity\App\City;
use App\Exception\City\CityAlreadyExistException;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\DBAL\FetchMode;
use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\ORMException;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Persistence\ManagerRegistry;
/**
* @method City|null find($id, $lockMode = null, $lockVersion = null)
* @method City|null findOneBy(array $criteria, array $orderBy = null)
* @method City[] findAll()
* @method City[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class CityRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, City::class);
}
/**
* Get all cities on DDBB
* @return int|mixed|string
*/
public function getAllCities() {
return $this->createQueryBuilder("c")->where('')->orderBy('name')->getQuery()->getResult();
}
public function getCityById(int $id): City {
return $this->createQueryBuilder('c')->where('id = :id')->setParameter('id', $id)->getQuery()->getResult();
}
public function getCityByName(string $name): ?City
{
$city = $this->createQueryBuilder('c')->where('name = :name')->setParameter('name', $name)->getQuery()->getResult();
return $city === null ? null : $city;
}
/**
* @throws CityAlreadyExistException
*/
public function createCity(City $city): ?City
{
try {
$entityManager = $this->getEntityManager();
$entityManager->persist($city);
$entityManager->flush();
return $city;
} catch (ORMException $e) {
throw new CityAlreadyExistException(sprintf("City %s already exist", $city->getName()));
}
}
public function calculateDistance(City $city, $lat, $lon)
{
$SQL = "
SELECT (ST_Distance(ST_MakePoint({$lat}, {$lon})::geography, ST_MakePoint(coordinate[0], coordinate[1])::geography) / 1000) as distance
FROM app.location
WHERE id = {$city->getId()}
";
return $this->executeSQL($SQL);
}
public function calculateDistanceBetweenPointInKm(Point $origin, Point $destiny)
{
$SQL = "
SELECT (ST_DISTANCE
(
ST_MakePoint({$origin->getLongitude()}, {$origin->getLatitude()})::geography,
ST_MakePoint({$destiny->getLongitude()}, {$destiny->getLatitude()})::geography
) / 1000) as distance
";
return $this->executeSQL($SQL)[0];
}
private function executeSQL(string $SQL)
{
$em = $this->getEntityManager();
$stmt = $em->getConnection()->prepare($SQL);
$stmt->execute();
return $stmt->fetchAll(FetchMode::COLUMN);
}
}
服务实体存储库(这是 doctrine 和 symfony 的默认设置):
class ServiceEntityRepository extends EntityRepository implements ServiceEntityRepositoryInterface
{
/**
* @param string $entityClass The class name of the entity this repository manages
* @psalm-param class-string<T> $entityClass
*/
public function __construct(ManagerRegistry $registry, string $entityClass)
{
$manager = $registry->getManagerForClass($entityClass);
if ($manager === null) {
throw new LogicException(sprintf(
'Could not find the entity manager for class "%s". Check your Doctrine configuration to make sure it is configured to load this entity’s metadata.',
$entityClass
));
}
parent::__construct($manager, $manager->getClassMetadata($entityClass));
}
}
已解决 - 经过时间和耐心的搜索,我发现了一个 ORM 符号错误。 composer json 文件被队友更新了,新版本的级联必须带括号,有一个地方是打开的但不是关闭的。
当我发现这个错误时,我正在尝试创建一个新服务。当我尝试列出可用的学说命令时,它显示了下一个错误:
Doctrine\ORM\Mapping\OneToMany::__construct() 必须是数组或 null 类型,给定的字符串,在 /var/www/html/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php
中调用我尝试重置对其负责的实体,但没有结果。这是所有跟踪:
TypeError {#478
#message: "Argument 3 passed to Doctrine\ORM\Mapping\OneToMany::__construct() must be of the type array or null, string given, called in /var/www/html/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php on line 971"
#code: 0
#file: "./vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OneToMany.php"
#line: 44
trace: {
./vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/OneToMany.php:44 { …}
./vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php:971 { …}
./vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php:719 { …}
./vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php:376 { …}
./vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php:178 { …}
./vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/PsrCachedReader.php:155 { …}
./vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/PsrCachedReader.php:88 { …}
./vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/PsrCachedReader.php:98 { …}
./vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php:331 { …}
./vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/Driver/MappingDriverChain.php:79 { …}
./vendor/doctrine/doctrine-bundle/Mapping/MappingDriver.php:45 { …}
./vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataFactory.php:134 { …}
./vendor/doctrine/doctrine-bundle/Mapping/ClassMetadataFactory.php:19 { …}
./vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php:382 { …}
./vendor/doctrine/persistence/lib/Doctrine/Persistence/Mapping/AbstractClassMetadataFactory.php:251 { …}
./vendor/doctrine/orm/lib/Doctrine/ORM/EntityManager.php:303 { …}
./var/cache/dev/ContainerX9n3NQZ/EntityManager_9a5be93.php:94 {
ContainerX9n3NQZ\EntityManager_9a5be93->getClassMetadata($className)^
›
› return $this->valueHolderda610->getClassMetadata($className);
› }
arguments: {
$className: "App\Entity\App\City"
}
}
./vendor/doctrine/doctrine-bundle/Repository/ServiceEntityRepository.php:45 { …}
./src/Repository/App/CityRepository.php:26 { …}
./var/cache/dev/ContainerX9n3NQZ/getCityRepositoryService.php:27 { …}
./var/cache/dev/ContainerX9n3NQZ/App_KernelDevDebugContainer.php:525 { …}
./var/cache/dev/ContainerX9n3NQZ/getCityServiceService.php:23 { …}
./var/cache/dev/ContainerX9n3NQZ/App_KernelDevDebugContainer.php:525 { …}
./var/cache/dev/ContainerX9n3NQZ/getDoctrine_FixturesLoadCommandService.php:43 { …}
./var/cache/dev/ContainerX9n3NQZ/App_KernelDevDebugContainer.php:525 { …}
./vendor/symfony/dependency-injection/Container.php:422 { …}
./vendor/symfony/dependency-injection/Argument/ServiceLocator.php:42 { …}
./vendor/symfony/console/CommandLoader/ContainerCommandLoader.php:45 { …}
./vendor/symfony/console/Application.php:551 { …}
./vendor/symfony/console/Application.php:519 { …}
./vendor/symfony/framework-bundle/Console/Application.php:126 { …}
./vendor/symfony/console/Application.php:664 { …}
Symfony\Component\Console\Application->Symfony\Component\Console\{closure}() {}
./vendor/symfony/console/Application.php:665 { …}
./vendor/symfony/framework-bundle/Console/Application.php:116 { …}
./vendor/symfony/console/Application.php:254 { …}
./vendor/symfony/framework-bundle/Console/Application.php:82 { …}
./vendor/symfony/console/Application.php:166 { …}
./bin/console:43 { …}
}
}
这是城市实体:
<?php
namespace App\Entity\App;
use App\DBAL\Types\Geolocation\Point;
use App\Entity\App\Graveyard;
use App\Repository\App\CityRepository;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
/**
* @ORM\Entity(repositoryClass=CityRepository::class)
* @ORM\Table (name="location", schema="app")
*/
class City
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column (type="integer")
*/
private $id;
/**
* @ORM\Column(type="string", length=255, nullable=false)
*/
private $name;
/**
* @ORM\Column(type="string", length=255, nullable=true)
*/
private $country;
/**
* @ORM\OneToMany(targetEntity=Company::class, mappedBy="city", cascade="persist")
*/
private $companies;
/**
* @ORM\OneToMany(targetEntity=Graveyard::class, mappedBy="city", cascade="persist")
*/
private $graveyards;
/**
* @ORM\OneToMany(targetEntity=FuneralParlor::class, mappedBy="city", cascade="persist")
*/
private $funeralParlors;
/**
* @ORM\OneToMany(targetEntity=AdvertisementTransfer::class, mappedBy="city")
*/
private $advertisementTransfers;
/**
* @ORM\OneToMany(targetEntity=Crematorium::class, mappedBy="city")
*/
private $crematoria;
/**
* @ORM\Column(type="point")
*/
private $coordinate;
/**
* @ORM\Column(type="string", length=255, nullable=true, options={"default" : null})
*/
private $province;
public function __construct()
{
$this->companies = new ArrayCollection();
$this->graveyards = new ArrayCollection();
$this->funeralParlors = new ArrayCollection();
$this->advertisementTransfers = new ArrayCollection();
$this->crematoria = new ArrayCollection();
}
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getCountry(): ?string
{
return $this->country;
}
public function setCountry(?string $country): self
{
$this->country = $country;
return $this;
}
/**
* @return Collection|Company[]
*/
public function getCompanies(): Collection
{
return $this->companies;
}
public function addCompany(Company $company): self
{
if (!$this->companies->contains($company)) {
$this->companies[] = $company;
$company->setCity($this);
}
return $this;
}
public function removeCompany(Company $company): self
{
if ($this->companies->removeElement($company)) {
// set the owning side to null (unless already changed)
if ($company->getCity() === $this) {
$company->setCity(null);
}
}
return $this;
}
/**
* @return Collection|Graveyard[]
*/
public function getGraveyards(): Collection
{
return $this->graveyards;
}
public function addGraveyard(Graveyard $graveyard): self
{
if (!$this->graveyards->contains($graveyard)) {
$this->graveyards[] = $graveyard;
$graveyard->setCity($this);
}
return $this;
}
public function removeGraveyard(Graveyard $graveyard): self
{
if ($this->graveyards->removeElement($graveyard)) {
// set the owning side to null (unless already changed)
if ($graveyard->getCity() === $this) {
$graveyard->setCity(null);
}
}
return $this;
}
/**
* @return Collection|FuneralParlor[]
*/
public function getFuneralParlors(): Collection
{
return $this->funeralParlors;
}
public function addFuneralParlor(FuneralParlor $funeralParlor): self
{
if (!$this->funeralParlors->contains($funeralParlor)) {
$this->funeralParlors[] = $funeralParlor;
$funeralParlor->setCity($this);
}
return $this;
}
public function removeFuneralParlor(FuneralParlor $funeralParlor): self
{
if ($this->funeralParlors->removeElement($funeralParlor)) {
// set the owning side to null (unless already changed)
if ($funeralParlor->getCity() === $this) {
$funeralParlor->setCity(null);
}
}
return $this;
}
/**
* @return Collection|AdvertisementTransfer[]
*/
public function getAdvertisementTransfers(): Collection
{
return $this->advertisementTransfers;
}
public function addAdvertisementTransfer(AdvertisementTransfer $advertisementTransfer): self
{
if (!$this->advertisementTransfers->contains($advertisementTransfer)) {
$this->advertisementTransfers[] = $advertisementTransfer;
$advertisementTransfer->setCity($this);
}
return $this;
}
public function removeAdvertisementTransfer(AdvertisementTransfer $advertisementTransfer): self
{
if ($this->advertisementTransfers->removeElement($advertisementTransfer)) {
// set the owning side to null (unless already changed)
if ($advertisementTransfer->getCity() === $this) {
$advertisementTransfer->setCity(null);
}
}
return $this;
}
/**
* @return Collection|Crematorium[]
*/
public function getCrematoria(): Collection
{
return $this->crematoria;
}
public function addCrematorium(Crematorium $crematorium): self
{
if (!$this->crematoria->contains($crematorium)) {
$this->crematoria[] = $crematorium;
$crematorium->setCity($this);
}
return $this;
}
public function removeCrematorium(Crematorium $crematorium): self
{
if ($this->crematoria->removeElement($crematorium)) {
// set the owning side to null (unless already changed)
if ($crematorium->getCity() === $this) {
$crematorium->setCity(null);
}
}
return $this;
}
public function getCoordinate(): Point
{
return $this->coordinate;
}
public function setCoordinate($coordinate): self
{
$this->coordinate = $coordinate;
return $this;
}
public function toJsonArray(): array
{
$coordinate = $this->getCoordinate();
return [
"id" => $this->getId(),
"name" => $this->getName(),
"country" => $this->getCountry(),
"coordinate" => $coordinate->toJsonArray()
];
}
public function getProvince(): ?string
{
return $this->province;
}
public function setProvince(?string $province): self
{
$this->province = $province;
return $this;
}
}
城市资料库:
<?php
namespace App\Repository\App;
use App\DBAL\Types\Geolocation\Point;
use App\Entity\App\City;
use App\Exception\City\CityAlreadyExistException;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\DBAL\FetchMode;
use Doctrine\ORM\AbstractQuery;
use Doctrine\ORM\OptimisticLockException;
use Doctrine\ORM\ORMException;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\Persistence\ManagerRegistry;
/**
* @method City|null find($id, $lockMode = null, $lockVersion = null)
* @method City|null findOneBy(array $criteria, array $orderBy = null)
* @method City[] findAll()
* @method City[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class CityRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, City::class);
}
/**
* Get all cities on DDBB
* @return int|mixed|string
*/
public function getAllCities() {
return $this->createQueryBuilder("c")->where('')->orderBy('name')->getQuery()->getResult();
}
public function getCityById(int $id): City {
return $this->createQueryBuilder('c')->where('id = :id')->setParameter('id', $id)->getQuery()->getResult();
}
public function getCityByName(string $name): ?City
{
$city = $this->createQueryBuilder('c')->where('name = :name')->setParameter('name', $name)->getQuery()->getResult();
return $city === null ? null : $city;
}
/**
* @throws CityAlreadyExistException
*/
public function createCity(City $city): ?City
{
try {
$entityManager = $this->getEntityManager();
$entityManager->persist($city);
$entityManager->flush();
return $city;
} catch (ORMException $e) {
throw new CityAlreadyExistException(sprintf("City %s already exist", $city->getName()));
}
}
public function calculateDistance(City $city, $lat, $lon)
{
$SQL = "
SELECT (ST_Distance(ST_MakePoint({$lat}, {$lon})::geography, ST_MakePoint(coordinate[0], coordinate[1])::geography) / 1000) as distance
FROM app.location
WHERE id = {$city->getId()}
";
return $this->executeSQL($SQL);
}
public function calculateDistanceBetweenPointInKm(Point $origin, Point $destiny)
{
$SQL = "
SELECT (ST_DISTANCE
(
ST_MakePoint({$origin->getLongitude()}, {$origin->getLatitude()})::geography,
ST_MakePoint({$destiny->getLongitude()}, {$destiny->getLatitude()})::geography
) / 1000) as distance
";
return $this->executeSQL($SQL)[0];
}
private function executeSQL(string $SQL)
{
$em = $this->getEntityManager();
$stmt = $em->getConnection()->prepare($SQL);
$stmt->execute();
return $stmt->fetchAll(FetchMode::COLUMN);
}
}
服务实体存储库(这是 doctrine 和 symfony 的默认设置):
class ServiceEntityRepository extends EntityRepository implements ServiceEntityRepositoryInterface
{
/**
* @param string $entityClass The class name of the entity this repository manages
* @psalm-param class-string<T> $entityClass
*/
public function __construct(ManagerRegistry $registry, string $entityClass)
{
$manager = $registry->getManagerForClass($entityClass);
if ($manager === null) {
throw new LogicException(sprintf(
'Could not find the entity manager for class "%s". Check your Doctrine configuration to make sure it is configured to load this entity’s metadata.',
$entityClass
));
}
parent::__construct($manager, $manager->getClassMetadata($entityClass));
}
}
已解决 - 经过时间和耐心的搜索,我发现了一个 ORM 符号错误。 composer json 文件被队友更新了,新版本的级联必须带括号,有一个地方是打开的但不是关闭的。