没有 PSR-4 的遗留控制器的 Symfony 自动装配
Symfony Autowiring for Legacy-Controllers without PSR-4
我有一个旧版应用程序,我正在使用 Symfony。
目前一切正常。
现在我想为我的遗留控制器使用自动装配。
- 它们是使用作曲家
classmap
功能加载的
- 在根命名空间中(例如
\Controller_Page
)
- class 名称与文件名不同
是的。我知道这很糟糕。但这是遗留问题,我现在不想触及每个控制器(该应用程序中存在更大的问题)。
我想使用依赖注入和自动装配来减少(可怕的)混乱。
以下是我已经尝试过的一些方法:
services:
_defaults:
autowire: true
autoconfigure: true
"\":
resource: '../legacy/Controller'
tags: ['controller.service_arguments']
Namespace is not a valid PSR-4 prefix
services:
_defaults:
autowire: true
autoconfigure: true
"":
resource: '../legacy/Controller'
tags: ['controller.service_arguments']
Namespace prefix must end with a "\"
// in Kernel::configureContainer()
$container->registerForAutoconfiguration(\BaseController::class);
(我的 \BaseController
只有 Symfony\Component\HttpFoundation\RequestStack
作为 __construct
参数)
Controller "BaseController" has required constructor arguments and does not exist in the container. Did you forget to define such a service?
// in Kernel::configureContainer()
$container->registerForAutoconfiguration(\Controller_Legacy::class);
Cannot load resource "4208ad7faaf7d383f981bd32e92c4f2f".
我不知道如何做到这一点。
感谢您的帮助。
编辑 1
更进一步。
我完成了其中一个遗留控制器的自动配置:
// Kernel.php
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
{
$container->addDefinitions([
\Controller_Legacy::class => (new Definition(\Controller_Legacy::class))
->setAutowired(true)
->setAutoconfigured(true)
->addTag('controller.service_arguments'),
]);
// ...
}
看来我之前的问题是由 yaml 配置或 smth 而不是容器本身引起的。
现在我必须找到一种方法来注册我所有的旧版控制器。
如果我找到一个好的解决方案,我会尝试一下并更新。
(非常欢迎好的解决方案)
编辑2
好的,这不是 YAML 配置。如果我使用 PHP-Configuration
我遇到了同样的问题。
/** @var $this \Symfony\Component\DependencyInjection\Loader\PhpFileLoader */
$definition = new Definition();
$definition
->setAutowired(true)
->setAutoconfigured(true)
->setPublic(false)
;
$this->registerClasses($definition, '\', '../legacy/*');
Namespace is not a valid PSR-4 prefix.
我现在将尝试手动注册 classes。
好的,我在原题中添加了导致这个结果的步骤。
对我来说,这个解决方案有效。
它可能不是最好的,但可以解决问题。
(尽管开放以获得更好的建议)。
在 Kernel.php
中,我滥用 composer-Autoloader 获取我需要的 类 并将它们注册为服务。由于未使用的服务将被删除,所以我没有问题:-)
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
{
/** @var ClassLoader $classLoader */
$classLoader = require $this->getProjectDir().'/vendor/autoload.php';
foreach (array_keys($classLoader->getClassMap()) as $class) {
$definition = (new Definition($class))
->setAutowired(true)
->setAutoconfigured(true)
->setPublic(false);
$container->setDefinition($class, $definition);
}
// Since my ClassMap contains not only controllers, I add the 'controller.service_arguments'-Tag
// after the loop.
$container
->registerForAutoconfiguration(\BaseController::class)
->addTag('controller.service_arguments');
// ...
}
我有一个旧版应用程序,我正在使用 Symfony。 目前一切正常。
现在我想为我的遗留控制器使用自动装配。
- 它们是使用作曲家
classmap
功能加载的 - 在根命名空间中(例如
\Controller_Page
) - class 名称与文件名不同
是的。我知道这很糟糕。但这是遗留问题,我现在不想触及每个控制器(该应用程序中存在更大的问题)。
我想使用依赖注入和自动装配来减少(可怕的)混乱。
以下是我已经尝试过的一些方法:
services:
_defaults:
autowire: true
autoconfigure: true
"\":
resource: '../legacy/Controller'
tags: ['controller.service_arguments']
Namespace is not a valid PSR-4 prefix
services:
_defaults:
autowire: true
autoconfigure: true
"":
resource: '../legacy/Controller'
tags: ['controller.service_arguments']
Namespace prefix must end with a "\"
// in Kernel::configureContainer()
$container->registerForAutoconfiguration(\BaseController::class);
(我的 \BaseController
只有 Symfony\Component\HttpFoundation\RequestStack
作为 __construct
参数)
Controller "BaseController" has required constructor arguments and does not exist in the container. Did you forget to define such a service?
// in Kernel::configureContainer()
$container->registerForAutoconfiguration(\Controller_Legacy::class);
Cannot load resource "4208ad7faaf7d383f981bd32e92c4f2f".
我不知道如何做到这一点。 感谢您的帮助。
编辑 1
更进一步。 我完成了其中一个遗留控制器的自动配置:
// Kernel.php
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
{
$container->addDefinitions([
\Controller_Legacy::class => (new Definition(\Controller_Legacy::class))
->setAutowired(true)
->setAutoconfigured(true)
->addTag('controller.service_arguments'),
]);
// ...
}
看来我之前的问题是由 yaml 配置或 smth 而不是容器本身引起的。
现在我必须找到一种方法来注册我所有的旧版控制器。 如果我找到一个好的解决方案,我会尝试一下并更新。 (非常欢迎好的解决方案)
编辑2
好的,这不是 YAML 配置。如果我使用 PHP-Configuration 我遇到了同样的问题。
/** @var $this \Symfony\Component\DependencyInjection\Loader\PhpFileLoader */
$definition = new Definition();
$definition
->setAutowired(true)
->setAutoconfigured(true)
->setPublic(false)
;
$this->registerClasses($definition, '\', '../legacy/*');
Namespace is not a valid PSR-4 prefix.
我现在将尝试手动注册 classes。
好的,我在原题中添加了导致这个结果的步骤。 对我来说,这个解决方案有效。 它可能不是最好的,但可以解决问题。 (尽管开放以获得更好的建议)。
在 Kernel.php
中,我滥用 composer-Autoloader 获取我需要的 类 并将它们注册为服务。由于未使用的服务将被删除,所以我没有问题:-)
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
{
/** @var ClassLoader $classLoader */
$classLoader = require $this->getProjectDir().'/vendor/autoload.php';
foreach (array_keys($classLoader->getClassMap()) as $class) {
$definition = (new Definition($class))
->setAutowired(true)
->setAutoconfigured(true)
->setPublic(false);
$container->setDefinition($class, $definition);
}
// Since my ClassMap contains not only controllers, I add the 'controller.service_arguments'-Tag
// after the loop.
$container
->registerForAutoconfiguration(\BaseController::class)
->addTag('controller.service_arguments');
// ...
}