从数据库加载 Symfony (5.2) 配置
Load Symfony (5.2) config from database
我是 Symfony 的新手,但我知道如何在 PHP 中使用 OOP。
我尝试(沮丧地)通过使用 Doctrine 实体将自定义参数与 Symfony 配置相结合。
为了解决我用于例如Michael Sivolobov 的回答: 和其他来源。
我的解决方案:
第 1 步:在配置文件夹中创建新包
-> config
-> packages
-> project
-> services.yaml
-> project
-> src
-> ParameterLoaderBundle.php
-> DependencyInjection
-> Compiler
-> ParameterLoaderPass.php
第 2 步:导入新资源
# config/services.yaml
...
imports:
- { resource: 'packages/project/config/services.yaml' }
...
第 3 步:包编码
# packages/project/config/services.yaml
services:
Project\:
resource: "../src"
<?php
namespace Project;
use Project\DependencyInjection\Compiler\ParameterLoaderPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class ParameterLoaderBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new ParameterLoaderPass(), PassConfig::TYPE_AFTER_REMOVING);
}
}
<?php
namespace Project\DependencyInjection\Compiler;
use App\Entity\SettingCategory;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class ParameterLoaderPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$em = $container->get('doctrine.orm.default_entity_manager');
$setting = $em->getRepository(SettingCategory::class)->findAll();
$container->setParameter('test', $setting);
}
}
我在 API 控制器中测试了新参数:
$this->getParameter('Test');
但是出现如下错误信息:
The parameter \"test\" must be defined.
这里发生了一些事情。首先,从数据库加载配置在 Symfony 中是非常不寻常的,所以你遇到困难也就不足为奇了。其次,您的流程代码永远不会被调用。调试的一部分是确保您期望调用的代码实际上被调用了。第三,您确实与尝试在配置下添加捆绑包有关。早在 Symfony 2 中,app/config 下曾经有更多与捆绑包相关的内容,这可能是您发现了一些旧文章并误解了它们。
但是,这里的大问题是 Symfony 有一个所谓的 'compile' 阶段,它基本上处理所有配置并缓存它。因此,CompilerPassInterface。不幸的是,服务本身在编译阶段不可用。它们根本不存在,所以没有实体管理器。如果你真的想从数据库加载配置,你需要打开你自己的数据库连接。您将只想使用数据库连接对象而不是实体管理器,因为编译阶段的一部分是处理实体本身。
所以摆脱你所有的代码并调整你的内核 class:
# src/Kernel.php
class Kernel extends BaseKernel implements CompilerPassInterface
{
use MicroKernelTrait;
public function process(ContainerBuilder $container)
{
$url = $_ENV['DATABASE_URL'];
$conn = DriverManager::getConnection(['url' => $url]);
$settings = $conn->executeQuery('SELECT * FROM settings')->fetchAllAssociative();
$container->setParameter('test',$settings);
}
请注意,即使所有这些工作正常,您也需要在更新设置后手动重建 Symfony 缓存 table。它不会是自动的。您真的可以考虑采用完全不同的方法。
我是 Symfony 的新手,但我知道如何在 PHP 中使用 OOP。 我尝试(沮丧地)通过使用 Doctrine 实体将自定义参数与 Symfony 配置相结合。
为了解决我用于例如Michael Sivolobov 的回答:
我的解决方案:
第 1 步:在配置文件夹中创建新包
-> config
-> packages
-> project
-> services.yaml
-> project
-> src
-> ParameterLoaderBundle.php
-> DependencyInjection
-> Compiler
-> ParameterLoaderPass.php
第 2 步:导入新资源
# config/services.yaml
...
imports:
- { resource: 'packages/project/config/services.yaml' }
...
第 3 步:包编码
# packages/project/config/services.yaml
services:
Project\:
resource: "../src"
<?php
namespace Project;
use Project\DependencyInjection\Compiler\ParameterLoaderPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class ParameterLoaderBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new ParameterLoaderPass(), PassConfig::TYPE_AFTER_REMOVING);
}
}
<?php
namespace Project\DependencyInjection\Compiler;
use App\Entity\SettingCategory;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class ParameterLoaderPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$em = $container->get('doctrine.orm.default_entity_manager');
$setting = $em->getRepository(SettingCategory::class)->findAll();
$container->setParameter('test', $setting);
}
}
我在 API 控制器中测试了新参数:
$this->getParameter('Test');
但是出现如下错误信息:
The parameter \"test\" must be defined.
这里发生了一些事情。首先,从数据库加载配置在 Symfony 中是非常不寻常的,所以你遇到困难也就不足为奇了。其次,您的流程代码永远不会被调用。调试的一部分是确保您期望调用的代码实际上被调用了。第三,您确实与尝试在配置下添加捆绑包有关。早在 Symfony 2 中,app/config 下曾经有更多与捆绑包相关的内容,这可能是您发现了一些旧文章并误解了它们。
但是,这里的大问题是 Symfony 有一个所谓的 'compile' 阶段,它基本上处理所有配置并缓存它。因此,CompilerPassInterface。不幸的是,服务本身在编译阶段不可用。它们根本不存在,所以没有实体管理器。如果你真的想从数据库加载配置,你需要打开你自己的数据库连接。您将只想使用数据库连接对象而不是实体管理器,因为编译阶段的一部分是处理实体本身。
所以摆脱你所有的代码并调整你的内核 class:
# src/Kernel.php
class Kernel extends BaseKernel implements CompilerPassInterface
{
use MicroKernelTrait;
public function process(ContainerBuilder $container)
{
$url = $_ENV['DATABASE_URL'];
$conn = DriverManager::getConnection(['url' => $url]);
$settings = $conn->executeQuery('SELECT * FROM settings')->fetchAllAssociative();
$container->setParameter('test',$settings);
}
请注意,即使所有这些工作正常,您也需要在更新设置后手动重建 Symfony 缓存 table。它不会是自动的。您真的可以考虑采用完全不同的方法。