Symfony

download Symfony

of 708

Transcript of Symfony

Documentazione SymfonyRelease 2.0

Fabien Potencier

02 April 2012

Indice

1

Giro rapido 1.1 Giro rapido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Libro 2.1 Libro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1 1 25 25

2

3

Ricettario 271 3.1 Ricettario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 Componenti 471 4.1 I componenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471 Documenti di riferimento 513 5.1 Documenti di riferimento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513 Bundle 637 6.1 Bundle di Symfony SE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 637 Contributi 683 7.1 Contribuire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 683 701

4

5

6

7

Indice

i

ii

CAPITOLO 1

Giro rapido

Iniziare subito con il giro rapido di Symfony2:

1.1 Giro rapido1.1.1 Un quadro generaleVolete provare Symfony2 avendo a disposizione solo dieci minuti? Questa prima parte di questa guida stata scritta appositamente: spiega come partire subito con Symfony2, mostrando la struttura di un semplice progetto gi pronto. Chi ha gi usato un framework per il web si trover come a casa con Symfony2. Suggerimento: Si vuole imparare perch e quando si ha bisogno di un framework? Si legga il documento Symfony in 5 minuti (http://symfony.com/symfony-in-ve-minutes).

Scaricare Symfony2 Prima di tutto, vericare di avere almeno PHP 5.3.2 (o successivo) installato e congurato correttamente per funzionare con un server web, come Apache. Pronti? Iniziamo scaricando Symfony2 Standard Edition (http://symfony.com/download), una distribuzione di Symfony precongurata per gli usi pi comuni e che contiene anche del codice che dimostra come usare Symfony2 (con larchivio che include i venditori, si parte ancora pi velocemente). Scaricare larchivio e scompattarlo nella cartella radice del web. Si dovrebbe ora avere una cartella Symfony/, come la seguente:www/ get(name); return new Response(Hello .$name, 200, array(Content-Type => text/plain));

Nota: Symfony2 abbraccia le speciche HTTP, che sono delle regole che governano tutte le comunicazioni sul web. Si legga il capitolo Symfony2 e fondamenti di HTTP del libro per sapere di pi sullargomento e sulle sue potenzialit. Symfony2 sceglie il controllore basandosi sul valore _controller della congurazione delle rotte: AcmeDemoBundle:Welcome:index. Questa stringa il nome logico del controllore e fa riferimento al metodo indexAction della classe Acme\DemoBundle\Controller\WelcomeController:// src/Acme/DemoBundle/Controller/WelcomeController.php namespace Acme\DemoBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; class WelcomeController extends Controller { public function indexAction() { return $this->render(AcmeDemoBundle:Welcome:index.html.twig); } }

Suggerimento: Si sarebbero potuti usare i nomi completi di classe e metodi, Acme\DemoBundle\Controller\WelcomeController::indexAction, per il valore di _controller. Ma se si seguono alcune semplici convenzioni, il nome logico pi breve e consente maggiore essibilit. La classe WelcomeController estende la classe predenita Controller, che fornisce alcuni utili metodi scorciatoia, come il metodo :method:Symfony\\Bundle\\FrameworkBundle\\Controller\\Controller::render, che carica e rende un template (AcmeDemoBundle:Welcome:index.html.twig). Il valore restituito un oggetto risposta, popolato con il contenuto resto. Quindi, se ci sono nuove necessit, loggetto risposta pu essere manipolato prima di essere inviato al browser:public function indexAction() {

1.1. Giro rapido

5

Documentazione Symfony, Release 2.0

$response = $this->render(AcmeDemoBundle:Welcome:index.txt.twig); $response->headers->set(Content-Type, text/plain); return $response; }

Indipendentemente da come lo si raggiunge, lo scopo nale del proprio controllore sempre quello di restituire loggetto Response da inviare allutente. Questo oggetto Response pu essere popolato con codice HTML, rappresentare un rinvio del client o anche restituire il contenuto di unimmagine JPG, con un header Content-Type del valore image/jpg. Suggerimento: Estendere la classe base Controller facoltativo. Di fatto, un controllore pu essere una semplice funzione PHP, o anche una funzione anonima PHP. Il capitolo Il controllore del libro dice tutto sui controllori di Symfony2. Il nome del template, AcmeDemoBundle:Welcome:index.html.twig, il nome logico del template e fa riferimento al le Resources/views/Welcome/index.html.twig dentro AcmeDemoBundle (localizzato in src/Acme/DemoBundle). La sezione successiva sui bundle ne spiega lutilit. Diamo ora un altro sguardo al le di congurazione delle rotte e cerchiamo la voce _demo:# app/config/routing_dev.yml _demo: resource: "@AcmeDemoBundle/Controller/DemoController.php" type: annotation prefix: /demo

Symfony2 pu leggere e importare informazioni sulle rotte da diversi le, scritti in YAML, XML, PHP o anche inseriti in annotazioni PHP. Qui, il nome logico del le @AcmeDemoBundle/Controller/DemoController.php e si riferisce al le src/Acme/DemoBundle/Controller/DemoController.php. In questo le, le rotte sono denite come annotazioni sui metodi delle azioni:// src/Acme/DemoBundle/Controller/DemoController.php use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; class DemoController extends Controller { /** * @Route("/hello/{name}", name="_demo_hello") * @Template() */ public function helloAction($name) { return array(name => $name); } // ... }

Lannotazione @Route() denisce una nuova rotta con uno schema /hello/{name}, che esegue il metodo helloAction quando trovato. Una stringa racchiusa tra parentesi graffe, come {name}, chiamata segnaposto. Come si pu vedere, il suo valore pu essere recuperato tramite il parametro $name del metodo. Nota: Anche se le annotazioni sono sono supportate nativamente da PHP, possono essere usate in Symfony2 come mezzo conveniente per congurare i comportamenti del framework e mantenere la congurazione accanto al codice.

6

Capitolo 1. Giro rapido

Documentazione Symfony, Release 2.0

Dando unocchiata pi attenta al codice del controllore, si pu vedere che invece di rendere un template e restituire un oggetto Response come prima, esso restituisce solo un array di parametri. Lannotazione @Template() dice a Symfony di rendere il template al posto nostro, passando ogni variabili dellarray al template. Il nome del template resto segue il nome del controllore. Quindi, nel nostro esempio, viene reso il template AcmeDemoBundle:Demo:hello.html.twig (localizzato in src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig). Suggerimento: Le annotazioni @Route() e @Template() sono pi potenti dei semplici esempi mostrati in questa guida. Si pu approfondire largomento annotazioni nei controllori nella documentazione ufciale.

Template

Il controllore rende il template src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig (oppure AcmeDemoBundle:Demo:hello.html.twig, se si usa il nome logico):{# src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig #} {% extends "AcmeDemoBundle::layout.html.twig" %} {% block title "Hello " ~ name %} {% block content %} Hello {{ name }}! {% endblock %}

Per impostazione predenita, Symfony2 usa Twig (http://twig.sensiolabs.org/) come sistema di template, ma si possono anche usare i tradizionali template PHP, se si preferisce. Il prossimo capitolo introdurr il modo in cui funzionano i template in in Symfony2.Bundle

Forse vi siete chiesti perch il termine bundle viene usato cos tante volte nora. Tutto il codice che si scrive per la propria applicazione organizzato in bundle. Nel linguaggio di Symfony2, un bundle un insieme strutturato di le (le PHP, fogli di stile, JavaScript, immagini, ...) che implementano una singola caratteristica (un blog, un forum, ...) e che pu essere condivisa facilmente con altri sviluppatori. Finora abbiamo manipolato un solo bundle, AcmeDemoBundle. Impareremo di pi sui bundle nellultimo capitolo di questa guida. Lavorare con gli ambienti Ora che si possiede una migliore comprensione di come funziona Symfony2, ora di dare unocchiata pi da vicino al fondo della pagina: si noter una piccola barra con il logo di Symfony2. Questa barra chiamata barra di debug del web ed il miglior amico dello sviluppatore.

1.1. Giro rapido

7

Documentazione Symfony, Release 2.0

Ma quello che si vede allinizio solo la punta delliceberg: cliccando sullo strano numero esadecimale, riveler un altro strumento di debug veramente utile di Symfony2: il prolatore.

Ovviamente, questo strumento non deve essere mostrato quando si rilascia lapplicazione su un server di produzione. Per questo motivo, si trover un altro front controller (app.php) nella cartella web/, ottimizzato per lambiente di produzione:http://localhost/Symfony/web/app.php/demo/hello/Fabien

Se si usa Apache con mod_rewrite abilitato, si pu anche omettere la parte app.php dellURL:http://localhost/Symfony/web/demo/hello/Fabien

Inne, ma non meno importante, sui server di produzione si dovrebbe far puntare la cartella radice del web alla cartella web/,per rendere linstallazione sicura e avere URL pi allettanti:

8

Capitolo 1. Giro rapido

Documentazione Symfony, Release 2.0

http://localhost/demo/hello/Fabien

Nota: Si noti che i tre URL qui forniti sono solo esempi di come un URL potrebbe apparire in produzione usando un front controller (con o senza mod_rewrite). Se li si prova effettivamente in uninstallazione base della Standard Edition di Symfony, si otterr un errore 404, perch AcmeDemoBundle abilitato solo in ambiente dev e le sue rotte importate in app/cong/routing_dev.yml. Per rendere lambiente di produzione pi veloce possibile, Symfony2 mantiene una cache sotto la cartella app/cache/. Quando si fanno delle modiche al codice o alla congurazione, occorre rimuovere a mano i le in cache. Per questo si dovrebbe sempre usare il front controller di sviluppo (app_dev.php) mentre si lavora al progetto. Diversi ambienti di una stessa applicazione differiscono solo nella loro congurazione. In effetti, una congurazione pu ereditare da unaltra:# app/config/config_dev.yml imports: - { resource: config.yml } web_profiler: toolbar: true intercept_redirects: false

Lambiente dev (che carica il le di congurazione config_dev.yml) importa il le globale config.yml e lo modica, in questo caso, abilitando la barra di debug del web. Considerazioni nali Congratulazioni! Avete avuto il vostro primo assaggio di codice di Symfony2. Non era cos difcile, vero? C ancora molto da esplorare, ma dovreste gi vedere come Symfony2 rende veramente facile implementare siti web in modo migliore e pi veloce. Se siete ansiosi di saperne di pi, andate alla prossima sezione: la vista.

1.1.2 La vistaDopo aver letto la prima parte di questa guida, avete deciso che Symfony2 vale altri dieci minuti. Bene! In questa seconda parte, si imparer di pi sul sistema dei template di Symfony2, Twig (http://twig.sensiolabs.org/). Twig un sistema di template veloce, essibile e sicuro per PHP. Rende i propri template pi leggibili e concisi e anche pi amichevoli per i designer. Nota: Invece di Twig, si pu anche usare PHP per i proprio template. Entrambi i sistemi di template sono supportati da Symfony2.

Familiarizzare con Twig

Suggerimento: Se si vuole imparare Twig, suggeriamo caldamente di leggere la sua documentazione (http://twig.sensiolabs.org/documentation) ufciale. Questa sezione solo un rapido sguardo ai concetti principali. Un template Twig un le di test che pu generare ogni tipo di contenuto (HTML, XML, CSV, LaTeX, ...). Twig denisce due tipi di delimitatori:

1.1. Giro rapido

9

Documentazione Symfony, Release 2.0

{{ ... {% ... esempio.

}}: Stampa una variabile o il risultato di unespressione; %}: Controlla la logica del template; usato per eseguire dei cicli for e delle istruzioni if, per

Segue un template minimale, che illustra alcune caratteristiche di base, usando due variabili, page_title e navigation, che dovrebbero essere passate al template: La mia pagina web {{ page_title }}

  • {% for item in navigation %}
  • {{ item.caption }}

{% endfor %}

Suggerimento: Si possono inserire commenti nei template, usando i delimitatori {# ...

#}.

Per rendere un template in Symfony, usare il metodo render dal controllore e passargli qualsiasi variabile necessaria al template:$this->render(AcmeDemoBundle:Demo:hello.html.twig, array( name => $name, ));

Le variabili passate a un template possono essere stringhe, array o anche oggetti. Twig astrae le differenze tra essi e consente di accedere agli attributi di una variabie con la notazione del punto (.):{# array(name => Fabien) #} {{ name }} {# array(user => array(name => Fabien)) #} {{ user.name }} {# forza la ricerca nellarray #} {{ user[name] }} {# array(user => new User(Fabien)) #} {{ user.name }} {{ user.getName }} {# forza la ricerca del nome del metodo #} {{ user.name() }} {{ user.getName() }} {# passa parametri a un metodo #} {{ user.date(Y-m-d) }}

Nota: importante sapere che le parentesi graffe non sono parte della variabile, ma istruzioni di stampa. Se si accede alle variabili dentro ai tag, non inserire le parentesi graffe. 10 Capitolo 1. Giro rapido

Documentazione Symfony, Release 2.0

Decorare i template Molto spesso, i template in un progetto condividono alcuni elementi comuni, come i ben noti header e footer. In Symfony2, il problema affrontato in modo diverso: un template pu essere decorato da un altro template. Funziona esattamente come nelle classi di PHP: lereditariet dei template consente di costruire un template di base layout, che contiene tutti gli elementi comuni del proprio sito e denisce dei blocchi, che i template gli possono sovrascrivere. Il template hello.html.twig eredita da layout.html.twig, grazie al tag extends:{# src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig #} {% extends "AcmeDemoBundle::layout.html.twig" %} {% block title "Hello " ~ name %} {% block content %} Hello {{ name }}! {% endblock %}

La notazione AcmeDemoBundle::layout.html.twig suona familiare, non vero? la stessa notazione usata per riferirsi a un template. La parte :: vuol dire semplicemente che lelemento controllore vuoto, quindi il le corrispondente si trova direttamente sotto la cartella Resources/views/. Diamo ora unocchiata a una versione semplicata di layout.html.twig:{# src/Acme/DemoBundle/Resources/views/layout.html.twig #} {% block content %} {% endblock %}

I tag {% block %} deniscono blocchi che i template gli possono riempire. Tutto ci che fa un tag di blocco dire al sistema di template che un template glio pu sovrascrivere quelle porzioni di template. In questo esempio, il template hello.html.twig sovrascrive il blocco content, quindi il testo Hello Fabien viene reso allinterno dellelemento div.symfony-content. Usare tag, ltri e funzioni Una delle migliori caratteristiche di Twig la sua estensibilit tramite tag, ltri e funzioni. Symfony2 ha dei bundle con molti di questi, per facilitare il lavoro dei designer. Includere altri template Il modo migliore per condividere una parte di codice di un template quello di denire un template che possa essere incluso in altri template. Creare un template embedded.html.twig:{# src/Acme/DemoBundle/Resources/views/Demo/embedded.html.twig #} Hello {{ name }}

E cambiare il template index.html.twig per includerlo:

1.1. Giro rapido

11

Documentazione Symfony, Release 2.0

{# src/Acme/DemoBundle/Resources/views/Demo/hello.html.twig #} {% extends "AcmeDemoBundle::layout.html.twig" %} {# override the body block from embedded.html.twig #} {% block content %} {% include "AcmeDemoBundle:Demo:embedded.html.twig" %} {% endblock %}

Inserire altri controllori Cosa fare se si vuole inserire il risultato di un altro controllore in un template? Pu essere molto utile quando si lavora con Ajax o quando il template incluso necessita di alcune variabili, non disponibili nel template principale. Se si crea unazione fancy e la si vuole includere nel template index, basta usare il tag render:{# src/Acme/DemoBundle/Resources/views/Demo/index.html.twig #} {% render "AcmeDemoBundle:Demo:fancy" with { name: name, color: verde } %}

Qui la stringa AcmeDemoBundle:Demo:fancy si riferisce allazione fancy del controllore Demo. I parametri (name e color) si comportano come variabili di richiesta simulate (come se fancyAction stesse gestendo una richiesta del tutto nuova) e sono rese disponibili al controllore:// src/Acme/DemoBundle/Controller/DemoController.php class DemoController extends Controller { public function fancyAction($name, $color) { // creare un oggetto, in base alla variabile $color $object = ...;

return $this->render(AcmeDemoBundle:Demo:fancy.html.twig, array(name => $name, object = } // ... }

Creare collegamenti tra le pagine

Parlando di applicazioni web, i collegamenti tra pagine sono una parte essenziale. Invece di inserire a mano gli URL nei template, la funzione path sa come generare URL in base alla congurazione delle rotte. In questo modo, tutti gli URL saranno facilmente aggiornati al cambiare della congurazione:Ciao Thomas!

La funzione path() accetta come parametri un nome di rotta e un array di parametri. Il nome della rotta la chiave principale sotto cui le rotte sono elencate e i parametri sono i valori dei segnaposto deniti nello schema della rotta:// src/Acme/DemoBundle/Controller/DemoController.php use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; /** * @Route("/hello/{name}", name="_demo_hello") * @Template() */

12

Capitolo 1. Giro rapido

Documentazione Symfony, Release 2.0

public function helloAction($name) { return array(name => $name); }

Suggerimento: La funzione url genera URL assoluti: Thomas }) }}.

{{ url(_demo_hello, { name:

Includere risorse: immagini, JavaScript e fogli di stile

Cosa sarebbe Internet senza immagini, JavaScript e fogli di stile? Symfony2 fornisce la funzione asset per gestirli facilmente.

Lo scopo principale della funzione asset quello di rendere le applicazioni maggiormente portabili. Grazie a questa funzione, si pu spostare la cartella radice dellapplicazione ovunque, sotto la propria cartella radice del web, senza cambiare nulla nel codice dei template. Escape delle variabili Twig congurato in modo predenito per lescape automatico di ogni output. Si legga la documentazione (http://twig.sensiolabs.org/documentation) di Twig per sapere di pi sullescape delloutput e sullestensione Escaper. Considerazioni nali Twig semplice ma potente. Grazie a layout, blocchi, template e inclusioni di azioni, molto facile organizzare i propri template in un modo logico ed estensibile. Tuttavia, chi non si trova a proprio agio con Twig pu sempre usare i template PHP in Symfony, senza problemi. Stiamo lavorando con Symfony2 da soli venti minuti e gi siamo in grado di fare cose incredibili. Questo il potere di Symfony2. Imparare le basi facile e si imparer presto che questa facilit nascosta sotto unarchitettura molto essibile. Ma non corriamo troppo. Prima occorre imparare di pi sul controllore e questo esattamente largomento della prossima parte di questa guida. Pronti per altri dieci minuti di Symfony2?

1.1.3 Il controlloreAncora qui, dopo le prime due parti? State diventano dei Symfony2-dipendenti! Senza ulteriori indugi, scopriamo cosa sono in grado di fare i controllori. Usare i formati Oggigiorno, unapplicazione web dovrebbe essere in grado di servire pi che semplici pagine HTML. Da XML per i feed RSS o per web service, a JSON per le richieste Ajax, ci sono molti formati diversi tra cui scegliere. Il supporto di tali formati in Symfony2 semplice. Modicare il le routing.yml e aggiungere un formato _format, con valore xml:

1.1. Giro rapido

13

Documentazione Symfony, Release 2.0

// src/Acme/DemoBundle/Controller/DemoController.php use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; /** * @Route("/hello/{name}", defaults={"_format"="xml"}, name="_demo_hello") * @Template() */ public function helloAction($name) { return array(name => $name); }

Usando il formato di richiesta (come denito nel valore _format), Symfony2 sceglie automaticamente il template giusto, in questo caso hello.xml.twig: {{ name }}

tutto. Per i formati standard, Symfony2 sceglier anche lheader Content-Type migliore per la risposta. Se si vogliono supportare diversi formati per una singola azione, usare invece il segnaposto {_format} nello schema della rotta:// src/Acme/DemoBundle/Controller/DemoController.php use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

/** * @Route("/hello/{name}.{_format}", defaults={"_format"="html"}, requirements={"_format"="html|xml|j * @Template() */ public function helloAction($name) { return array(name => $name); }

Ora il controller sar richiamato per URL come /demo/hello/Fabien.xml o /demo/hello/Fabien.json. La voce requirements denisce delle espressioni regolari che i segnaposto devono soddisfare. In questo esempio, se si prova a richiedere la risorsa /demo/hello/Fabien.js, si otterr un errore 404, poich essa non corrisponde al requisito di _format. Rinvii e rimandi Se si vuole rinviare lutente a unaltra pagina, usare il metodo redirect():return $this->redirect($this->generateUrl(_demo_hello, array(name => Lucas)));

Il metodo generateUrl() lo stesso della funzione path() che abbiamo usato nei template. Accetta come parametri il nome della rotta e un array di parametri e restituisce lURL amichevole associato. Si pu anche facilmente rimandare lazione a unaltra, col metodo forward(). Internamente, Symfony effettua una sotto-richiesta e restituisce un oggetto Response da tale sotto-richiesta:

$response = $this->forward(AcmeDemoBundle:Hello:fancy, array(name => $name, color => green)); // fare qualcosa con la risposta o restituirla direttamente

14

Capitolo 1. Giro rapido

Documentazione Symfony, Release 2.0

Ottenere informazioni dalla richiesta Oltre ai valori dei segnaposto delle rotte, il controllore ha anche accesso alloggetto Request:$request = $this->getRequest(); $request->isXmlHttpRequest(); // una richiesta Ajax? $request->getPreferredLanguage(array(en, fr)); $request->query->get(page); // prende un parametro $_GET $request->request->get(page); // prende un parametro $_POST

In un template, si pu anche avere accesso alloggetto Request tramite la variabile app.request:{{ app.request.query.get(page) }} {{ app.request.parameter(page) }}

Persistere i dati nella sessione Anche se il protocollo HTTP non ha stato, Symfony2 fornisce un belloggetto sessione, che rappresenta il client (sia esso una persona che usa un browser, un bot o un servizio web). Tra due richieste, Symfony2 memorizza gli attributi in un cookie, usando le sessioni native di PHP. Si possono memorizzare e recuperare informazioni dalla sessione in modo facile, da un qualsiasi controllore:$session = $this->getRequest()->getSession(); // memorizza un attributo per riusarlo pi avanti durante una richiesta utente $session->set(foo, bar); // in un altro controllore per unaltra richiesta $foo = $session->get(foo); // imposta la localizzazione dellutente $session->setLocale(fr);

Si possono anche memorizzare piccoli messaggi che saranno disponibili solo per la richiesta successiva:// memorizza un messaggio per la richiesta successiva (in un controllore) $session->setFlash(notice, Congratulazioni, azione eseguita con successo!); // mostra il messaggio nella richiesta successiva (in un template) {{ app.session.flash(notice) }}

Ci risulta utile quando occorre impostare un messaggio di successo, prima di rinviare lutente a unaltra pagina (la quale mostrer il messaggio). Proteggere le risorse La Standard Edition di Symfony possiede una semplice congurazione di sicurezza, che soddisfa i bisogni pi comuni:# app/config/security.yml security: encoders:

1.1. Giro rapido

15

Documentazione Symfony, Release 2.0

Symfony\Component\Security\Core\User\User: plaintext role_hierarchy: ROLE_ADMIN: ROLE_USER ROLE_SUPER_ADMIN: [ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] providers: in_memory: users: user: { password: userpass, roles: [ ROLE_USER ] } admin: { password: adminpass, roles: [ ROLE_ADMIN ] } firewalls: dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false login: pattern: ^/demo/secured/login$ security: false secured_area: pattern: ^/demo/secured/ form_login: check_path: /demo/secured/login_check login_path: /demo/secured/login logout: path: /demo/secured/logout target: /demo/

Questa congurazione richiede agli utenti di effettuare login per ogni URL che inizi per /demo/secured/ e denisce due utenti validi: user e admin. Inoltre, lutente admin ha il ruolo ROLE_ADMIN, che include il ruolo ROLE_USER (si veda limpostazione role_hierarchy). Suggerimento: Per leggibilit, le password sono memorizzate in chiaro in questa semplice congurazione, ma si pu usare un qualsiasi algoritmo di hash, modicando la sezione encoders. Andando allURL http://localhost/Symfony/web/app_dev.php/demo/secured/hello, si verr automaticamente rinviati al form di login, perch questa risorsa protetta da un firewall. Si pu anche forzare lazione a richiedere un dato ruolo, usando lannotazione @Secure nel controllore:use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use JMS\SecurityExtraBundle\Annotation\Secure; /** * @Route("/hello/admin/{name}", name="_demo_secured_hello_admin") * @Secure(roles="ROLE_ADMIN") * @Template() */ public function helloAdminAction($name) { return array(name => $name); }

Ora, si entri come utente user (che non ha il ruolo ROLE_ADMIN) e, dalla pagina sicura hello, si clicchi sul collegamento Hello resource secured. Symfony2 dovrebbe restituire un codice di stato HTTP 403 (forbidden), 16 Capitolo 1. Giro rapido

Documentazione Symfony, Release 2.0

indicando che lutente non autorizzato ad accedere a tale risorsa. Nota: Il livello di sicurezza di Symfony2 molto essibile e fornisce diversi provider per gli utenti (come quello per lORM Doctrine) e provider di autenticazione (come HTTP basic, HTTP digest o certicati X509). Si legga il capitolo Sicurezza del libro per maggiori informazioni su come usarli e congurarli.

Mettere in cache le risorse Non appena il proprio sito inizia a generare pi trafco, si vorr evitare di dover generare la stessa risorsa pi volte. Symfony2 usa gli header di cache HTTP per gestire la cache delle risorse. Per semplici strategie di cache, si pu usare lannotazione @Cache():use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template; use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache; /** * @Route("/hello/{name}", name="_demo_hello") * @Template() * @Cache(maxage="86400") */ public function helloAction($name) { return array(name => $name); }

In questo esempio, la risorsa sar in cache per un giorno. Ma si pu anche usare la validazione invece della scadenza o una combinazione di entrambe, se questo soddisfa meglio le proprie esigenze. La cache delle risorse gestita dal reverse proxy predenito di Symfony2. Ma poich la cache gestita usando i normali header di cache di HTTP, possibile rimpiazzare il reverse proxy predenito con Varnish o Squid e scalare facilmente la propria applicazione. Nota: E se non si volesse mettere in cache lintera pagina? Symfony2 ha una soluzione, tramite Edge Side Includes (ESI), supportate nativamente. Si possono avere maggiori informazioni nel capitolo Cache HTTP del libro.

Considerazioni nali tutto, e forse non abbiamo nemmeno speso tutti e dieci i minuti previsti. Nella prima parte abbiamo introdotto brevemente i bundle e tutte le caratteristiche apprese nora fanno parte del bundle del nucleo del framework. Ma, grazie ai bundle, ogni cosa in Symfony2 pu essere estesa o sostituita. Questo largomento della prossima parte di questa guida.

1.1.4 LarchitetturaSei il mio eroe! Chi avrebbe pensato che tu fossi ancora qui dopo le prime tre parti? I tuoi sforzi saranno presto ricompensati. Le prime tre parti non danno uno sguardo approfondito allarchitettura del framework. Poich essa rende unico Symfony2 nel panorama dei framework, vediamo in cosa consiste.

1.1. Giro rapido

17

Documentazione Symfony, Release 2.0

Capire la struttura delle cartelle La struttura delle cartelle di unapplicazione Symfony2 alquanto essibile, ma la struttura delle cartelle della distribuzione Standard Edition riette la struttura tipica e raccomandata di unapplicazione Symfony2: app/: La congurazione dellapplicazione; src/: Il codice PHP del progetto; vendor/: Le dipendenze di terze parti; web/: La cartella radice del web.La cartella web/

La cartella radice del web la casa di tutti i le pubblici e statici, come immagini, fogli di stile, le JavaScript. anche il posto in cui stanno i front controller:// 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();

Il kernel inizialmente richiede il le bootstrap.php.cache, che lancia lapplicazione e registra lautoloader (vedi sotto). Come ogni front controller, app.php usa una classe Kernel, AppKernel, per inizializzare lapplicazione.La cartella app/

La classe AppKernel il punto di ingresso principale della congurazione dellapplicazione e quindi memorizzata nella cartella app/. Questa classe deve implementare due metodi: registerBundles() deve restituire un array di tutti i bundle necessari per eseguire lapplicazione; registerContainerConfiguration() carica la congurazione dellapplicazione (approfondito pi avanti); Il caricamento automatico di PHP pu essere congurato tramite app/autoload.php:// app/autoload.php use Symfony\Component\ClassLoader\UniversalClassLoader; $loader = new UniversalClassLoader(); $loader->registerNamespaces(array( Symfony => array(__DIR__./../vendor/symfony/src, __DIR__./../vendor/bundles), Sensio => __DIR__./../vendor/bundles, JMS => __DIR__./../vendor/bundles, Doctrine\\Common => __DIR__./../vendor/doctrine-common/lib, Doctrine\\DBAL => __DIR__./../vendor/doctrine-dbal/lib, Doctrine => __DIR__./../vendor/doctrine/lib, Monolog => __DIR__./../vendor/monolog/src,

18

Capitolo 1. Giro rapido

Documentazione Symfony, Release 2.0

Assetic Metadata

=> __DIR__./../vendor/assetic/src, => __DIR__./../vendor/metadata/src,

)); $loader->registerPrefixes(array( Twig_Extensions_ => __DIR__./../vendor/twig-extensions/lib, Twig_ => __DIR__./../vendor/twig/lib, )); // ... $loader->registerNamespaceFallbacks(array( __DIR__./../src, )); $loader->register();

La classe Symfony\Component\ClassLoader\UniversalClassLoader di Symfony2 usata per auto-caricare i le che rispettano gli standard (http://groups.google.com/group/php-standards/web/psr-0-nal-proposal) di interoperabilit per gli spazi dei nomi di PHP 5.3 oppure la convenzione (http://pear.php.net/) dei nomi di PEAR per le classi. Come si pu vedere, tutte le dipendenze sono sotto la cartella vendor/, ma questa solo una convenzione. Si possono inserire in qualsiasi posto, globalmente sul proprio server o localmente nei propri progetti. Nota: Se si vuole approfondire largomento essibilit dellautoloader di Symfony2, si pu leggere il capitolo Il componente ClassLoader.

Capire il sistema dei bundle Questa sezione unintroduzione a una delle pi grandi e potenti caratteristiche di Symfony2, il sistema dei bundle. Un bundle molto simile a un plugin in un altro software. Ma perch allora si chiama bundle e non plugin? Perch ogni cosa un bundle in Symfony2, dalle caratteristiche del nucleo del framework al codice scritto per la propria applicazione. I bundle sono cittadini di prima classe in Symfony2. Essi forniscono la essibilit di usare delle caratteristiche pre-costruite impacchettate in bundle di terze parti o di distribuire i propri bundle. Questo rende molto facile scegliere quali caratteristiche abilitare nella propria applicazione e ottimizzarle nel modo preferito. A ne giornata, il codice della propria applicazione importante quanto il nucleo stesso del framework.Registrare un bundle

Unapplicazione composta di bundle, come denito nel metodo registerBundles() della classe AppKernel . Ogni bundle una cartella che contiene una singola classe Bundle che la descrive:// 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(), new JMS\SecurityExtraBundle\JMSSecurityExtraBundle(), );

1.1. Giro rapido

19

Documentazione Symfony, Release 2.0

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

Oltre a AcmeDemoBundle, di cui abbiamo gi parlato, si noti che il kernel abilita anche FrameworkBundle, DoctrineBundle, SwiftmailerBundle e AsseticBundle. Fanno tutti parte del nucleo del framework.Congurare un bundle

Ogni bundle pu essere personalizzato tramite le di congurazione scritti in YAML, XML o PHP. Si veda la congurazione predenita:# app/config/config.yml imports: - { resource: parameters.ini } - { resource: security.yml } framework: secret: %secret% charset: UTF-8 router: { resource: "%kernel.root_dir%/config/routing.yml" } form: true csrf_protection: true validation: { enable_annotations: true } templating: { engines: [twig] } #assets_version: SomeVersionScheme session: default_locale: %locale% auto_start: true # Configurazione di Twig twig: debug: %kernel.debug% strict_variables: %kernel.debug% # Configurazione di Assetic assetic: debug: %kernel.debug% use_controller: false filters: cssrewrite: ~ # closure: # jar: %kernel.root_dir%/java/compiler.jar # yui_css: # jar: %kernel.root_dir%/java/yuicompressor-2.4.2.jar # Configurazione di Doctrine doctrine: dbal: driver: %database_driver% host: %database_host% dbname: %database_name%

20

Capitolo 1. Giro rapido

Documentazione Symfony, Release 2.0

user: %database_user% password: %database_password% charset: UTF8 orm: auto_generate_proxy_classes: %kernel.debug% auto_mapping: true # Configurazione di Swiftmailer swiftmailer: transport: %mailer_transport% host: %mailer_host% username: %mailer_user% password: %mailer_password% jms_security_extra: secure_controllers: true secure_all_services: false

Ogni voce come framework denisce la congurazione per uno specico bundle. Per esempio, framework congura FrameworkBundle, mentre swiftmailer congura SwiftmailerBundle. Ogni ambiente pu sovrascrivere la congurazione predenita, fornendo un le di congurazione specico. Per esempio, lambiente dev carica il le config_dev.yml, che carica la congurazione principale (cio config.yml) e quindi la modica per aggiungere alcuni strumenti di debug:# app/config/config_dev.yml imports: - { resource: config.yml } framework: router: { resource: "%kernel.root_dir%/config/routing_dev.yml" } profiler: { only_exceptions: false } web_profiler: toolbar: true intercept_redirects: false monolog: handlers: main: type: path: level: firephp: type: level:

stream %kernel.logs_dir%/%kernel.environment%.log debug firephp info

assetic: use_controller: true

Estendere un bundle

Oltre a essere un modo carino per organizzare e congurare il proprio codice, un bundle pu estendere un altro bundle. Lereditariet dei bundle consente di sovrascrivere un bundle esistente, per poter personalizzare i suoi controllori, i template o qualsiasi altro suo le. Qui sono daiuto i nomi logici (come

1.1. Giro rapido

21

Documentazione Symfony, Release 2.0

@AcmeDemoBundle/Controller/SecuredController.php), che astraggono i posti in cui le risorse sono effettivamente memorizzate. Nomi logici di le Quando si vuole fare riferimento a un le da un bundle, usare questa notazione: @NOME_BUNDLE/percorso/del/file; Symfony2 risolver @NOME_BUNDLE nel percorso reale del bundle. Per esempio, il percorso logico @AcmeDemoBundle/Controller/DemoController.php verrebbe convertito in src/Acme/DemoBundle/Controller/DemoController.php, perch Symfony conosce la locazione di AcmeDemoBundle. Nomi logici di controllori Per i controllori, occorre fare riferimento ai nomi dei metodi usando il formato NOME_BUNDLE:NOME_CONTROLLORE:NOME_AZIONE. Per esempio, AcmeDemoBundle:Welcome:index mappa il metodo indexAction della classe Acme\DemoBundle\Controller\WelcomeController. Nomi logici di template Per i template, il nome logico AcmeDemoBundle:Welcome:index.html.twig convertito al percorso del le src/Acme/DemoBundle/Resources/views/Welcome/index.html.twig. I template diventano ancora pi interessanti quando si realizza che i le non hanno bisogno di essere memorizzati su lesystem. Si possono facilmente memorizzare, per esempio, in una tabella di database. Estendere i bundle Se si seguono queste convenzioni, si pu usare lereditariet dei bundle per sovrascrivere le, controllori o template. Per esempio, se un nuovo bundle chiamato AcmeNewBundle estende AcmeDemoBundle, Symfony prover a caricare prima il controllore AcmeDemoBundle:Welcome:index da AcmeNewBundle e poi cercher il secondo AcmeDemoBundle. Questo vuol dire che un bundle pu sovrascrivere quasi ogni parte di un altro bundle! Capite ora perch Symfony2 cos essibile? Condividere i propri bundle tra le applicazioni, memorizzarli localmente o globalmente, a propria scelta. Usare i venditori Probabilmente la propria applicazione dipender da librerie di terze parti. Queste ultime dovrebbero essere memorizzate nella cartella vendor/. Tale cartella contiene gi le librerie di Symfony2, SwiftMailer, lORM Doctrine, il sistema di template Twig e alcune altre librerie e bundle di terze parti. Capire la cache e i log Symfony2 forse uno dei framework completi pi veloci in circolazione. Ma come pu essere cos veloce, se analizza e interpreta decine di le YAML e XML a ogni richiesta? In parte, per il suo sistema di cache. La congurazione dellapplicazione analizzata solo per la prima richiesta e poi compilata in semplice le PHP, memorizzato nella cartella app/cache/ dellapplicazione. Nellambiente di sviluppo, Symfony2 abbastanza intelligente da pulire la cache quando cambiano dei le. In produzione, invece, occorre pulire la cache manualmente quando si aggiorna il codice o si modica la congurazione. Sviluppando unapplicazione web, le cose possono andar male in diversi modi. I le di log nella cartella app/logs/ dicono tutto a proposito delle richieste e aiutano a risolvere il problema in breve tempo. Usare linterfaccia a linea di comando Ogni applicazione ha uno strumento di interfaccia a linea di comando (app/console), che aiuta nella manutenzione dellapplicazione. La console fornisce dei comandi che incrementano la produttivit, automatizzando dei compiti noiosi e ripetitivi.

22

Capitolo 1. Giro rapido

Documentazione Symfony, Release 2.0

Richiamandola senza parametri, si pu sapere di pi sulle sue capacit:php app/console

Lopzione --help aiuta a scoprire lutilizzo di un comando:php app/console router:debug --help

Considerazioni nali Dopo aver letto questa parte, si dovrebbe essere in grado di muoversi facilmente dentro Symfony2 e farlo funzionare. Ogni cosa in Symfony2 fatta per rispondere alle varie esigenze. Quindi, si possono rinominare e spostare le varie cartelle, nch non si raggiunge il risultato voluto. E questo tutto per il giro veloce. Dai test allinvio di email, occorre ancora imparare diverse cose per padroneggiare Symfony2. Pronti per approfondire questi temi? Senza indugi, basta andare nella pagine del libro e scegliere un argomento a piacere. Un quadro generale > La vista > Il controllore > Larchitettura

1.1. Giro rapido

23

Documentazione Symfony, Release 2.0

24

Capitolo 1. Giro rapido

CAPITOLO 2

Libro

Approfondire Symfony2 con le guide per argomento:

2.1 Libro2.1.1 Symfony2 e fondamenti di HTTPCongratulazioni! Imparando Symfony2, si tende a essere sviluppatori web pi produttivi, versatili e popolari (in realt, per questultimo dovete sbrigarvela da soli). Symfony2 costruito per tornare alle basi: per sviluppare strumenti che consentono di sviluppare pi velocemente e costruire applicazioni pi robuste, anche andando fuori strada. Symfony costruito sulle migliori idee prese da diverse tecnologie: gli strumenti e i concetti che si stanno per apprendere rappresentano lo sforzo di centinaia di persone, in molti anni. In altre parole, non si sta semplicemente imparando Symfony, si stanno imparando i fondamenti del web, le pratiche migliori per lo sviluppo e come usare tante incredibili librerie PHP, allinterno o dipendenti da Symfony2. Tenetevi pronti. Fedele alla losoa di Symfony2, questo capitolo inizia spiegando il concetto fondamentale comune allo sviluppo web: HTTP. Indipendentemente dalla propria storia o dal linguaggio di programmazione preferito, questo capitolo andrebbe letto da tutti. HTTP semplice HTTP (Hypertext Transfer Protocol) un linguaggio testuale che consente a due macchine di comunicare tra loro. Tutto qui! Per esempio, quando controllate lultima vignetta di xkcd (http://xkcd.com/), ha luogo la seguente conversazione (approssimata):

25

Documentazione Symfony, Release 2.0

E mentre il linguaggio veramente usato un po pi formale, ancora assolutamente semplice. HTTP il termine usato per descrivere tale semplice linguaggio testuale. Non importa in quale linguaggio si sviluppi sul web, lo scopo del proprio server sempre quello di interpretare semplici richieste testuali e restituire semplici risposte testuali. Symfony2 costruito n dalle basi attorno a questa realt. Che lo si comprenda o meno, HTTP qualcosa che si usa ogni giorno. Con Symfony2, si imparer come padroneggiarlo.Passo 1: il client invia una richiesta

Ogni conversazione sul web inizia con una richiesta. La richiesta un messaggio testuale creato da un client (per esempio un browser, unapplicazione mobile, ecc.) in uno speciale formato noto come HTTP. Il client invia la richiesta a un server e quindi attende una risposta. Diamo uno sguardo alla prima parte dellinterazione (la richiesta) tra un browser e il server web di xkcd:

Nel gergo di HTTP, questa richiesta apparirebbe in realt in questo modo:GET / HTTP/1.1 Host: xkcd.com Accept: text/html User-Agent: Mozilla/5.0 (Macintosh)

26

Capitolo 2. Libro

Documentazione Symfony, Release 2.0

Questo semplice messaggio comunica ogni cosa necessaria su quale risorsa esattamente il client sta richiedendo. La prima riga di ogni richiesta HTTP la pi importante e contiene due cose: lURI e il metodo HTTP. LURI (p.e. /, /contact, ecc.) lindirizzo univoco o la locazione che identica la risorsa che il client vuole. Il metodo HTTP (p.e. GET) denisce cosa si vuole fare con la risorsa. I metodi HTTP sono verbi della richiesta e deniscono i pochi modi comuni in cui si pu agire sulla risorsa: GET POST PUT DELETE Recupera la risorsa dal server Crea una risorsa sul server Aggiorna la risorsa sul server Elimina la risorsa dal server

Tenendo questo a mente, si pu immaginare come potrebbe apparire una richiesta HTTP per cancellare una specica voce di un blog, per esempio:DELETE /blog/15 HTTP/1.1

Nota: Ci sono in realt nove metodi HTTP deniti dalla specica HTTP, ma molti di essi non sono molto usati o supportati. In realt, molti browser moderni non supportano nemmeno i metodi PUT e DELETE. In aggiunta alla prima linea, una richiesta HTTP contiene sempre altre linee di informazioni, chiamate header. Gli header possono fornire un ampio raggio di informazioni, come lHost richiesto, i formati di risposta accettati dal client (Accept) e lapplicazione usata dal client per eseguire la richiesta (User-Agent). Esistono molti altri header, che possono essere trovati nella pagina di Wikipedia Lista di header HTTP (http://en.wikipedia.org/wiki/List_of_HTTP_header_elds).Passo 2: Il server restituisce una risposta

Una volta che il server ha ricevuto la richiesta, sa esattamente la risorsa di cui il client ha bisogno (tramite lURI) e cosa vuole fare il client con tale risorsa (tramite il metodo). Per esempio, nel caso di una richiesta GET, il server prepara la risorsa e la restituisce in una risposta HTTP. Consideriamo la risposta del server web di xkcd:

Tradotto in HTTP, la risposta rimandata al browser assomiglier a questa:HTTP/1.1 200 OK Date: Sat, 02 Apr 2011 21:05:05 GMT Server: lighttpd/1.4.19 Content-Type: text/html

2.1. Libro

27

Documentazione Symfony, Release 2.0

La risposta HTTP contiene la risorsa richiesta (il contenuto HTML, in questo caso). oltre che altre informazioni sulla risposta. La prima riga particolarmente importante e contiene il codice di stato della risposta HTTP (200, in questo caso). Il codice di stato comunica il risultato globale della richiesta al client. La richiesta andata a buon ne? C stato un errore? Diversi codici di stato indicano successo, errore o che il client deve fare qualcosa (p.e. rimandare a unaltra pagina). Una lista completa pu essere trovata nella pagina di Wikipedia Elenco dei codici di stato HTTP (http://it.wikipedia.org/wiki/Elenco_dei_codici_di_stato_HTTP). Come la richiesta, una risposta HTTP contiene parti aggiuntive di informazioni, note come header. Per esempio, un importante header di risposta HTTP Content-Type. Il corpo della risorsa stessa potrebbe essere restituito in molti formati diversi, inclusi HTML, XML o JSON, mentre lheader Content-Type usa i tipi di media di Internet, come text/html, per dire al client quale formato restituito. Ua lista di tipi di media comuni si pu trovare sulla voce di Wikipedia Lista di tipi di media comuni (http://en.wikipedia.org/wiki/Internet_media_type#List_of_common_media_types). Esistono molti altri header, alcuni dei quali molto potenti. Per esempio, alcuni header possono essere usati per creare un potente sistema di cache.Richieste, risposte e sviluppo web

Questa conversazione richiesta-risposta il processo fondamentale che guida tutta la comunicazione sul web. Questo processo tanto importante e potente, quanto inevitabilmente semplice. Laspetto pi importante questo: indipendentemente dal linguaggio usato, il tipo di applicazione costruita (web, mobile, API JSON) o la losoa di sviluppo seguita, lo scopo nale di unapplicazione sempre quello di capire ogni richiesta e creare e restituire unappropriata risposta. Larchitettura di Symfony strutturata per corrispondere a questa realt. Suggerimento: Per saperne di pi sulla specica HTTP, si pu leggere la RFC HTTP 1.1 (http://www.w3.org/Protocols/rfc2616/rfc2616.html) originale o la HTTP Bis (http://datatracker.ietf.org/wg/httpbis/), che uno sforzo attivo di chiarire la specica originale. Un importante strumento per vericare sia gli header di richiesta che quelli di risposta durante la navigazione lestensione Live HTTP Headers (https://addons.mozilla.org/en-US/refox/addon/3829/) di Firefox.

Richieste e risposte in PHP Dunque, come interagire con la richiesta e creare una risposta quando si usa PHP? In realt, PHP astrae un po lintero processo: