Diferència entre revisions de la pàgina «NF2 - Framework PHP (15h)»

De wikiserver
Dreceres ràpides: navegació, cerca
(Creant l'aplicació)
Línia 347: Línia 347:
  
 
Ara que ja està configurat el bundle, pots començar a construir la teva aplicació dins del bundle.
 
Ara que ja està configurat el bundle, pots començar a construir la teva aplicació dins del bundle.
==Creant l'aplicació==
+
==Exemple per crear l'aplicació==
 
*'''Pas 1: Creant la ruta'''
 
*'''Pas 1: Creant la ruta'''
 
Per defecte, l'arxiu de configuració d'encaminament en una aplicació Symfony2 es troba en '''app/config/routing.yml'''. Si ho prefereixes, i igual que en la resta de la configuració en Symfony2, pots utilitzar el format XML o PHP per configurar les teves rutes.
 
Per defecte, l'arxiu de configuració d'encaminament en una aplicació Symfony2 es troba en '''app/config/routing.yml'''. Si ho prefereixes, i igual que en la resta de la configuració en Symfony2, pots utilitzar el format XML o PHP per configurar les teves rutes.

Revisió del 09:47, 16 gen 2015

Introducció a Symfony

Symfony.jpg


Un framework simplifica el desenvolupament de les aplicacions, ja que automatitza molts dels patrons utilitzats per resoldre les tasques comunes. A més, un framework proporciona estructura al codi font, forçant al desenvolupador a crear codi més llegible i més fàcil de mantenir. Finalment, un framework facilita la programació d'aplicacions, ja que encapsula operacions complexes en instruccions senzilles.

Symfony és un complet framework dissenyat per optimitzar, gràcies a les seves característiques, el desenvolupament de les aplicacions web. Per començar, separa la lògica de negoci, la lògica de servidor i la presentació de l'aplicació web. Proporciona diverses eines i classes encaminades a reduir el temps de desenvolupament d'una aplicació web complexa. A més, automatitza les tasques més comunes, permetent al desenvolupador dedicar-se per complet als aspectes específics de cada aplicació. El resultat de tots aquests avantatges és que no s'ha de reinventar la roda cada vegada que es crea una nova aplicació web.

Symfony està desenvolupat completament amb PHP i ha estat provat amb èxit en llocs com Yahoo! Answers, delicious, DailyMotion i molts altres llocs web de primer nivell. Symfony és compatible amb la majoria de gestors de bases de dades, com MySQL, PostgreSQL, Oracle i SQL Server de Microsoft. Es pot executar tant en plataformes Unix (Unix, Linux, etc.) com en plataformes Windows. A continuació es mostren algunes de les seves característiques.

 

 

Característiques

Symfony es va dissenyar perquè s'ajustés als següents requisits:

  • Fàcil d'instal·lar i configurar en la majoria de plataformes (i amb la garantia que funciona correctament en els sistemes Windows i *nix estàndards)
  • Independent del sistema gestor de bases de dades
  • Senzill d'usar en la majoria de casos, però prou flexible com per adaptar-se als casos més complexos
  • Basat en la premissa de "convenir en comptes de configurar", en la qual el desenvolupador solament ha de configurar allò que no és convencional
  • Segueix la majoria de millors pràctiques i patrons de disseny per a la web
  • Preparat per a aplicacions empresarials i adaptable a les polítiques i arquitectures pròpies de cada empresa, a més de ser prou estable com per desenvolupar aplicacions a llarg termini
  • Codi fàcil de llegir que inclou comentaris de phpDocumentor i que permet un manteniment molt senzill
  • Fàcil d'estendre, la qual cosa permet la seva integració amb llibreries desenvolupades per tercers

Symfony pot ser completament personalitzat per complir amb els requisits de les empreses que disposen de les seves pròpies polítiques i regles per a la gestió de projectes i la programació d'aplicacions. Per defecte incorpora diversos entorns de desenvolupament diferents i inclou diverses eines que permeten automatitzar les tasques més comunes de l'enginyeria del programari:

Les eines que generen automàticament codi han estat dissenyades per fer prototips d'aplicacions i per crear fàcilment la part de gestió de les aplicacions.

  • El framework de desenvolupament de proves unitàries i funcionals proporciona les eines ideals per al desenvolupament basat en proves "test-driven development").
  • La barra de depuració web simplifica la depuració de les aplicacions, ja que mostra tota la informació que els programadors necessiten sobre la pàgina en la qual estan treballant.
  • La interfície de línia de comandos automatitza la instal·lació de les aplicacions entre servidors.
  • És possible realitzar canvis "en calent" de la configuració (sense necessitat de reiniciar el servidor).
  • El complet sistema de log permet als administradors accedir fins a l'últim detall de les activitats que realitza l'aplicació.

Desenvolupament ràpid d'aplicacions (RAD)

Durant molt temps, la programació d'aplicacions web va ser un tasca tediosa i molt lenta. Seguint els cicles habituals de l'enginyeria del programari (com els proposats pel Procés Racional Unificat o Rational Unified Process) el desenvolupament d'una aplicació web no pot començar fins que s'han establert per escrit una sèrie de requisits, s'han creat els diagrames UML Unified Modeling Language) i s'ha produït abundant documentació sobre el projecte. Aquest model es veia afavorit per la baixa velocitat de desenvolupament, la falta de versatilitat dels llenguatges de programació (abans d'executar el programa s'ha de construir, compilar i reiniciar) i sobretot pel fet que els clients no estaven disposats a adaptar-se a altres metodologies.

