Могу ли я включить дополнительный файл конфигурации в Symfony2?

Я хочу создать локальный файл конфигурации, config_local.yml, который позволяет настраивать каждую среду разработки правильно, не закручивая среды других людей. Я хочу, чтобы это был отдельный файл, так что я могу "gitignore" его и знаю, что в проекте нет ничего существенного, но одновременно не имеет проблемы с git, постоянно сообщая мне, что config_dev.yml имеет новые изменения (и работает риск того, что кто-то совершит эти изменения).

Сейчас у меня есть config_dev.yml, делающий

imports:
    - { resource: config_local.yml }

что отлично, если только файл не существует (т.е. для нового клона репозитория).

Мой вопрос: есть ли способ сделать это необязательным? I.e. Если файл существует, то импортируйте его, иначе проигнорируйте его.

Изменить: Я надеялся на синтаксис вроде:

imports:
    - { resource: config.yml }
    ? { resource: config_local.yml }

Ответы

Ответ 1

Решение состоит в создании отдельной среды, которая объясняется в Symfony2 cookbook. Если вы не хотите его создавать, существует еще один способ создания расширения.

// src/Acme/Bundle/AcmeDemo/DepencendyInjection/AcmeDemoExtension.php
namespace Acme\DemoBundle\DependencyInjection;

use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;

class AcmeDemoExtension extends Extension
{
    public function load(array $configs, ContainerBuilder $container)
    {   
        // All following files will be loaded from the configuration directory
        // of your bundle. You may change the location to /app/ of course.
        $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));

        try
        {
            $loader->load('config_local.yml');
        }
        catch(\InvalidArgumentException $e)
        {
            // File was not found
        }
    }
}

Некоторое копание в коде Symfony показало мне, что YamlFileLoader::load() FileLocator::locate() будет бросать \InvalidArgumentException, если файл не найден. Он вызывается YamlFileLoader::load().

Если вы используете соглашения об именах, расширение будет автоматически выполнено. Для более подробного объяснения посетите этот блог.

Ответ 2

Я знаю, что это действительно старый вопрос, и я считаю, что одобренное решение лучше, я думал, что я дам более простое решение, которое имеет смысл не менять код

Вы можете использовать опцию ignore_errors, которая не будет отображать какие-либо ошибки, если файл не существует

imports:
   - { resource: config_local.yml, ignore_errors: true }

Предупреждение, если у вас есть синтаксическая ошибка в файле, он также будет проигнорирован, поэтому, если у вас есть неожиданные результаты, проверьте, нет ли синтаксической ошибки или другой ошибки в файл.

Ответ 3

Существует еще один вариант.

в app/appKernel.php измените метод registerContainerConfiguration на это:

 public function registerContainerConfiguration(LoaderInterface $loader)
{
    $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');

    $extrafiles = array (
        __DIR__.'/config/config_local.yml',
    );

    foreach ($extrafiles as $filename) {
        if (file_exists($filename) && is_readable($filename)) {
             $loader->load($filename);
        }
    }
}

Таким образом, у вас есть глобальный файл config_local.yml, который перезаписывает файлы config_env.yml

Ответ 4

Я попробовал оба ответа выше, но никто не работал у меня.

  • я создал новую среду: "local", которая импортирует "dev", но, как вы можете прочитать здесь: Нет расширения, которое может загрузить конфигурацию для " web_profiler " вам также пришлось взломать класс AppKernel.
    Кроме того, вы не можете установить config_local.yml в .gitignore, потому что файл необходим в локальном env.

  • Так как мне пришлось взломать AppKernel, я попробовал этот подход с $extrafiles, но это привело к "ForbiddenOverwriteException"

Итак, теперь для меня работала модификация метода $extrafiles:
заменить в app/AppKernel.php
$loader->load(__DIR__ . '/config/config_' . $this->getEnvironment() . '.yml');
с

if ($this->getEnvironment() == 'dev') {
        $extrafiles = array(
            __DIR__ . '/config/config_local.yml',
        );
        foreach ($extrafiles as $filename) {
            if (file_exists($filename) && is_readable($filename)) {
                $loader->load($filename);
            }
        }
    } else {
        $loader->load(__DIR__ . '/config/config_' . $this->getEnvironment() . '.yml');
    }