symfony Drupal 10:通过编译器传递的参数值解析器给出类型错误

c9x0cxw0  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(109)

我在一个Drupal站点上发现了一个bug,我们正在升级到Drupal 10:
类型错误:Drupal\my_module\Controller\ApiController::catchAll():参数#1($request)必须是Symfony\Component\HttpFoundation\Request,Drupal\my_module\Entity\Channel中给出的Drupal\my_module\Controller\ApiController->catchAll()(modules/custom/my_module/src/Controller/ApiController.php的第50行)。
我们.似乎正在使用自定义服务通过编译器传递将当前Channel注入到控制器中,在我们尝试升级到D10之前,这一直工作得很好。现在看起来.
服务定义:

my_module.argument_resolver.channel_resolver:
    class: Drupal\my_module\Resolver\ChannelResolver
    arguments:
        - '@entity_type.manager'
    autowire: true
    tags:
        - { name: controller.argument_value_resolver, priority: 50 }

服务提供商:

class MyModuleServiceProvider extends ServiceProviderBase
{
    /**
     * {@inheritdoc}
     */
    public function register(ContainerBuilder $container)
    {
        $container->addCompilerPass(new ControllerArgumentValueResolverPass('http_kernel.controller.argument_resolver'));
    }
}

验证者通行证:

class ControllerArgumentValueResolverPass implements CompilerPassInterface
{
    use PriorityTaggedServiceTrait;

    private $argumentResolverService;
    private $argumentValueResolverTag;

    public function __construct($argumentResolverService = 'argument_resolver', $argumentValueResolverTag = 'controller.argument_value_resolver')
    {
        $this->argumentResolverService = $argumentResolverService;
        $this->argumentValueResolverTag = $argumentValueResolverTag;
    }

    public function process(ContainerBuilder $container)
    {
        if (!$container->hasDefinition($this->argumentResolverService)) {
            return;
        }

        $container
            ->getDefinition($this->argumentResolverService)
            ->replaceArgument(1,
                array_merge(
                    $this->findAndSortTaggedServices($this->argumentValueResolverTag, $container),
                    $container->getDefinition($this->argumentResolverService)->getArgument(1)
                ));
    }
}

如果还不清楚的话,我..

jgovgodb

jgovgodb1#

您似乎正在使用自定义服务通过编译器通道将 *'Channel '**实体注入到控制器参数中。过渡到Drupal 10似乎导致了控制器方法的预期参数类型与正在传递的实际参数之间的冲突。这可能是由于Symfony或Drupal核心的内部更改可能会影响编译器通道的行为。


**检查Drupal 10和Symfony文档:**该问题可能与Drupal 10或Symfony中的更改有关,特别是它们如何处理服务参数或控制器参数解析器。Review the migration documentation for Drupal 10和Symfony查看是否有任何破坏性更改。
**调试器传递:**在ControllerArgumentValueResolverPass类中,您可以添加调试语句来打印传递给控制器的参数。这有助于您了解编译过程中实际发生的情况。

public function process(ContainerBuilder $container)
{
    // Add debug statements here
    print_r($container->getDefinition($this->argumentResolverService)->getArgument(1));

    // Existing code...
}

**Controller中的类型检查:**在调用控制器逻辑之前,添加类型检查以查看实际传递的参数类型。

public function catchAll($request) {
    if (!($request instanceof Request)) {
        throw new \InvalidArgumentException('Invalid argument type');
    }
    // Rest of the code
}

**检查Resolver:**检查您的Resolver类以确保它解析为正确的类型。如果它将所有内容解析为Channel实体,则可能是罪魁祸首。
**调整优先级:**您已为自定义冲突解决程序设置了50的优先级。请尝试更改此优先级,以确保它不会覆盖其他基本冲突解决程序。

tags:
    - { name: controller.argument_value_resolver, priority: 10 }  # Changed priority
  • 解决问题 *

根据您在调试过程中发现的内容,您可能需要:
修改您的参数解析器,使其解析参数的方式更具选择性,特别是现在您使用Drupal 10。更新控制器方法签名以接受不同类型的参数,并使用运行时检查来相应地处理它们。更改应用自定义参数解析器的优先级或条件。
了解Symfony的服务容器、参数解析器和编译器传递是如何工作的对于调试此问题至关重要。鉴于您正在升级到Drupal 10,这些知识将帮助您不仅解决此问题,还可以解决迁移过程中可能出现的其他问题。
希望这对你有帮助。

相关问题