Beruflich Dokumente
Kultur Dokumente
app/
console
cache/
config/
logs/
Resources/
src/
AppBundle/
vendor/
web/
Symfony propone esta jerarqua de archivos y directorios para estructurar tus aplicaciones.
El propsito de cada archivo/directorio es el siguiente:
app/cache/, almacena todos los archivos de cach generados por la aplicacin.
app/config/, almacena toda la informacin definida para cada entorno de ejecucin.
app/logs/, almacena todos los archivos de log donde se guardan los mensajes de log
generados por la aplicacin.
app/Resources/, almacena todas las plantillas de la aplicacin y todos los archivos de
traducciones.
src/AppBundle/, almacena todo el cdigo especfico de Symfony (controladores,
rutas, etc.) y todo tu cdigo propio (clases de tu lgica de negocio, entidades de
Doctrine, etc.)
vendor/, este es el directorio donde Composer instala las dependencias de la
aplicacin y por tanto nunca deberas tocar nada en este directorio.
web/, almacena los controladores frontales y todos los assets relacionados con el
frontend, tales como archivos CSS, archivos JavaScript y las imgenes.
Bundles
Los bundles estn pensados para que sean elementos de software que se pueden reutilizar
de manera autnoma. En otras palabras, si tienes por ejemplo un bundle llamado
UserBundle pero que no puedes reutilizarlo tal y como est en otras aplicaciones Symfony2,
entonces ese bundle est mal hecho. Lo mismo que si tu bundle InvoiceBundle depende de
otro bundle como ProductBundle. Se trata de un error y estos dos elementos no deberan
ser bundles independientes
1
Dentro de las buenas practicas se aconseja crear solo un bundle llamado AppBundle para
poder tener el codigo mas ordenado y sea mas facil leerlo y escribirlo.
La idea de este bundle es que no sea reutilizado.
Este wizard, nos dara varias opciones para generar nuestro bundle y se encargara de crear el
esqueleto del bundle, asi como la modfiicacion de los archivos necesarios para su uso.
Uno puede crear un bundle de forma manual, pero para ello hay que realizar las siguientes
tareas.
use Symfony\Component\HttpKernel\Bundle\Bundle;
Esta clase tiene que estar dentro del directorio raz del bundle, la clase tiene que heredar de
Bundle.
2. Registrar el Bundle
2
De esta manera estamos avisando a symfony que existe un nuevo bundle, y que
necesitamos que lo empiece a utilizar.
Herencia y reutilizacin
Configuracion de bundles
3
Teniendo en cuenta el archivo config.yml, la siguiente configuracin le dice a
FrameworkBundle que active la integracin de formularios, que incluye la definicin de unos
cuantos services as como la integracin de otros componentes relacionados:
framework:
form: true
Configurando el bundle.
Una de las formas mas comunes de configurar un bundle, es que el mismo tenga sus propios
archivos de configuracion, para cargar la configuracin tienes que crear una extensin
Dependency Injection para tu bundle. Esta clase tiene algunas convenciones para poder ser
detectado automticamente, pero despues vers cmo puedes cambiarlo para tus propias
necesidades. Por defecto, Extension tiene que ajustarse a las siguientes convenciones:
// src/AppBundle/DependencyInjection/AppExtension.php
namespace AppBundle\DependencyInjection;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
4
Registrar manualmente una clase Extension
// ...
use AppBundle\DependencyInjection\UnconventionalExtensionClass;
El metodo load
En el mtodo load() puedes usar el cdigo PHP para registrar definiciones de services, pero
es ms frecuente que pongas estas definiciones en un archivo de configuracin (usando
YAML, XML o PHP). Por suerte puedes emplear file loaders en la extensin.
5
Por ejemplo si tenemos un archivo llamado services.xml en el directorio Resources/config
de tu bundle, tu mtodo load ser as:
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\Config\FileLocator;
// ...
public function load(array $configs, ContainerBuilder $container)
{
$loader = new XmlFileLoader(
$container,
new FileLocator(__DIR__.'/../Resources/config')
);
$loader->load('services.xml');
}
Otros loaders disponibles son YamlFileLoader, PhpFileLoader e IniFileLoader (este ltimo
slo puede usarse para cargar parmetros y slo puede cargarlos como strings).
La idea bsica es que en lugar de tener que modificar los parmetros individualmente,
permites al desarrollador configurar slo unas pocas opciones especficamente creadas.
Como desarrollador del bundle, analizas esa configuracin y cargas los services correctos y
parmetros dentro de una clase Extension.
Como ejemplo, imagina que estas creando un social bundle, que proporciona integracin
con Twitter y dems. Para poder reutilizar el bundle, tienes que hacer las variables client_id
y client_secret configurables. La configuracin de tu bundle sera as:
# app/config/config.yml
acme_social:
twitter:
client_id: 123
client_secret: $ecret
6
Procesando la configuracin
Una vez creada la clase Extension, cuando el desarrollador incluya la key acme_social (que
es el DI alias) en un archivo de configuracin, la configuracin se aadir a un array de
configuraciones y se pasar al mtodo load() de tu extensin (Symfony automticamente
convierte XML y YAML a un array).
Para el ejemplo de configuracin dado antes, el array que se pasa al mtodo load es as:
array(
array(
'twitter' => array(
'client_id' => 123,
'client_secret' => '$ecret',
),
),
)
Ntese que es un array de arrays, no un simple array de los valores de configuracin. Esto es
intencionado ya que permite a Symfony analizar varias fuentes de configuracin. Por
ejemplo, si acme_social aparece en otro archivo de configuracin, por ejemplo
_configdev.yml, con valores diferentes, el array sera como sigue:
array(
// valores de config.yml
array(
'twitter' => array(
'client_id' => 123,
'client_secret' => '$secret',
),
),
// valores de config_dev.yml
array(
'twitter' => array(
'client_id' => 456,
),
),
)
El orden de los dos arrays depende de cual se establece primero.
7
El componente Config de Symfony ayudar a unir estos valores, proporcionar valores por
defecto y mostrar errores de validacin en caso de configuracin incorrecta. Primero
creamos una clase Configuration en el directorio DependencyInjection y creamos un rbol
que define la estructura de la configuracin de tu bundle.
// src/Acme/SocialBundle/DependencyInjection/Configuration.php
namespace Acme\SocialBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
$rootNode
->children()
->arrayNode('twitter')
->children()
->integerNode('client_id')->end()
->scalarNode('client_secret')->end()
->end()
->end() // twitter
->end()
;
return $treeBuilder;
}
}
La clase Configuration puede ser mucho ms complicada que el ejemplo anterior,
soportando nodos prototype, validacin avanzada, normalizacin especfica de XML y
uniones ms avanzadas. Puedes leer ms en la documentacin del componente Config, o
ver ejemplos complejos de configuracin del FrameworkBundle o del TwigBundle.
8
Configuration ahora puede emplearse en el mtodo load() para unir configuraciones y forzar
la validacin (por ejemplo, si se pasa una opcin adicional, se lanzar una excepcin):
// src/Acme/HelloBundle/DependencyInjection/AcmeHelloExtension.php
namespace Acme\HelloBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;
9
Utilizar el componente Config es totalmente opcional. El mtodo load() obtiene un array de
valores de configuracin. Puedes simplemente parsear estos arrays t mismo (por ejemplo
sobreescribiendo configuraciones y utilizando isset para comprobar la existencia de un
valor). Ten en cuenta que ser complicado que soporte XML:
Si tiene mltiples bundles que dependen unos de otros, podra ser til permitir a una clase
Extension modificar la configuracin de otra clase extension de otro bundle, como si se
pudiera definir la configuracin desde app/config/config.yml. Esto se puede conseguir
utilizando una prepend extension.
Volcado de configuracion
10
Compiler Passes
Los Compiler Passes permiten manipular otras definiciones de services que se han
registrado en el service container. Puedes ver cmo se crean en la seccin de compilacin
del container. Para registrar un compiler pass desde un bundle hay que aadirlo al mtodo
build de la clase que define el bundle:
// src/Acme/MailerBundle/AcmeMailerBundle.php
namespace Acme\MailerBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Acme\MailerBundle\DependencyInjection\Compiler\CustomCompilerPass;
$container->addCompilerPass(new CustomCompilerPass());
}
}
Uno de los usos ms comunes de los compiler passes es para los tagged services. Si utilizas
custom tags en un bundle, por convencin los nombres de los tags consisten en el nombre
del bundle (minsculas, barras bajas y separadores), seguidos de un punto, y finalmente el
nombre "real". Por ejemplo, si quieres introducir algn tipo de tag "transport" en tu
AcmeMailerBundle, se debera llamar acme_mailer.transport.
11
12