PHP 更新 8.0 至 8.1:Doctrine 注释解析器错误

问题描述 投票:0回答:1

有谁知道从 PHP 8.0 到 8.1 旧的 Doctrine 注释发生了什么变化?我有一个带有 Doctrine 注释的遗留代码,需要暂时迁移到 PHP 8.1。整个事情现在在 PHP 8.0 下运行。

在 PHP 8.1 下出现以下错误:

Doctrine\Common\Annotations\DocLexer::T_CLOSE_PARENTHESIS, 
got 'CLASS' at position 25 in class @Doctrine\ORM\Mapping\Entity.

词法分析器/解析器不再正确解释以下注释

/**
 * @Annotation
 * @Target("CLASS")
 */

正如我所说,它在 8.0 下工作 - 代码/库中没有任何更改。我的猜测是,在 PHP 8.1 下,要么注释的解释不同(双引号?),要么比较操作(==)发生了变化。我认为双引号不再被正确识别。 这是一个快速、临时的解决方案。当前 Doctrine 版本的完整代码转换正在进行中,但由于项目的复杂性,需要一些时间。

完整的错误堆栈:

{
            "file": "\/html\/frontend\/www\/backend\/vendor\/doctrine\/annotations\/lib\/Doctrine\/Common\/Annotations\/DocParser.php",
            "line": 445,
            "function": "syntaxError",
            "class": "Doctrine\\Common\\Annotations\\AnnotationException",
            "type": "::",
            "args": [
                "Expected Doctrine\\Common\\Annotations\\DocLexer::T_CLOSE_PARENTHESIS, got \u0027CLASS\u0027 at position 25 in class @Doctrine\\ORM\\Mapping\\Entity."
            ]
        },
        {
            "file": "\/html\/frontend\/www\/backend\/vendor\/doctrine\/annotations\/lib\/Doctrine\/Common\/Annotations\/DocParser.php",
            "line": 399,
            "function": "syntaxError",
            "class": "Doctrine\\Common\\Annotations\\DocParser",
            "type": "-\u003E",
            "args": [
                "Doctrine\\Common\\Annotations\\DocLexer::T_CLOSE_PARENTHESIS"
            ]
        },
        {
            "file": "\/html\/frontend\/www\/backend\/vendor\/doctrine\/annotations\/lib\/Doctrine\/Common\/Annotations\/DocParser.php",
            "line": 863,
            "function": "match",
            "class": "Doctrine\\Common\\Annotations\\DocParser",
            "type": "-\u003E",
            "args": [
                103
            ]
        },
        {
            "file": "\/html\/frontend\/www\/backend\/vendor\/doctrine\/annotations\/lib\/Doctrine\/Common\/Annotations\/DocParser.php",
            "line": 770,
            "function": "MethodCall",
            "class": "Doctrine\\Common\\Annotations\\DocParser",
            "type": "-\u003E",
            "args": []
        },
        {
            "file": "\/html\/frontend\/www\/backend\/vendor\/doctrine\/annotations\/lib\/Doctrine\/Common\/Annotations\/DocParser.php",
            "line": 654,
            "function": "Annotation",
            "class": "Doctrine\\Common\\Annotations\\DocParser",
            "type": "-\u003E",
            "args": []
        },
        {
            "file": "\/html\/frontend\/www\/backend\/vendor\/doctrine\/annotations\/lib\/Doctrine\/Common\/Annotations\/DocParser.php",
            "line": 359,
            "function": "Annotations",
            "class": "Doctrine\\Common\\Annotations\\DocParser",
            "type": "-\u003E",
            "args": []
        },
        {
            "file": "\/html\/frontend\/www\/backend\/vendor\/doctrine\/annotations\/lib\/Doctrine\/Common\/Annotations\/DocParser.php",
            "line": 515,
            "function": "parse",
            "class": "Doctrine\\Common\\Annotations\\DocParser",
            "type": "-\u003E",
            "args": [
                "\/**\r\n * @Annotation\r\n * @Target(\u0022CLASS\u0022)\r\n *\/",
                "class @Doctrine\\ORM\\Mapping\\Entity"
            ]
        },
        {
            "file": "\/html\/frontend\/www\/backend\/vendor\/doctrine\/annotations\/lib\/Doctrine\/Common\/Annotations\/DocParser.php",
            "line": 744,
            "function": "collectAnnotationMetadata",
            "class": "Doctrine\\Common\\Annotations\\DocParser",
            "type": "-\u003E",
            "args": [
                "Doctrine\\ORM\\Mapping\\Entity"
            ]
        },
        {
            "file": "\/html\/frontend\/www\/backend\/vendor\/doctrine\/annotations\/lib\/Doctrine\/Common\/Annotations\/DocParser.php",
            "line": 654,
            "function": "Annotation",
            "class": "Doctrine\\Common\\Annotations\\DocParser",
            "type": "-\u003E",
            "args": []
        },
        {
            "file": "\/html\/frontend\/www\/backend\/vendor\/doctrine\/annotations\/lib\/Doctrine\/Common\/Annotations\/DocParser.php",
            "line": 359,
            "function": "Annotations",
            "class": "Doctrine\\Common\\Annotations\\DocParser",
            "type": "-\u003E",
            "args": []
        },
        {
            "file": "\/html\/frontend\/www\/backend\/vendor\/doctrine\/annotations\/lib\/Doctrine\/Common\/Annotations\/AnnotationReader.php",
            "line": 221,
            "function": "parse",
            "class": "Doctrine\\Common\\Annotations\\DocParser",
            "type": "-\u003E",
            "args": [
                "\/**\n * @ORM\\Entity\n * @ORM\\Table(name=\u0022appointment\u0022)\n * @PIM\\Config(label=\u0022Termine\u0022, labelProperty=\u0022title\u0022, sortBy=\u0022bookedDate\u0022, tabs=\u0022{\u0027contact\u0027: \u0027Kundendaten\u0027}\u0022, sort=10)\n *\/",
                "class Custom\\Entity\\Appointment\\Appointment"
            ]
        },
        {
            "file": "\/html\/frontend\/www\/backend\/lib\/contentfly\/Classes\/Api.php",
            "line": 1414,
            "function": "getClassAnnotations",
            "class": "Doctrine\\Common\\Annotations\\AnnotationReader",
            "type": "-\u003E",
            "args": [
                {
                    "name": "Custom\\Entity\\Appointment\\Appointment"
                }
            ]
        }
