Sie sind auf Seite 1von 12

SYMFONY

La estructura basica de una aplicacion Symfony, es como la siguiente:

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.

El comando para crear un bundle es:


php app/console generate:bundle

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.

1. Crear clase de bundle:


namespace Acme\TestBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class AcmeTestBundle extends Bundle


{
}

Esta clase tiene que estar dentro del directorio raz del bundle, la clase tiene que heredar de
Bundle.

2. Registrar el Bundle

En el directorio app encontramos el archivo AppKernel.php, ahi encontraremos la funcion


registerBundles en la que tenemos que modificar el array que las contiene y agregar nuestro
nuevo bundle:

public function registerBundles()


{
$bundles = array(
// ...
// Registramos el bundle
new Acme\TestBundle\AcmeTestBundle(),
);
// ...
return $bundles;
}

2
De esta manera estamos avisando a symfony que existe un nuevo bundle, y que
necesitamos que lo empiece a utilizar.

Herencia y reutilizacin

Un bundle puede extender a otro, de esta manera se puede sobre-escribir controladores,


templates o cualquier otro archivo definido en el padre.

Si sigues estas convenciones, puedes usar la herencia de bundles para sobreescribir


archivos, controladores o plantillas. Si por ejemplo creamos un nuevo bundle NuevoBundle
y especificamos que sobreescribe a AppBundle, cuando Symfony inicie el controlador
AppBundle:Default:index, buscar primero la clase DefaultController en el NuevoBundle, y si
no existe, lo buscar en AppBundle. Un bundle puede extender casi cualquier otra parte de
otro bundle.

Configuracion de bundles

La configuracin de bundles incluye muchos aspectos a tener en cuenta, vamos a empezar


por la configuracin ms bsica para poder ir entendiendo y avanzando a los aspectos mas
potentes de symfony para utilizar la configuracin.

Normalmente la configuracin de nuestra aplicacion se encuentra dentro del directorio


app/config/, ahi encontraremos varios archivos .yml que nos permitiran configurar los
aspectos mas basicos de la aplicacion.
Por defecto estos archivos ya traen una configuracin base, por lo que no es necesario
modificarlos, excepto que necesitemos alguna funcionalidad no contemplada por lo basico.
Lo normal es utilizar archivos tipo YAML, si bien symfony puede manejar varios tipos de
archivos, este es el mas comun.

Los archivos de configuracin basicos son:


config.yml, este archvico contiene la configuracion basica de la aplicacion, asi como
del framework.
parameters.yml, aqui encontramos los parametros que necesitamos que la
aplicacion conozca.
routing.yml este archivo contiene todas las rutas y referencia de ruteo de la
aplicacion.
security.yml todo lo relacionado a la seguridad de la aplicacion.
services.yml los servicios por defecto de la aplicacion.
Tambien tenemos varios archivos con el sufijo _dev, _prod, _test, estos archivos son
especificos para el entorno en el que se encuentre la aplicacion.

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

Es mejor utilizar parmetros para configurar tu bundle, aunque si no tienes planes de


compartir tu bundle con otros proyectos, no tiene mucho sentido utilizar esta forma de
configuracin ms avanzada. Si utilizas el bundle slo en un proyecto, puedes simplemente
cambiar la configuracin del service cada vez.

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:

Tiene que estar en el namespace DependencyInjection del bundle.


El nombre es igual al nombre del bundle con el sufijo Bundle reemplazado por Extension
(por ejemplo la clase Extension del bundle AppBundle sera AppExtension y la clase para
AcmeHelloBundle sera AcmeHelloExtension).
La clase Extension debera implementar la ExtensionInterface, pero normalmente slo
tendrs que extender la clase Extension:

// src/AppBundle/DependencyInjection/AppExtension.php
namespace AppBundle\DependencyInjection;

use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class AppExtension extends Extension


{
public function load(array $configs, ContainerBuilder $container)
{
// Cargars los archivos aqu despus
}
}

4
Registrar manualmente una clase Extension

Cuando no quieras seguir las convenciones, tendras que registrar manualmente tu


extension. Para hacerlo, deberas sobreescribir el mtodo Bundle::getContainerExtension()
para devolver la instancia de la extensin:

// ...
use AppBundle\DependencyInjection\UnconventionalExtensionClass;

class AppBundle extends Bundle


{
public function getContainerExtension()
{
return new UnconventionalExtensionClass();
}
}
Ya que la nueva clase Extension no sigue las convenciones de nombres, deberas tambin
sobreescribir Extension::getAlias() para devolver el correcto alias DI. El alias DI es el nombre
utilizado para referirse al bundle en el container (por ejemplo en el archivo
app/config/config.yml). Por defecto esto se hace removiendo el sufijo Extension y
convirtiendo el nombre de clase a barras bajas (por ejemplo el alias ID de
AcmeHelloExtension es acme_hello).

El metodo load

Con el mtodo load(), todos la configuracion y parmetros relacionados a esta extensin se


cargarn. Este mtodo no obtiene la instancia real del container, sino una copia. Este
container slo tiene los parmetros del container real. Despus de cargar los services y
parmetros, la copia se unir al container real para asegurar que todos los services y
parmetros tambin se aaden al container real.

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).

Utilizar la extensin Bundle

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

Si un bundle proporciona una clase Extension, generalmente no deberas sobreescribir los


parmetros del service container de ese bundle. La idea es que si hay una clase Extension,
cada ajuste que se tenga que configurar debera estar presente en la configuracin
disponible proporcionada por esa clase. En otras palabras, la clase extension define todos
los ajustes de configuracin pblicos para mantener la compatibilidad de versiones.

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;

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;
}
}
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):

public function load(array $configs, ContainerBuilder $container)


{
$configuration = new Configuration();

$config = $this->processConfiguration($configuration, $configs);


// ...
}
El mtodo processConfiguration() utiliza el rbol de configuracin que hemos definido en la
clase Configuration para validar, normalizar y unir todos los arrays de configuracin juntos.

En lugar de llamar a processConfiguration() en tu extensin cada vez que proporcionas


algunas opciones de configuracin, puedes extender ConfigurableExtension para que se
haga de forma automtica:

// 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


{
// ntese que este mtodo se llama loadInternal y no load
protected function loadInternal(array $mergedConfig, ContainerBuilder $container)
{
// ...
}
}
Esta clase utiliza el mtodo getConfiguration() para obtener la instancia Configuration.
Deberas sobreescribirlo si tu clase de configuracin no se llama Configuration o no est en
el mismo namespace que la extensin.

Procesar a mano la configuracion

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:

public function load(array $configs, ContainerBuilder $container)


{
$config = array();
// dejar que los resources sobreescriban el set de valores previo
foreach ($configs as $subConfig) {
$config = array_merge($config, $subConfig);
}

// ... ahora utiliza la etiqueta $config array


}

Modificar la configuracin de otro bundle

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

El comando config:dump-reference vuelca la configuracin por defecto de un bundle en la


consola utilizando el formato Yaml.

Siempre que la configuracin de tu bundle est localizada en la localizacin estndar


(TuBundle\DependencyInjectio\Configuration) y no requiere que se pasen argumentos al
constructor, funcionar automticamente. Si tienes algo diferente, tu clase Extension debe
sobreescribir al mtodo Extension::getConfiguration() y devolver una instancia de tu
Configuration.

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;

class AcmeMailerBundle extends Bundle


{
public function build(ContainerBuilder $container)
{
parent::build($container);

$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

Das könnte Ihnen auch gefallen