Avui dia, les empreses reaccionen més ràpidament i els clients canvien d'opinió constantment durant el desenvolupament dels projectes. D'aquesta manera, els equips de desenvolupament han d'adaptar-se a aquestes necessitats i han de poder canviar l'estructura d'una aplicació de forma ràpida. Afortunadament, l'ús de llenguatges de script com Python, Ruby i PHP permeten seguir altres estratègies de programació, com RAD (desenvolupament ràpid d'aplicacions) i el desenvolupament àgil de programari.

Una de les idees centrals d'aquesta metodologia és que el desenvolupament comença al més aviat possible perquè el client pugui revisar un prototip que funciona i pugui indicar el camí a seguir. A partir d'aquí, l'aplicació es desenvolupa de forma iterativa, en la qual cada nova versió incorpora noves funcionalitats i es desenvolupa en un breu espai de temps.

Les conseqüències d'aquestes metodologies per al desenvolupador són nombroses. El programador no ha de pensar sobre les versions futures en incloure una nova funcionalitat. Els mètodes utilitzats han de ser el més senzills i directes possibles. Aquestes idees es resumeixen en el principi denominat KISS: Fes-ho senzill, idiota!Keep It Simple, Stupid

Quan es modifiquen els requisits o quan s'afegeix una nova funcionalitat, normalment s'ha de reescriure part del codi existent. Aquest procés es diu refactorización i succeeix sovint durant el desenvolupament d'una aplicació web. El codi sol moure's a altres llocs en funció de la seva naturalesa. Els blocs de codi repetits es refactorizan en un únic lloc, aplicant el principi DRY: No et repeteixis Don't Repeat Yourself.

Per assegurar que l'aplicació segueix funcionant correctament malgrat els canvis constants, es necessita una sèrie de proves unitàries que puguin ser automatitzades. Si estan ben escrites, les proves unitàries permeten assegurar que gens ha deixat de funcionar després d'haver-hi refactorizado part del codi de l'aplicació. Algunes metodologies de desenvolupament d'aplicacions obliguen a escriure les proves abans que el propi codi, la qual cosa es coneix com TDD: desenvolupament basat en proves test-driven development.

Symfony és l'eina ideal pel RAD. De fet, el framework ha estat desenvolupat per una empresa que aplica el RAD als seus propis projectes. Per aquest motiu, aprendre a utilitzar Symfony no és com aprendre un nou llenguatge de programació, sinó que consite a aprendre a prendre les decisions correctes per desenvolupar les aplicacions de forma més efectiva.

La implementació del MVC que realitza Symfony

  • La capa del Modelo
    • Abstracció de la base de dades
    • Accés a les dades
  • La capa de la Vista
    • Vista
    • Plantilla
    • Layout
  • La capa del Controlador
    • Controlador frontal
    • Acció

En total són set scripts, la qual cosa semblen molts arxius per obrir i modificar cada vegada que es crea una pàgina. Afortunadament, Symfony simplifica aquest procés. Symfony pren el millor de l'arquitectura MVC i la implementa de manera que el desenvolupament d'aplicacions sigui ràpid i senzill.

En primer lloc, el controlador frontal i el layout són comuns per a totes les accions de l'aplicació. Es poden tenir diversos controladors i diversos layouts, però solament és obligatori tenir un de cada. El controlador frontal és un component que només té codi relatiu al MVC, per la qual cosa no és necessari crear un, ja que Symfony ho genera de forma automàtica.

L'altra bona notícia és que les classes de la capa del model també es generen automàticament, en funció de l'estructura de dades de l'aplicació. El ORM s'encarrega de crear l'esquelet o estructura bàsica de les classes i genera automàticament tot el codi necessari. Quan el ORM troba restriccions de claus foranes (o externes) o quan troba dades de tipus data, crea mètodes especials per accedir i modificar aquestes dades, per la qual cosa la manipulació de dades es converteix en un joc de nens. L'abstracció de la base de dades és completament transparent per al programador, ja que es realitza de forma nativa mitjançant PDO PHP Data Objects). Així, si es canvia el sistema gestor de bases de dades a qualsevol moment, no s'ha de reescriure ni una línia de codi, ja que tan sols és necessari modificar un paràmetre en un arxiu de configuració.

Finalment, la lògica de la vista es pot transformar en un arxiu de configuració senzill, sense necessitat de programar-la.

Mvc-symfony.png


Instal·lació de Symfony

Utilitzarem la versió de symfony 2.4.

Creació i configuració de l'entorn de treball

1. Crea un directori pel teu projecte symfony. (mkdir el_meu_projecte) 2. Baixa't el programa composer que t'ajudarà a instal·lar symfony:

curl -s https://getcomposer.org/installer | php

3. Baixa't symfoni i crea el teu projecte dins el directori creat prèviament:

php composer.phar create-project symfony/framework-standard-edition /ruta/hasta/directorio-raiz-servidor-web/ 2.4.0

4. Actualitza les llibreries externes (vendors)

php composer.phar install

