Documentação do Symfony - versão 3.1
Renderizada do repositório symfony-docs-pt-BR no Github
Se você abrir o arquivo de configuração da sua aplicação (geralmente app/config/config.yml
),
você verá seções de configuração diferentes, como framework
, twig
and doctrine
.
Cada uma dessas seções configura um bundle específico, te permitindo definir opções em um alto nível
e deixar o bundle fazer todas as mudanças complexas e de baixo nível baseado em suas configurações.
Por exemplo, a configuração a seguir diz ao FrameworkBundle que permita a integração de form, o que envolve a definição de alguns serviços bem como integração de outros componentes relacionados:
1 2 | framework:
form: true
|
1 2 3 4 5 6 7 8 9 10 11 12 | <?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:framework="http://symfony.com/schema/dic/symfony"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/symfony
http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
<framework:config>
<framework:form />
</framework:config>
</container>
|
1 2 3 | $container->loadFromExtension('framework', array(
'form' => true,
));
|
A ideia básica é que em vez de ter o usuário sobrescrevendo parâmetros individuais, você permite o usuário configurar algumas opções especificamente criadas. Como desenvolvedor do bundle, você analisa a configuração a carrega os serviços corretos e parâmetros dentro de uma classe “Extension”.
Como exemplo, imagine que você esta criando um bundle social, que provê integração
com Twitter. Para ser possível reusar seu bundle, você tem de fazer as variáveis
client_id
e client_secret
configuráveis. A configuração do seu bundle poderia
parecer com:
1 2 3 4 5 | # app/config/config.yml
acme_social:
twitter:
client_id: 123
client_secret: $ecret
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!-- app/config/config.xml -->
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:acme-social="http://example.org/dic/schema/acme_social"
xsi:schemaLocation="http://symfony.com/schema/dic/services
http://symfony.com/schema/dic/services/services-1.0.xsd">
<acme-social:config>
<twitter client-id="123" client-secret="$ecret" />
</acme-social:config>
<!-- ... -->
</container>
|
1 2 3 4 5 | // app/config/config.php
$container->loadFromExtension('acme_social', array(
'client_id' => 123,
'client_secret' => '$ecret',
));
|
See also
Leia mais sobre a extensão em /cookbook/bundles/extension.
Tip
Se um bundle provê uma classe Extension, geralmente você não deve sobrescrever algum parâmetro do contêiner de serviços deste bundle. A ideia é que se uma classe Extension está presente, toda configuração que deve ser configurável deve estar presente na configuração disponibilizada por esta classe. Em outras palavras, a classe de extensão define todas as definições de configurações cuja compatibilidade com versões anteriores será mantida.
See also
Para manipulação de parâmetros num contêiner de injeção de dependência veja /cookbook/configuration/using_parameters_in_dic.
$configs
¶Primeiramente você tem que criar um classe de extensão como explicado em Como expor uma Configuração Semântica para um Bundle.
Sempre que um usuário inclui a chave acme_social
(que é o pseudônimo do DI)
em um arquivo de configuração, a configuração sob ele é adicionada a um array de
configurações e passada ao método load()
da sua extensão (Symfony automaticamente
converte XML e YAML em array).
Para a configuração de exemplo na seção anterior, o array passado ao seu método
load()
vai se parecer com isso:
Note que esse é um array de arrays, não apenas um único array plano de valores
de configuração. Isto é intencional, uma vez que permite que o Symfony analise
várias fontes de recursos. Por exemplo, se acme_social
aparece em outro arquivo
de configuração - say config_dev.yml
- com valores diferentes abaixo dele,
o array de entrada deve parecer com isso:
array(
// values from config.yml
array(
'twitter' => array(
'client_id' => 123,
'client_secret' => '$secret',
),
),
// values from config_dev.yml
array(
'twitter' => array(
'client_id' => 456,
),
),
)
A ordem dos dois arrays depende de qual é configurado primeiro.
Mas não se preocupe! A configuração de componentes do Symfony vai ajudá-lo a mesclar esses valores,
prover padrões e oferecer erros de validação de usuário em casos de má configuração.
Segue como isso funciona. Crie uma classe Configuration
no diretório DependencyInjection
e construa uma árvore que defina a estrutura de configuração do seu pacote.
A classe Configuration
que lida com o exemplo de configuração parece com o seguinte:
// src/Acme/SocialBundle/DependencyInjection/Configuration.php
namespace Acme\SocialBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('acme_social');
$rootNode
->children()
->arrayNode('twitter')
->children()
->integerNode('client_id')->end()
->scalarNode('client_secret')->end()
->end()
->end() // twitter
->end()
;
return $treeBuilder;
}
}
See also
A classe Configuration
pode ser muito mais complicada do que mostrado aqui,
suportando nós “protótipo”, validação avançada, normalização específica de XML
e fusão avançada. Você pode ler mais sobre isso em
documentação do componente Config. Você
também pode ver isso em ação dando uma olhada em algumas classes de configuração
do core, como `FrameworkBungle Configuration`_ or the TwigBundle Configuration.
Agora esta classe pode ser usada em seu método load()
para mesclar configurações
e forçar validação (e.g. se uma opção adicional for passada uma exceção vai ser jogada):
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
// ...
}
O método processConfiguration()
usa a árvore de configuração que você definiu
na classe Configuration
para validar, normalizar e mesclar todas or arrays
de configuração juntos.
Tip
Em vez de chamar processConfiguration()
na sua extensão cada vez que que você
provêr opções de configuração, você deve querer usar a
ConfigurableExtension
para fazer isso automaticamente para você:
// src/Acme/HelloBundle/DependencyInjection/AcmeHelloExtension.php
namespace Acme\HelloBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
class AcmeHelloExtension extends ConfigurableExtension
{
// note that this method is called loadInternal and not load
protected function loadInternal(array $mergedConfig, ContainerBuilder $container)
{
// ...
}
}
Essa classe usa o método getConfiguration()
para instanciar a configuração.
Você deve sobrescrevê-lo se sua classe de configuração não se chama Configuration
ou se não está localizada no mesmo namespace que a extensão.
Se você tem múltiplos pacotes que dependem uns dos outros, será útil
permitir que uma classe Extension
modifique a configuração passada a
outra classe Extension
do bundle, como se o desenvolvedor-cliente tenha realmente
colocando aquela configuração no seu arquivo app/config/config.yml
. Isso pode ser
alcançado usando uma extensão pré-fixada. Para mais detalhes, veja
/cookbook/bundles/prepend_extension.
O comando config:dump-reference
imprimi a configuração padrão de um
bundle no console usando o formato Yaml.
Contanto que a configuração do seu bundle esteja localizada na localização
padrão (YourBundle\DependencyInjection\Configuration
) e não necessite de
receber argumentos no construtor isso funcionará automaticamente. Se você
têm algo diferente, sua classe Extension
deve sobrescrever o método
Extension::getConfiguration()
e retornar uma instância da sua Configuration
.
O Symfony permite às pessoas provês a configuração em três formatos diferentes: Yaml, XML and PHP. Ambos Yaml e PHP usam a mesma sintaxe e são suportados por padrão quando usam o componente Config. Suportar XML exige que você mais algumas coisas. Porém quando compartilhar seu pacote com outros, é recomendado seguir estes passos.
O componente Config provê alguns métodos por padrão para permitir processar configuração em XML corretamente. Veja ”:ref:component-config-normalization” da documentação do componente. Entretando, você pode fazer algumas coisas opcionais, isso vai melhorar a experiência de uso de configuração em XML.
No XML, o XML namespace é usado para determinar quais elementos pertencem
à configuração de um bundle específico. O namespace é retornado do método
Extension::getNamespace()
Por convenção, o namespace é uma URL (não tem de ser uma URL válida nem necessita existir).
Por padrão, o namespace de um bundle é http://example.org/dic/schema/DI_ALIAS
,
onde
DI_ALIAS
é o apelido do DI da extensão. Você deve querer alterar isso para uma URL mais profissional:// src/Acme/HelloBundle/DependencyInjection/AcmeHelloExtension.php // ... class AcmeHelloExtension extends Extension { // ... public function getNamespace() { return 'http://acme_company.com/schema/dic/hello'; } }
O XML tém uma funcionalidade muito útil chamada XML schema. Ela permite que você descreva todos os possíveis elementos e atributos e seus valores em um XML Schema Definition (um arquivo xsd). Esse arquivo XSD é usado por IDEs para auto compleção e é usado pelo componente Config para validar os elementos.
A fim de usar o schema, o arquivo de configuração XML deve prover um
atributo xsi:schemaLocation
apontando o arquivo XSD para um determinado
namespace XML. Esta localização sempre inicia com o namespace XML. Esse namespace XML
é então substituído pelo caminho base de validação XSD retornado do método
Extension::getXsdValidationBasePath()
Por convenção, o arquivo XSD fica em Resources/config/schema
, porém você
poe colocá-lo onde você preferir. Você deve retornar este caminho como o caminho base:
// src/Acme/HelloBundle/DependencyInjection/AcmeHelloExtension.php
// ...
class AcmeHelloExtension extends Extension
{
// ...
public function getXsdValidationBasePath()
{
return __DIR__.'/../Resources/config/schema';
}
}
Presumindo que o arquivo XSD se chame hello-1.0.xsd` a localização do schema
vai ser http://acme_company.com/schema/dic/hello-1.0.xsd
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <!-- app/config/config.xml -->
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:acme-hello="http://acme_company.com/schema/dic/hello"
xsi:schemaLocation="http://acme_company.com/schema/dic/hello
http://acme_company.com/schema/dic/hello/hello-1.0.xsd">
<acme-hello:config>
<!-- ... -->
</acme-hello:config>
<!-- ... -->
</container>
|