php doctrine
1个回答
0
投票

这可能不是一个有效的答案,但是您是否尝试过以下语法:

/**
 * @Annotation
 * @Target({"CLASS"})
 */

对于处理遗留代码,我强烈建议使用 Rector 将代码更新到 PHP 8.1 标准。

安装校长:

command composer require --dev 'rector/rector'

首次启动Rector生成默认配置文件 (`rector.php`):

command php 'vendor/bin/rector' 'process' --dry-run

Symfony 项目的 Rector 配置示例(在

rector.php
中)是:

<?php

declare(strict_types=1);

use Rector\CodeQuality\Rector\Class_\InlineConstructorDefaultToPropertyRector;
use Rector\Config\RectorConfig;
use Rector\Doctrine\Set\DoctrineSetList;
use Rector\Set\ValueObject\LevelSetList;
use Rector\Set\ValueObject\SetList;
use Rector\Symfony\Bridge\Symfony\Routing\SymfonyRoutesProvider;
use Rector\Symfony\CodeQuality\Rector\ClassMethod\ActionSuffixRemoverRector;
use Rector\Symfony\Contract\Bridge\Symfony\Routing\SymfonyRoutesProviderInterface;
use Rector\Symfony\Set\SymfonySetList;

return static function (RectorConfig $rectorConfig): void {
    $rectorConfig->paths([
        __DIR__.'/config',
        __DIR__.'/public',
        __DIR__.'/src',
        __DIR__.'/tests',
    ]);

    // register a single rule
    $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class);

    // Provide Symfony XML Service List.
    $rectorConfig->symfonyContainerXml(__DIR__.'/var/cache/dev/App_KernelDevDebugContainer.xml');
    // define sets of rules
    $rectorConfig->sets([
        SetList::DEAD_CODE,
        LevelSetList::UP_TO_PHP_81,
        DoctrineSetList::DOCTRINE_CODE_QUALITY,
        SymfonySetList::SYMFONY_64,
        SymfonySetList::SYMFONY_CODE_QUALITY,
        SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION,
    ]);

    // Provide Symfony PHP container.
    $rectorConfig->symfonyContainerPhp(__DIR__.'/tests/RectorSymfonyContainer.php');

    // Add Symfony Route annotation config.
    $rectorConfig->singleton(SymfonyRoutesProvider::class);
    $rectorConfig->alias(SymfonyRoutesProvider::class, SymfonyRoutesProviderInterface::class);

    // skip ActionSuffixRemoverRector for SonataAdmin Controler.
    $rectorConfig->skip([
        ActionSuffixRemoverRector::class => [
            __DIR__.'/src/*/Controller/Admin/*Controller.php',
        ],
    ]);
};

根据您的 PHP 和 Symfony 版本调整此配置(或者如果您的项目不使用 Symfony,则删除对 Symfony 的引用),并查看 Rector 提出的更改:

php 'vendor/bin/rector' 'process' --dry-run
© www.soinside.com 2019 - 2024. All rights reserved.