如何在 Symfony 中正确使用 '%' 转义 YAML 配置?

How to properly use '%' for escaping YAML configuration in Symfony?

在创建捆绑包时,通常需要为使用捆绑包的开发人员提供一些支持。configuration

在这种情况下,我需要配置的值来支持 %someText%,而不需要 Symfony trying to resolve this value as parameter

示例:配置不正确

my_bundle_name:
    my_configuration: '%someText%'

所以,我想,我必须转义 %(所以它看起来像 %%)才能使事情正常进行 - 导致值 %%someText%%

If some parameter value includes the % character, you need to escape it by adding another % so Symfony doesn't consider it a reference to a parameter name [...]

示例:没有错误,但出现意外结果

my_bundle_name:
    my_configuration: '%%someText%%'

虽然这解决了 You have requested a non-existent parameter[...] 错误,但实际值现在是 %%someText%%。我希望 Symfony return 取而代之的是 unsecaped 值,即 %someText%.

我当然可以 str_replace('%%', '%', '%%someText%%'),但这感觉有点老套。

如何更改值以实际获得 %someText%

这里是加载配置的地方:

// Namespace and use statements omitted for brevity
class MyBundleNameExtension extends ConfigurableExtension
{
    /**
     * @inheritDoc
     */
    protected function loadInternal(array $mergedConfig, ContainerBuilder $container)
    {
        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
        $loader->load('config.yml');

        p_r($mergedConfig["my_configuration"]); // Prints %%someText%%
    }
}

我已经验证使用 '" 会产生相同的结果。

问题

问题是 loadInternal 在处理参数之前被调用,因此,给我留下 %%someText%%

解决方案

我创建了一个 SetupListener class 像这样:

<?php

// Namespace and use statements omitted

class SetupListener
{
    /** @var ParameterBagInterface $parameterBag */
    private $parameterBag;

    /** @var ContainerInterface $container */
    private $container;

    /**
     * SetupListener constructor.
     * @param ParameterBagInterface $parameterBag
     * @param ContainerInterface $container
     */
    public function __construct(ParameterBagInterface $parameterBag, ContainerInterface $container)
    {
        $this->parameterBag = $parameterBag;
        $this->container = $container;
    }

    /**
     * @param RequestEvent $event
     */
    public function onSetup(RequestEvent $event)
    {
        if($event->isMasterRequest() && !$event->getRequest()->isXmlHttpRequest()) {
            $var = $this->parameterBag->get("my_configuration");
            // Further processing...
        }
    }
}

可能不是最优雅的解决方案,但它适合我。