为什么在 Symfony 项目中使用 "php bin/console cache:clear" 命令时会出现与 PHP8 #[ApiResource()] 属性相关的错误?

Why do I get an error associated with PHP8 #[ApiResource()] attribute when using "php bin/console cache:clear"command in Symfony project?

我是开发菜鸟,第一次使用PHP8属性,所以不知道问题出在哪里。 :s

我正在尝试配置 API 平台以确定用户可以看到哪些与我的 API 项目中的基本 HTTP 操作相关的属性。 为此,我使用 ApiPlatform 的 PHP8 属性:#[ApiResource()] 和 #[Groups()].

我正在使用 PHP8 - Symfony 5.3 - VSCode 1.58.2 - Window 10

问题:

  1. 在文档中似乎使用 normalizationContext 配置的 HTTP 操作没问题(正如预期的那样,PUT 在我的 api 文档中不再可见)但是属性不受影响(所有当我发出请求时,属性仍会发送)。我假设序列化组工作不正常...

  2. 我试图用命令“php bin/console cache:clear”清除 symfony 缓存。我收到一条消息,告诉我我的 #[ApiResource()] 属性中有一个解析错误,但我找不到它。

这是我的代码:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use App\Repository\ClientRepository;
use Doctrine\Common\Collections\Collection;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Serializer\Annotation\Groups;

/**
 * @ORM\Entity(repositoryClass=ClientRepository::class)
 */
#[ApiResource(
    collectionOperations: [
        'get' => [
            'normalizationContext' => [
                'groups' => [
                    'read_Client_collection',
                ],
            ],
        ],
        'post' => [
            'denormalizationContext' => [
                'groups' => [
                    'write_Client_item',
                ],
            ],
        ],
    ],
    itemOperations: [
        'get' => [
            'normalizationContext' => [
                'groups' => [
                    'read_Client_item',
                ],
            ],
        ],
        'delete',
        'patch' => [
            'denormalizationContext' => [
                'groups' => [
                    'write_Client_item',
                ],
            ],
        ],
    ],
)]
class Client
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    #[Groups(['read_Client_collection', 'read_User_collection', 'read_User_item'])]
    private $id;

    /**
     * @ORM\Column(type="string", length=75)
     */
    #[Groups(['read_Client_collection', 'read_Client_item', 'read_User_collection', 'read_User_item', 'write_Client_item'])]
    private $companyName;

    /**
     * @ORM\Column(type="string", length=20, nullable=true)
     */
    #[Groups(['read_Client_item', 'write_Client_item'])]
    private $phoneNumber;

    /**
     * @ORM\Column(type="string", length=255)
     */
    #[Groups(['read_Client_item', 'write_Client_item'])]
    private $address;

    /**
     * @ORM\Column(type="string", length=45)
     */
    #[Groups(['read_Client_item', 'write_Client_item'])]
    private $SiretNumber;

    /**
     * @ORM\OneToMany(targetEntity=User::class, mappedBy="client")
     */
    private $users;

    public function __construct()
    {
        $this->users = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getCompanyName(): ?string
    {
        return $this->companyName;
    }

    public function setCompanyName(string $companyName): self
    {
        $this->companyName = $companyName;

        return $this;
    }

    public function getAddress(): ?string
    {
        return $this->address;
    }

    public function setAddress(string $address): self
    {
        $this->address = $address;

        return $this;
    }

    public function getSiretNumber(): ?string
    {
        return $this->SiretNumber;
    }

    public function setSiretNumber(string $SiretNumber): self
    {
        $this->SiretNumber = $SiretNumber;

        return $this;
    }

    public function getPhoneNumber(): ?string
    {
        return $this->phoneNumber;
    }

    public function setPhoneNumber(?string $phoneNumber): self
    {
        $this->phoneNumber = $phoneNumber;

        return $this;
    }

    /**
     * @return Collection|User[]
     */
    public function getUsers(): Collection
    {
        return $this->users;
    }

    public function addUser(User $user): self
    {
        if (!$this->users->contains($user)) {
            $this->users[] = $user;
            $user->setClient($this);
        }

        return $this;
    }

    public function removeUser(User $user): self
    {
        if ($this->users->removeElement($user)) {
            // set the owning side to null (unless already changed)
            if ($user->getClient() === $this) {
                $user->setClient(null);
            }
        }

        return $this;
    }
}

