Tengo un archivo de parámetros en una aplicación que utiliza consola symfony 3.2, configuración y componente YAML , y trato de configurar Parámetros externos del entorno variable en los parámetros del Contenedor de servicios.

Creo un generador de contenedores.

$container = new ContainerBuilder();

Estoy usando el localizador de archivos para localizar recursos:

$container = new ContainerBuilder();

Resolver cargador para cargar recursos

LoaderResolver();

Y usando el método de carga:

$this->load('parameters.yml');

parámetros.yml archivo:

parameters:
  database:
    driver: pdo_mysql
    host: 127.0.0.1
    dbname: dbname
    user: env(VAL1)
    password: env(VAL2)
  Local: us-en

Después de compilar el contenedor e intentar verificar los valores de la bolsa de parámetros:

$container->getParameterBag()->all()

Me devuelve valores como este:

env_VAL1_3ec776edc429c1734ed780a29a0af538 , env_VAL2_3ec776edc429c1734ed780a29a0af538

Creo que el contenedor no puede resolver esos valores del entorno.

Nota: configuré la variable de entorno usando:

$ export VAL1='SOME TEXT'

Alguien tiene una idea de por qué?

4
SMSM 27 dic. 2016 a las 04:46

3 respuestas

La mejor respuesta

Así que pasé un tiempo investigando este 'problema' y esto es lo que descubrí ...

La única forma de hacer que env(VAL1) funcione es generar el contenedor en un archivo PHP usando PHPDumper y luego usar el contenedor generado. No hay otra forma de hacerlo funcionar porque solo resuelve el entorno en ese archivo.

En el proyecto normal de Symfony hay un archivo var/cache/dev/appDevDebugProjectContainer.php generado. Hay un método getDynamicParameter que se parece a esto

 private function getDynamicParameter($name)
    {
        switch ($name) {
            case 'kernel.root_dir': $value = ($this->targetDirs[3].'/app'); break;
            case 'kernel.logs_dir': $value = ($this->targetDirs[2].'/logs'); break;
            case 'user': $value = $this->getEnv('VAL1'); break;
            case 'session.save_path': $value = ($this->targetDirs[3].'/app/../var/sessions/dev'); break;
            case 'router.resource': $value = ($this->targetDirs[3].'/app/config/routing_dev.yml'); break;
            default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name));
        }
        $this->loadedDynamicParameters[$name] = true;

        return $this->dynamicParameters[$name] = $value;
    }

Es el único lugar donde se evalúa el env(VAL1).

Entonces, para su caso, la solución es la siguiente.

Usé parameters.yml simplificado:

parameters:
    user: '%env(VAL1)%'

El export que hice:

export VAL1=abc

Código PHP:

$container = new ContainerBuilder();

$loader = new YamlFileLoader(
    $container,
    new FileLocator('.')
);

$loader->load('parameters.yml');

$container->compile();

$dumper = new PhpDumper($container);

$content = $dumper->dump(
    [
        'class' => 'DumpedContainer',
        'base_class' => 'Container',
        'file' => 'DumpedContainer.php',
        'debug' => true
    ]
);

// Use this code if you want to write file to the disk
$cache = new ConfigCache('DumpedContainer.php', true);
$cache->write($content, $container->getResources());
require_once $cache->getPath();

// ... otherwise use this code
//$content = str_replace('<?php', '', $content);
//eval($content);

$container = new DumpedContainer();

$user = $container->getParameter('user'); // $user = 'abc'

En el código generado verás el siguiente método que hace la magia

private function getDynamicParameter($name)
{
    switch ($name) {
        case 'user': $value = $this->getEnv('VAL1'); break;
        default: throw new InvalidArgumentException(sprintf('The dynamic parameter "%s" must be defined.', $name));
    }
    $this->loadedDynamicParameters[$name] = true;

    return $this->dynamicParameters[$name] = $value;
}

Esta solución funciona bien pero, al mirarla, me pregunto si esto realmente es necesario en su proyecto ¿Qué le pasa a getenv()?

6
Stepashka 3 ene. 2017 a las 16:03

Si usa Symfony \ Bundle \ FrameworkBundle \ Test \ WebTestCase en lugar de \ PHPUnit_Framework_TestCase Symfony3, haga la magia por usted.

$client = static::createClient();
$this->container = $client->getContainer();
$user = $container->getParameter('user'); // $user = 'abc'

Echa un vistazo a http://symfony.com/doc/current/testing. html # your-first-funcional-test

Con este método, también podrá modificar las configuraciones de Symfony utilizando archivos específicos * _test.yml.

Creo que este es el camino correcto.

-1
aqquadro 5 jul. 2017 a las 09:42

Por favor, inténtalo:

parameters:
database:
    driver: pdo_mysql
    host: 127.0.0.1
    dbname: dbname
    user: '%env(VAL1)%'
    password: '%env(VAL2)%'
log_path: /logs

Creo que ese es el problema. Consulte esta documentación para referencia: http://symfony.com/doc/current/configuration/external_parameters.html

1
Alvin Bunk 27 dic. 2016 a las 05:27