5. Configurar apache2 S'ha de crear un nou fitxer (virtualhost) de configuració del apache2. El podeu anomenar symfony.conf i ha d'estar ubicat a /etc/apache2/sites-available El contingut del fitxer ha de ser semblant a aquest:

<VirtualHost *:80>
    ServerName      mi-sitio.com
    ServerAlias     www.mi-sitio.com

    SetEnv SYMFONY__DATABASE__USER     "..."
    SetEnv SYMFONY__DATABASE__PASSWORD "..."

    DocumentRoot    "/Proyectos/Symfony2/mi-sitio.com/web"
    DirectoryIndex  app.php

    <Directory "/Proyectos/Symfony2/mi-sitio.com/web">
        AllowOverride None
        Allow from All

        <IfModule mod_rewrite.c>
            Options -MultiViews
            RewriteEngine On
            RewriteCond %{REQUEST_FILENAME} !-f
            RewriteRule ^(.*)$ app.php [QSA,L]
        </IfModule>
    </Directory>

    CustomLog  /var/log/httpd/mi-sitio.com-access.log combined

    KeepAlive            On
    MaxKeepAliveRequests 200
    KeepAliveTimeout     5

    AddOutputFilterByType DEFLATE text/css text/plain text/html application/xhtml+xml text/xml application/xml

    <IfModule mod_headers.c>
        Header append Vary User-Agent env=!dont-vary

        ExpiresActive On
        ExpiresDefault "now plus 1 week"
        ExpiresByType image/x-icon "now plus 1 month"
        ExpiresByType image/gif    "now plus 1 month"
        ExpiresByType image/png    "now plus 1 month"
        ExpiresByType image/jpeg   "now plus 1 month"
    </IfModule>
</VirtualHost>

Una vegada tenim el fitxer executem les següents comandes:

sudo apt-get install php5-intl
sudo a2enmod headers
sudo a2enmod expires
sudo a2enmod deflate
sudo a2enmod rewrite
sudo a2ensite synfony.conf


Estructura del projecte: Aplicacions, Mòduls i Accions

Symfony considera un projecte com un conjunt de serveis i operacions disponibles sota un determinat nom de domini i que comparteixen el mateix model d'objectes.

Dins d'un projecte, les operacions s'agrupen de forma lògica en aplicacions. Normalment, una aplicació s'executa de forma independent respecte d'altres aplicacions del mateix projecte. L'habitual és que un projecte contingui dues aplicacions: una per a la part pública i una altra per a la part de gestió, compartint ambdues la mateixa base de dades. També és possible definir projectes que estiguin formats per diversos llocs web petits, cadascun d'ells considerat com una aplicació. En aquest cas, és important tenir en compte que els enllaços entre aplicacions s'han d'indicar de forma absoluta.

Cada aplicació està formada per un o més mòduls. Un mòdul normalment representa

  • a una pàgina web o
  • a un grup de pàgines amb un propòsit relacionat.

Per exemple, una aplicació podria tenir mòduls com home, articulos, ajuda, carritoCompra, compte, etc.

Els mòduls emmagatzemen les accions, que representen cadascuna de les operacions que es pot realitzar en un mòdul. Per exemple el mòdul carretCompra pot definir accions com afegir, mostrar i actualitzar. Normalment les accions es descriuen mitjançant verbs. Treballar amb accions és molt similar a treballar amb les pàgines d'una aplicació web tradicional, encara que en aquest cas dues accions diferents poden acabar mostrant la mateixa pàgina (com per exemple l'acció d'afegir un comentari a una entrada d'un blog, que acaba tornant a mostrar la pàgina de l'entrada amb el nou comentari).

Estructura de l'arbre de arxius

ormalment, tots els projectes web comparteixen el mateix tipus de continguts, com per exemple:

Una base de dades, com MySQL o PostgreSQL

  • Arxiu estàtics (HTML, imatges, arxius de Javascript, fulles d'estils, etc.)
  • Arxius pujats al lloc web per part dels usuaris o els administradors
  • Classes i llibreries PHP
  • Llibreries externes (scripts desenvolupats per tercers)
  • Arxius que s'executen per lots batch files) que normalment són scripts que s'executen via línia de comandos o mitjançant cron
  • Arxius de log (les traces que generen les aplicacions i/o el servidor)
  • Arxius de configuració

Symfony proporciona una estructura en forma d'arbre d'arxius per organitzar de forma lògica tots aquests continguts, a més de ser consistent amb l'arquitectura MVC utilitzada i amb l'agrupació projecto / aplicació / mòdul. Cada vegada que es crea un nou projecte, aplicació o mòdul, es genera de forma automàtica la part corresponent d'aquesta estructura. A més, l'estructura es pot personalitzar completament, per reorganitzar els arxius i directoris o per complir amb les exigències d'organització d'un client.

Encara que es pot canviar, per defecte totes les aplicacions Symfony tenen la mateixa estructura de directoris senzilla (i recomanada):

  • app/: conté la configuració de l'aplicació.
  • src/: aquí es troba tot el codi PHP de l'aplicació.
  • vendor/: per convenció aquí es guarden totes les llibreries creades per tercers.
  • web/: est és el directori web arrel i conté tots els arxius que es poden accedir públicament.

El directori web

El directori web arrel és el lloc on es troben tots els arxius públics i estàtics tals com a imatges, fulles d'estil i arxius Javascript. També és el lloc on es defineixen tots els controladors frontals, com per exemple el següent:

// web/app.php
require_once __DIR__.'/../app/bootstrap.php.cache';
require_once __DIR__.'/../app/AppKernel.php';
 
use Symfony\Component\HttpFoundation\Request;
 
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
$kernel->handle(Request::createFromGlobals())->send();

L'arxiu del controlador frontal (app.php en aquest exemple) és l'arxiu PHP que realment s'executa quan utilitzes una aplicació Symfony2 i el seu treball consisteix a arrencar l'aplicació utilitzant una classe del nucli (AppKernel).

Tenir un controlador frontal significa que s'utilitzen URL diferents i més flexibles que les d'una aplicació PHP típica. Quan es disposa d'un controlador frontal, les URL es formaten de la següent manera:

http://localhost/app.php/hello/Ryan

El controlador frontal, app.php, s'executa i la URL interna: /hello/Ryan es dirigeix internament segons la configuració d'encaminament.

Si a més utilitzes el mòdul mod_rewrite d'Apache, pots forçar l'execució de l'arxiu app.php sense necessitat d'incloure-ho en la URL, per la qual cosa així les URL són encara més netes:

http://localhost/hello/Ryan

El directori de l'aplicació (app)

La classe AppKernel és el punt d'entrada principal de l'aplicació i és la responsable de tota la configuració. Com a tal, s'emmagatzema en el directori app/.

Aquesta classe ha d'implementar dos mètodes que defineixen tot el que Symfony necessita saber sobre la teva aplicació. Ni tan sols has de preocupar-te d'aquests mètodes durant l'arrencada — Symfony els emplena per tu amb paràmetres predeterminats.

  • registerBundles(): retorna un array amb tots els bundles necessaris per executar l'aplicació.
  • registerContainerConfiguration(): carrega l'arxiu de configuració de recursos de l'aplicació (consulta la secció Configurant l'aplicació).

Durant el desenvolupament d'una aplicació, normalment el directori app/ solament els utilitzes per modificar la configuració i els arxius d'encaminament en el directori app/config/.

Aquest directori també conté el directori caché de l'aplicació (app/cache), un directori de logs (app/logs) i un directori per a arxius de recursos globals, tals com a plantilles (app/Resources).

Carga automàtica En arrencar Symfony, s'inclou un arxiu especial anomenat vendor/autoload.php. Aquest arxiu, creat per Composer, s'encarrega de configurar el carregador automàtic de classes, que al seu torn carrega automàticament tots els arxius de la teva aplicació que es trobin en el directori src/ i totes les llibreries externes configurades en l'arxiu composer.json.

Gràcies al carregador automàtic, mai hauràs de preocupar-te d'usar declaracions include o require. Això és possible perquè Composer utilitza namespace o espai de noms d'una classe per determinar la seva ubicació i així inclou automàticament l'arxiu en l'instant en què necessites una classe.

El carregador automàtic ja està configurat per buscar qualsevol de les teves classes PHP en el directori src/. Perquè funcioni la càrrega automàtica, el nom de la classe i la ruta de l'arxiu han de seguir el mateix patró:

Nom de la classe: Acme\HelloBundle\Controller\HelloController
Ruta física de l'arxiu: src/Acme/HelloBundle/Controller/HelloController.php

Configuració de l'aplicació

Segons el lloc web oficial de YAML (http://www.yaml.org/), YAML és "un estàndard per serializar dades en qualsevol llenguatge de programació i amb un format fàcil de llegir per part de les persones". Dit d'una altra forma, YAML és un llenguatge molt senzill que permet descriure les dades com en XML, però amb una sintaxi molt més senzilla. YAML és un format especialment útil per descriure dades que poden ser transformats en arrays simples i associatius, com per exemple:

$casa = array(
  'familia' => array(
    'apellido'  => 'García',
    'padres'  => array('Antonio', 'María'),
    'hijos'   => array('Jose', 'Manuel', 'Carmen')
  ),
  'direccion' => array(
    'numero'        => 34,
    'calle'         => 'Gran Vía',
    'ciudad'        => 'Cualquiera',
    'codigopostal'  => '12345'
  )
);

//format yml:
casa:
  familia:
    apellido: García
    padres:
      - Antonio
      - María
    hijos:
      - Jose
      - Manuel
      - Carmen
  direccion:
    numero: 34
    calle: Gran Vía
    ciudad: Cualquiera
    codigopostal: "12345"

YAML és l'acrònim de "YAML Ain't Markup Language" ("YAML No és un Llenguatge de Marcat") i es pronuncia "yamel". El format es porta utilitzant des de 2001 i existeixen utilitats per processar YAML en una gran varietat de llenguatges de programació.

YAML és molt més ràpid d'escriure que XML (ja que no fan falta les etiquetes de tancament i l'ús continu de les cometes) i és molt més poderós que els tradicionals arxius .ini (ja que aquests últims no suporten l'herència i les estructures complexes). Per aquest motiu, Symfony utilitza el format YAML com el llenguatge preferit per emmagatzemar la seva configuració.

Per saber més sobre aquest format pots consultar la següent pàgina web.

El directori font (src)

El directori src/ conté tot el codi real (codi PHP, plantilles, arxius de configuració, estils, etc.) que pertany a la teva aplicació. De fet, en programar una aplicació Symfony, la major part del teu treball es durà a terme dins d'un o més bundles creats en aquest directori.

Els Bundles

Un bundle és un concepte similar al dels plugins en altres aplicacions, però encara millor. La diferència clau és que en Symfony2 tot és un bundle, incloent tant la funcionalitat bàsica de la plataforma com el codi escrit per a la teva aplicació.

Els bundles són la part més important de Symfony2. Permeten utilitzar funcionalitats construïdes per tercers o empaquetar les teves pròpies funcionalitats per distribuir-les i reutilitzar-les en altres projectes. A més, faciliten molt l'activació o desactivació de determinades característiques dins d'una aplicació.

Un bundle simplement és un conjunt estructurat d'arxius que es troben en un directori i que implementen una sola característica. Pots crear per exemple un BlogBundle, un ForoBundle o un bundle per gestionar usuaris (molts d'ells ja existeixen com bundles de programari lliure). Cada directori conté tot el relacionat amb aquesta característica, incloent arxius PHP, plantilles, fulles d'estil, arxius Javascript, tests i qualsevol altra cosa necessària.

Les aplicacions Symfony es componen de bundles, tal com es defineix en el mètode registerBundles() de la classe AppKernel:

// app/AppKernel.php
public function registerBundles()
{
    $bundles = array(
        new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
        new Symfony\Bundle\SecurityBundle\SecurityBundle(),
        new Symfony\Bundle\TwigBundle\TwigBundle(),
        new Symfony\Bundle\MonologBundle\MonologBundle(),
        new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
        new Symfony\Bundle\DoctrineBundle\DoctrineBundle(),
        new Symfony\Bundle\AsseticBundle\AsseticBundle(),
        new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
    );
 
    if (in_array($this->getEnvironment(), array('dev', 'test'))) {
        $bundles[] = new Acme\DemoBundle\AcmeDemoBundle();
        $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
        $bundles[] = new Sensio\Bundle\DistributionBundle\SensioDistributionBundle();
        $bundles[] = new Sensio\Bundle\GeneratorBundle\SensioGeneratorBundle();
    }
 
    return $bundles;
}

Creant un bundle

L'edició estàndard de Symfony inclou un comando per crear bundles totalment funcionals d'una manera molt senzilla. Per descomptat, també pots crear els bundles a mà si ho prefereixes.

php app/console generate:bundle --namespace=NomAplicacio/NomFuncionalitatBundle --format=yml


Creació del primer bundle

Crea un bundle a la teva aplicació amb el nom Hola seguin la nomenclatura de bundles (NomAplicacio/NomFuncionalitatBundle) en format yml.

Estructura de directoris d'un bundle

L'estructura de directoris d'un bundle és simple i flexible. Per defecte el sistema de bundles segueix una sèrie de convencions que ajuden a mantenir el codi consistent entre tots els bundles Symfony2. Fa un cop d'ull a AcmeHelloBundle, ja que conté alguns dels elements més comuns d'un bundle:

  • Controller/: conté els controladors del bundle (per exemple, HelloController.php).
  • DependencyInjection/: conté elements relacionats amb el contenidor d'injecció de dependències. Entre unes altres, conté les extensions per a les classes d'injecció de dependències, la configuració que importen els serveis i registra un o més passades del compilador (aquest directori no és obligatori).
  • Resources/config/: conté la configuració, incloent la configuració de enrutamiento (per exemple, routing.yml).
  • Resources/views/: conté les plantilles organitzades segons el nom del controlador (per exemple, Hello/index.html.twig).
  • Resources/public/: conté recursos web (imatges, fulles d'estil, etc.) i és copiat o enllaçat simbòlicament al directori web/ del projecte amb el comando assets:install.
  • Tests/: té els tests unitaris i funcionals del bundle.

Configurant l'aplicació

L'aplicació està formada per una col·lecció de bundles que representen totes les característiques i capacitats de la teva aplicació. Cada bundle es pot personalitzar a través d'arxius de configuració escrits en YAML, XML o PHP. De forma predeterminada, l'arxiu de configuració principal es troba en el directori app/config/ i es diu config.yml, config.xml o config.php en funció del format que prefereixis.

# app/config/config.yml
imports:
    - { resource: parameters.yml }
    - { resource: security.yml }

framework:
    secret:          "%secret%"
    router:          { resource: "%kernel.root_dir%/config/routing.yml" }
    # ...
 
# Twig Configuration
twig:
    debug:            "%kernel.debug%"
    strict_variables: "%kernel.debug%"
 
# ...

Ara que ja està configurat el bundle, pots començar a construir la teva aplicació dins del bundle.

Exemple per crear l'aplicació

  • Pas 1: Creant la ruta

Per defecte, l'arxiu de configuració d'encaminament en una aplicació Symfony2 es troba en app/config/routing.yml. Si ho prefereixes, i igual que en la resta de la configuració en Symfony2, pots utilitzar el format XML o PHP per configurar les teves rutes.

Si et fixes en l'arxiu d'encaminament principal, veuràs que Symfony ja ha agregat una entrada en generar el bundle ProvesHolaBundle:

# app/config/routing.yml
acme_hello:
    resource: "@ProvesHolaBundle/Resources/config/routing.yml"
    prefix:   /

Aquesta directiva de configuració li diu a Symfony que carregui la configuració d'encaminament de l'arxiu Resources/config/routing.yml que es troba a l'interior del bundle ProvesHolaBundle.

En altres paraules, pots configurar les teves rutes directament en l'arxiu app/config/routing.yml o pots definir-les en diverses parts de l'aplicació i després les importes des d'aquest arxiu.

Ara que l'arxiu routing.yml del bundle s'importa des de l'arxiu d'encaminament principal de l'aplicació, afegeix la nova ruta que defineix la URL de la pàgina que ets a punt de crear:

# src/Proves/HolaBundle/Resources/config/routing.yml
hello:
    path:     /hello/{name}
    defaults: { _controller: ProvesHolaBundle:Hola:index }

La ruta es compon bàsicament de dues parts: el path, que és la URL amb la qual ha de coincidir la petició de l'usuari per activar la ruta, i un array anomenat defaults, que especifica el controlador que s'executa. Les parts de la URL tancades entre cometes indiquen que el seu valor pot variar. D'aquesta forma, {name} significa que les URL /hello/Ryan, /hello/Fabien o qualsevol altra URI similar coincidirà amb aquesta ruta. El valor de les parts variables també es passa al controlador, que pot accedir a ells a través del nom assignat en la pròpia ruta (name en aquest cas).

  • Pas 2: Creant el controlador

Quan l'usuari sol·licita la URL /hello/Ryan, s'activa la ruta hello, a la qual correspon el controlador ProvesHolaBundle:Hola:index, que és realment el codi que s'executa. El segon pas del procés de creació de pàgines consisteix precisament a crear aquest controlador.

La cadena ProvesHolaBundle:Hola:index és el nom lògic del controlador, que es tradueix com el mètode indexAction() d'una classe PHP Proves\HolaBundle\Controller\Hola. Crea en primer lloc aquest arxiu dins del teu bundle ProvesHolaBundle:

// src/Proves/HolaBundle/Controller/HolaController.php
namespace Proves\HolaBundle\Controller;
 
use Symfony\Component\HttpFoundation\Response;
 
class HolaController
{
}

En realitat, el controlador no és més que un mètode PHP que tu creguis i Symfony executa. Aquí és on el codi utilitza la informació de la petició per construir i preparar el recurs sol·licitat. Excepte en alguns casos avançats, el resultat final d'un controlador sempre és el mateix: un objecte Response de Symfony2.

Crea el mètode indexAction que Symfony executarà quan se serveixi la ruta hola:

// src/Proves/HolaBundle/Controller/HolaController.php
 
// ...
class HolaController
{
    public function indexAction($name)
    {
        return new Response('<html><body>Hola '.$name.'!</body></html>');
    }
}

El controlador és molt senzill: crea un nou objecte de tipus Response i el primer argument del qual és el contingut que s'utilitza per crear la resposta enviada a l'usuari (en aquest cas, una pàgina HTML molt simple).

Enhorabona! Després de crear solament una ruta i un controlador ja tens una pàgina completament funcional! Si tot ho has configurat correctament, l'aplicació ha de donar-te la benvinguda en accedir a la següent URL:

http://localhost/app_dev.php/hola/alex

També pots generar controladors de manera automàtica utilitzant una comanda:

php app/console generate:controller

El tercer i últim pas per crear una pàgina és opcional però gairebé totes les aplicacions ho fan: crear una plantilla.

Pas 3 opcional: Creant la plantilla

Les plantilles et permeten moure tota la part de la vista (és a dir, el codi HTML) a un arxiu separat i reutilitzar diferents parts del disseny de la pàgina. En comptes d'escriure el codi HTML dins del controlador, genera el codi HTML a partir d'una plantilla en format TWIG:

// src/Proves/HolaBundle/Controller/HolaController.php
namespace Acme\HelloBundle\Controller;
 
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 
class HolaController extends Controller
{
    public function indexAction($name)
    {
        return $this->render('ProvesHolaBundle:Hello:index.html.twig', array('name' => $name));
 
    }
}

El mètode render() crea un objecte Response i li afegeix el contingut resultant de renderizar la plantilla. Així que com qualsevol altre controlador, el codi anterior realment està retornant un objecte de tipus Response.

Tingues en compte que pots processar les plantilles de dues formes diferents. Per defecte Symfony2 admet dos llenguatges de plantilles: les clàssiques plantilles creades amb PHP i les noves i concises plantilles creades amb Twig. No t'espantis perquè pots triar lliurement quin utilitzar o fins i tot barrejar les dues en el mateix projecte.

En processar la plantilla ProvesHolaBundle:Hola:index.html.twig, el controlador utilitza la següent convenció de nomenclatura:

NombreBundle:NombreControlador:NombrePlantilla

Aquest és el nom lògic de la plantilla, que es tradueix a un arxiu físic utilitzant la següent convenció:

</ruta/a/Nombrebundle>/Resources/views/<NombreControlador>/<NombrePlantilla>

En aquest cas, ProvesHolaBundle és el nom del bundle, Hola és el controlador i index.html.twig la plantilla:

{# src/Proves/HolaBundle/Resources/views/Hola/index.html.twig #}
{% extends '::base.html.twig' %}
 
{% block body %}
    Hello {{ name }}!
{% endblock %}

Vegem la situació a través de la plantilla Twig línia per línia:

L'etiqueta extends indica que s'utilitza una plantilla pare on es defineix el disseny del lloc web. L'etiqueta block indica que tot el seu contingut s'ha de col·locar dins d'un bloc anomenat body. Com s'explicarà més endavant, la plantilla pare (base.html.twig) és la responsable de definir aquest bloc i de mostrar-ho a la pàgina HTML adequadament. La plantilla pare s'indica com ::base.html.twig, per la qual cosa no inclou ni la part del nom del bundle ni la del nom del controlador (d'aquí els dos punts dobles (::) al principi). Això significa que la plantilla no es troba dins de cap bundle, sinó en el directori app del projecte:

{# app/Resources/views/base.html.twig #}
<!DOCTYPE html>
<html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>{% block title %}Welcome!{% endblock %}</title>
    {% block stylesheets %}{% endblock %}
    <link rel="shortcut icon" href="{{ asset('favicon.ico') }}" />
    </head>
    <body>
    {% block body %}{% endblock %}
    {% block javascripts %}{% endblock %}
    </body>
</html>

Entorn de desenvolupament i entorn de producció

Una aplicació pot funcionar en diversos entorns. Els diferents entorns comparteixen el mateix codi PHP (solament és diferent el controlador frontal), però usen una configuració diferent. Per exemple, un entorn de desenvolupament dev guarda els advertiments i errors, mentre que un entorn de producció prod només registra els errors. Alguns arxius es tornen a generar en cada petició en l'entorn dev (para major comoditat dels desenvolupadors), però s'escorcollen en l'entorn prod. Tots els entorns es troben en la mateixa màquina i executen la mateixa aplicació.

Un projecte Symfony2 normalment comença amb tres entorns (dev, test i prod), encara que resulta senzill crear nous entorns. Pots veure la teva aplicació en diferents entorn amb només canviar el controlador frontalen el teu navegador. Per veure l'aplicació en l'entorn dev, accedeix a l'aplicació a través del controlador frontal de desenvolupament:

http://localhost/app_dev.php/hola

Si desitges veure com es comportarà la teva aplicació a l'entorn de producció, utilitza en el seu lloc el controlador frontal prod:

http://localhost/app.php/hola

Si fas qualsevol canvi en les plantilles, no ho veuràs en l'entorn prod tret que esborris la cache de l'aplicació i així forcis a Symfony a tornar a compilar les plantilles. Per esborrar la cache de l'entorn de producció, executa la següent comanda de consola:

sudo php app/console cache:clear --env=prod && sudo php app/console cache:warmup --env=prod
i donar-li permísos:
chmod 777 nomprojecte/ -R

El controlador

Un controlador és una funció PHP creada per tu i que s'encarrega d'obtenir la informació de la petició HTTP i de generar i retornar la resposta HTTP (en forma d'objecte de tipus Response de Symfony2). La resposta pot ser:

  • una pàgina HTML,
  • un document XML,
  • un array JSON serializado,
  • una imatge,
  • una redirecció a una altra pàgina,
  • un error de tipus 404
  • o qualsevol altra cosa que se t'ocorri.

El controlador conté tota la lògica que la teva aplicació necessita per generar el contingut de la pàgina. L'objectiu d'un controlador sempre és el mateix: crear i retornar un objecte Response.

Cicle de vida d'una petició

  • 1.Cada petició és manejada per un únic arxivo controlador frontal (per exemple, app.php o app_dev.php) el qual és responsable d'iniciar l'aplicació.
  • 2. El sistema d'encaminament (classe Routing) llegeix la informació de la petició (per exemple, la URI), troba una ruta que coincideixi amb aquesta informació, i llegeix el paràmetre _controller de la ruta.
  • 3. S'executa el controlador assignat a la ruta i aquest controlador crea i retorna un objecte Response.
  • 4. Les capçaleres HTTP i el contingut de l'objecte Response s'envien de tornada al client.

Exemple de controlador:

// src/Acme/HelloBundle/Controller/HelloController.php
 
namespace Acme\HelloBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
 
class HelloController
{
    public function indexAction()
    {
      return new Response('<html><body>Hello world!</body></html>');
    }
}

Associant una URI a un controlador

El nou controlador retorna una pàgina HTML simple. Per poder provar realment aquesta pàgina en el teu navegador, has de crear una ruta que el seu path sigui la URI que vols associar al controlador al fitxer routing.yml:

hello:
    path:         /hello
    defaults:     { _controller: AcmeHelloBundle:Hello:index }

Observa la sintaxi utilitzada per referir-se al controlador: AcmeHelloBundle:Hello:index. Symfony2 utilitza aquesta notació curta per referir-se als controladors. Es tracta de la sintaxi recomanada i li diu a Symfony2 que busqui una classe controlador anomenada HelloController dins d'un paquet anomenat AcmeHelloBundle i que després executi el mètode indexAction().

Passar arguments al mètode del controlador Exemple de controlador amb un argument en un dels seus mètodes:

<?php
// src/Acme/HelloBundle/Controller/HelloController.php
 
namespace Acme\HelloBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 
class HelloController extends Controller
{
    public function indexAction($name)
    {
      // ...
    }
}

El controlador anterior té un sol argument, anomenat $name, el valor del qual correspon al paràmetre {name} de la ruta associada. De fet, quan executes el teu controlador, Symfony2 associa cada argument del controlador amb un paràmetre de la ruta. L'arxiu d'enrutament hauria de ser aquest:

hello:
    path:         /hello
    defaults:     { _controller: AcmeHelloBundle:Hello:index }


Considera el següent exemple:

# app/config/routing.yml
hello:
    path:         /hello/{firstName}/{lastName}
    defaults:     { _controller: AcmeHelloBundle:Hello:index, color: green }
public function indexAction($firstName, $lastName, $color)
{
    // ...
}

Les variables {firstName} i {lastName} de la ruta es diuen placeholders, ja que "guarden el lloc" perquè qualsevol valor substitueixi aquesta variable. D'altra banda, la variable color és una variable de tipus default, ja que el seu valor sempre està definit per a totes les rutes. Existeixen regles amb els arguments (paràmetres):

  • Cada argument obligatori del controlador ha de tenir associat un paràmetre en la ruta
  • No tots els paràmetres de la ruta han de ser arguments en el teu controlador
  • és perfectament vàlid fer que l'argument sigui opcional.

El següent exemple no llançarà una excepció:

public function indexAction($firstName, $lastName, $color, $foo = 'bar')
{
    // ...
}

objecte Request com a argument del controlador

Sol ser molt útil disposar en el controlador de l'objecte Request associat a la petició de l'usuari, especialment quan treballes amb formularis. Per fer que Symfony passi aquest objecte automàticament com a argument del controlador, utilitza el següent codi:

use Symfony\Component\HttpFoundation\Request;
 
public function updateAction(Request $request)
{
    $form = $this->createForm(...);
 
    $form->handleRequest($request);
 
    // ...
}

Generador de controladors

Si el que volem és generar un nou controlador a la nostra aplicació podem automatitzar el procés utilitzant la següent comanda:

php app/console generate:controller

Aquesta comanda et demanarà tota la informació necessaria per crear el controlador i els actions (mètodes) necessaris que podràs utilitzar en el fitxer de rutes. Tant si utilitzes la comanda com si no la utilitzes, sempre podràs canviar la classe generada com tu prefereixis.

Encaminament

Una ruta és una associació entre un patró d'URL i un controlador. Suposem per exemple que desitges associar URL de tipus /blog/el meu-post o /blog/tot-sobre-symfony amb un controlador que sigui capaç de buscar i mostrar l'article sol·licitat.

# app/config/routing.yml
blog_show:
    path:      /blog/{slug}
    defaults:  { _controller: AcmeBlogBundle:Blog:show }

Codi PHP del controlador associat a aquesta ruta:

// src/Acme/BlogBundle/Controller/BlogController.php
 
namespace Acme\BlogBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 
class BlogController extends Controller
{
    public function showAction($slug)
    {
        $blog = // usa la variable $slug para consultar la base de datos
 
        return $this->render('AcmeBlogBundle:Blog:show.html.twig', array(
            'blog' => $blog,
        ));
    }
}

Aquest és l'objectiu del encaminador de Symfony2: associar la URL d'una petició a un controlador

Funcionament

L'objectiu del sistema d'encaminament de Symfony2 és analitzar aquesta URL i determinar què controlador s'ha d'executar. El procés complet consta dels següents passos:

  • La petició es processa en el controlador frontal de Symfony2 (per exemple, en l'arxiu app.php).
  • El nucli de Symfony2 (conegut com kernel) sol·licita al enrutador que examini la petició.
  • El enrutador busca què patró de les rutes de l'aplicació coincideix amb la URL entrant i retorna informació sobre la ruta, incloent el controlador que s'ha d'executar.
  • El nucli de Symfony2 executa el controlador, que en última instància, retorna un objecte Response.

Funcionament-routing.png

Prefix a les rutes

Resulta habitual haver d'afegir un prefix a totes les rutes importades des d'un arxiu extern. Si vols per exemple que el patró de la ruta acme_hello sigui /admin/hello/{name} en comptes de /hello/{name}, afegeix l'opció prefix en importar les rutes:

# app/config/routing.yml
acme_hello:
    resource: "@AcmeHelloBundle/Resources/config/routing.yml"
    prefix:   /admin

El valor indicat en l'opció prefix (en aquest cas /admin) s'afegeix per davant de tots els patrons de les rutes importades des de l'arxiu extern.

Sessions a Symfony2

Symfony2 inclou un objecte de sessió que permet emmagatzemar informació persistent sobre l'usuari, és a dir, informació que es guarda d'una petició a una altra. Per defecte Symfony2 emmagatzema la informació en una cookie usant les sessions natives de PHP.

use Symfony\Component\HttpFoundation\Request;
 
public function indexAction(Request $request)
{
    $session = $request->getSession();
 
    // guarda un atributo para reutilizarlo durante una
    // petición posterior del usuario
    $session->set('foo', 'bar');
 
    // obtener el valor de un atributo de la sesión
    $foo = $session->get('foo');
 
    // utilizar un valor por defecto si el atributo no existe
    $filters = $session->get('filters', array());
}