Как правильно использовать «%» для экранирования конфигурации YAML в Symfony? - PullRequest
0 голосов
/ 15 февраля 2020

Когда дело доходит до создания пакетов, часто необходимо поддерживать некоторую конфигурацию для разработчиков, которые будут использовать пакет.

В этом случае мне нужно значение конфигурации для поддержки %someText%, без Symfony, пытаясь разрешить это значение как параметр .

Пример: неправильная конфигурация

my_bundle_name:
    my_configuration: '%someText%'

Итак, я подумал, что мне придется экранировать % (чтобы он выглядел как %%), чтобы все заработало - в результате получается значение %%someText%%.

Если значение какого-либо параметра включает% символ, вам нужно экранировать его, добавив еще один%, чтобы Symfony не считал его ссылкой на имя параметра [...]

Пример: без ошибок, но неожиданно Результат

my_bundle_name:
    my_configuration: '%%someText%%'

Хотя это устраняет ошибку You have requested a non-existent parameter[...], фактическое значение теперь равно %%someText%%. Я ожидал, что Symfony вернет вместо этого unsecaped , то есть %someText%.

Конечно, я мог бы str_replace('%%', '%', '%%someText%%'), но это похоже на хак-я sh.

Как бы я изменил значение, чтобы фактически получить %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%%
    }
}

I ' мы убедились, что использование ' и " дает одинаковый результат.

1 Ответ

1 голос
/ 05 марта 2020

Проблема

Проблема заключалась в том, что loadInternal был вызван до обработки параметров, поэтому у меня осталось %%someText%%.

Решение

Я создал класс SetupListener следующим образом:

<?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...
        }
    }
}

Возможно, это не самое элегантное решение, но оно работает для меня.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...