Doctrine - 传递给 __construct 的参数必须是一个数组

Posted

技术标签:

【中文标题】Doctrine - 传递给 __construct 的参数必须是一个数组【英文标题】:Doctrine - Argument passed to __construct must be an array [closed] 【发布时间】:2021-12-06 09:34:23 【问题描述】:

当我发现这个错误时,我只是尝试创建一个新服务。当我尝试列出可用的学说命令时,它会显示下一个错误:

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);
    

服务实体存储库(默认情况下来自于学说和 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));
    

【问题讨论】:

你很容易被SQL注入,你应该准备好你的请求,即使是在尝试执行rawSQL的时候。请参阅此处的示例:***.com/questions/3325012/… 我对 rawSQL 没有任何问题。它一直工作到昨天。今天我正在开发一个访问 Google Drive Api 的新工具。当我尝试上传更改时,我得到了那个错误。好久没碰城市班了。它正在工作。 我知道我需要清理和调整我的代码。我未来的任务之一是抽象所有类的原始 SQL 执行。但我现在的问题是我不能使用教义,因为我遇到了这个错误。 阅读错误,问题出在您的 OneToMany 注释上,检查它们,您会发现问题所在。 我在尝试,但找不到任何东西。这就像我第一次上传,并没有改变。我不知道为什么会显示该错误。 【参考方案1】:

已解决 - 经过时间和耐心的搜索,我发现 ORM 符号有一个错误。 composer json 文件由队友更新,在新版本中,级联必须带括号,在一个地方它是打开而不是关闭。

【讨论】:

以上是关于Doctrine - 传递给 __construct 的参数必须是一个数组的主要内容,如果未能解决你的问题,请参考以下文章

Symfony-Catchable致命错误:传递给Doctrine Common Collections ArrayCollection :: __ construct()的参数1必须是类(代码

如何通过 ZF2 FormElementManager 将 Doctrine ObjectManager 传递给表单

Doctrine_Collection __toString() 类型的功能

在 $_SESSION 中存储 Doctrine 对象

application / config / doctrine / proxies __ CG__ConcreteCoreEntitySiteType.php):无法打开流:没有这样的文件或目录,(

高手入门资格