这是我在尝试“php bin/console cache:clear”命令时终端出现的错误(第 32 行是“itemOperations: [”之前的唯一一条):

ParseError {#6596
#message: "syntax error, unexpected ','"
#code: 0
#file: "D:\...\project\src\Entity\Client.php"
#line: 32
trace: {
D:\...\project\src\Entity\Client.php:32 {
    Symfony\Component\ErrorHandler\DebugClassLoader->loadClass(string $class): void^
    ›     ],
    › ],
    › itemOperations: [
}
Symfony\Component\ErrorHandler\DebugClassLoader->loadClass() {}
spl_autoload_call() {}
D:\...\project\vendor\doctrine\annotations\lib\Doctrine\Common\Annotations\DocParser.php:1123 { …}
D:\...\project\vendor\doctrine\annotations\lib\Doctrine\Common\Annotations\DocParser.php:1245 { …}
D:\...\project\vendor\doctrine\annotations\lib\Doctrine\Common\Annotations\DocParser.php:1300 { …}
D:\...\project\vendor\doctrine\annotations\lib\Doctrine\Common\Annotations\DocParser.php:1220 { …}
D:\...\project\vendor\doctrine\annotations\lib\Doctrine\Common\Annotations\DocParser.php:1053 { …}
D:\...\project\vendor\doctrine\annotations\lib\Doctrine\Common\Annotations\DocParser.php:1035 { …}
D:\...\project\vendor\doctrine\annotations\lib\Doctrine\Common\Annotations\DocParser.php:869 { …}
D:\...\project\vendor\doctrine\annotations\lib\Doctrine\Common\Annotations\DocParser.php:719 { …}
D:\...\project\vendor\doctrine\annotations\lib\Doctrine\Common\Annotations\DocParser.php:376 { …}
D:\...\project\vendor\doctrine\annotations\lib\Doctrine\Common\Annotations\AnnotationReader.php:178 { …}
D:\...\project\vendor\doctrine\annotations\lib\Doctrine\Common\Annotations\PsrCachedReader.php:155 { …}
D:\...\project\vendor\doctrine\annotations\lib\Doctrine\Common\Annotations\PsrCachedReader.php:88 { …}
D:\...\project\vendor\api-platform\core\src\Util\AnnotationFilterExtractorTrait.php:47 { …}
D:\...\project\vendor\api-platform\core\src\Util\AnnotationFilterExtractorTrait.php:112 { …}
D:\...\project\vendor\api-platform\core\src\Bridge\Symfony\Bundle\DependencyInjection\Compiler\AnnotationFilterPass.php:65 { …}
D:\...\project\vendor\symfony\dependency-injection\Compiler\Compiler.php:91 { …}
D:\...\project\vendor\symfony\dependency-injection\ContainerBuilder.php:749 { …}
D:\...\project\vendor\symfony\http-kernel\Kernel.php:545 { …}
D:\...\project\vendor\symfony\http-kernel\Kernel.php:786 { …}
D:\...\project\vendor\symfony\http-kernel\Kernel.php:125 { …}
D:\...\project\vendor\symfony\framework-bundle\Console\Application.php:168 { …}
D:\...\project\vendor\symfony\framework-bundle\Console\Application.php:74 { …}
D:\...\project\vendor\symfony\console\Application.php:167 { …}
D:\...\project\vendor\symfony\runtime\Runner\Symfony\ConsoleApplicationRunner.php:56 { …}
D:\...\project\vendor\autoload_runtime.php:35 { …}
D:\...\project\bin\console:11 { …}
}
}

我试过没有成功:

它适用于解析错误...但是我的 API 文档完全是空的。

我 运行 没主意了... 感谢您的帮助:)

注意:问题不是特定于此实体文件:当我在客户端实体中抑制 ApiResource 属性时,问题切换到项目的其他资源实体。

我设法解决了我的问题...我不知道其他人是否可以参与解决方案,但以防万一...

  • 问题 1:标准化组不起作用:

通过写作

'normalizationContext' => [

我混合了两种不同的语法:

#[ApiResource(
    normalizationContext: ['groups' => ['read']],
    denormalizationContext: ['groups' => ['write']],
)]

#[ApiResource(attributes: [
    'normalization_context' => ['groups' => ['read']],
    'denormalization_context' => ['groups' => ['write']],
])]

我用 'normalization_context' 替换了 'normalizationContext' 并且群组现在工作正常...

  • 问题 2:当我使用“symfony cache:clear”命令时,#[ApiAttributes()] 中的解析错误:

我的 PHP 8.0.3 由 .php-version 文件确定,该文件位于我的 symfony 项目所在的文件夹的根目录中,但我的 windows 系统的其余部分 运行 PHP 7.3.12。 我也将系统 PHP 版本更改为 8.0.3,现在问题已解决。

(在window10,对于像我这样的菜鸟:

  • 右键单击屏幕左下角的 windows 图标
  • 点击“系统”
  • 点击“高级系统参数”(屏幕右侧)
  • 点击“环境变量”按钮
  • 在系统变量中,select“路径”并点击“修改”
  • 如果您想要的 php 版本不在列表中,请添加路径。
  • select 并将其移动到 php 版本列表的顶部。)

我认为问题是由于我的作曲家安装造成的:我为它进行了全局安装,所以当我更改 composer.json 文件以指示 php >=8.0 时,此操作会产生冲突在系统上使用 PHP 版本 运行ning。当我尝试“作曲家更新”命令时,一条消息告诉我。

也许我错了,所以如果有人能证实我的解释,那就太好了。谢谢大家

编辑: 我想出了如何让作曲家为项目选择相同的 PHP 版本而不是系统 PHP 版本。

在项目父文件夹中创建 .php-version 文件后(您在其中记下 php 版本以向 Symfony 客户端指定您希望此项目具体使用哪个版本),您必须 运行 'symfony composer diagnose' 命令相应地更改作曲家 PHP 版本。

这也有效:

#[ApiResource(
    attributes: [
        'normalization_context' => [
            'groups' => ['clients:read'],
        ],
        'denormalization_context' => [
            'groups' => ['clients:write'],
        ],
    ],
)]