routing (2/3) | train to symfony

69
http://traintosymfony.com 1 Emanuele Gaspari TRAIN TO SYMFONY Verona, 13•14 Aprile 2013 the frameworkshop http://traintosymfony.com @TrainToSymfony Media partner: Routing (2/3)

Upload: inmarelibero

Post on 07-Dec-2014

1.131 views

Category:

Documents


4 download

DESCRIPTION

Topic: Symfony Language: italian (english version soon) First of three presentations shown during the first edition of the Train to Symfony Verona 13/14 April 2013 http://traintosymfony.com http://twitter.com/TrainToSymfony Emanuele Gaspari https://twitter.com/inmarelibero

TRANSCRIPT

Page 1: Routing (2/3) | Train to Symfony

http://traintosymfony.com1 Emanuele Gaspari

TRAINTO SYMFONY

Verona, 13•14 Aprile 2013

the frameworkshop

http://traintosymfony.com@TrainToSymfony

Media partner:

Routing (2/3)

Page 2: Routing (2/3) | Train to Symfony

http://traintosymfony.com2 Emanuele Gaspariabout me

creatore di SymfonyBricks

Emanuele Gaspari

ultimo sito pubblicato (copiaincolla): www.ilovesanmartino.it4 bundles21 controllers6 services9 entities5 repositories custom4 estensioni twig14 macros10 bundles aggiuntivi(FOSUserBundle, FOSJsRoutingBundle, KnpPaginatorBundle, CopiaincollaMetaTagsBundle, etc..)

co-sviluppatore di CopiaincollaMetaTagsBundle https://github.com/copiaincolla/MetaTagsBundle

https://symfonybricks.com

[email protected] @inmarelibero

Page 3: Routing (2/3) | Train to Symfony

http://traintosymfony.com3 Emanuele Gaspari

Symfony: teoria e codice

Routing Templating

frameworkshop: il programma

overview

obiettivo della seconda parte:

il sistema di Routing in Symfony

Page 4: Routing (2/3) | Train to Symfony

http://traintosymfony.com4 Emanuele GaspariRouting

il Routing è il meccanismo di associazione tra url e controllers

Page 5: Routing (2/3) | Train to Symfony

http://traintosymfony.com5 Emanuele Gaspari

Routes

Controller e Action

specificare una Route

Routes parametriche

annotation @Route

collisione di urls

Controller Naming Pattern

Request

oggetto Request

i parametri

Response

oggetto Response

redirect

parametri per il template

ROUTING

Page 6: Routing (2/3) | Train to Symfony

http://traintosymfony.com6 Emanuele GaspariController

Symfony\Bundle\FrameworkBundle\Controller\Controller

● riceve i parametri● esegue delle operazioni e restituisce una risposta

in Symfony un Controller è una classe PHP che estende la classe

task comuni: passaggio di variabili ai templates, accesso a “servizi”, comunicazione con database, redirect

Page 7: Routing (2/3) | Train to Symfony

http://traintosymfony.com7 Emanuele Gaspari

● funzione definita all'interno di un controller

● la firma ha la sintassi public function ...Action()

nel Controller vengono definite le

actions (azioni)

Action

Page 8: Routing (2/3) | Train to Symfony

http://traintosymfony.com8 Emanuele Gaspariactions: esempi

# src/Tts/DemoBundle/Controller/DefaultController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller{

public function homepageAction() { [...] }

public function contattiAction() { [...] }

public function chiSiamoAction() { [...] }}

# src/Tts/DemoBundle/Controller/DefaultController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller{

public function homepageAction() { [...] }

public function contattiAction() { [...] }

public function chiSiamoAction() { [...] }}

Page 9: Routing (2/3) | Train to Symfony

http://traintosymfony.com9 Emanuele Gaspariscopo di un'azione

lo scopo di un'azione è di preparare i datiche verranno mostrati nel template

le azioni non dovrebbero essere molto estese

se un'azione lo è, chiediti se la logica debba essereridistribuita in altri servizi, repository, entities

Page 10: Routing (2/3) | Train to Symfony

http://traintosymfony.com10 Emanuele Gaspari

Routes

Controller e Action

specificare una Route

Routes parametriche

annotation @Route

collisione di urls

Controller Naming Pattern

Request

oggetto Request

i parametri

Response

oggetto Response

redirect

parametri per il template

ROUTING

Page 11: Routing (2/3) | Train to Symfony

http://traintosymfony.com11 Emanuele Gaspari

una Route è un'associazione tra url e controller che specifico:

Route: tra url e Controller

● in app/config/routing.yml● in un altro file yml● nel controller

Page 12: Routing (2/3) | Train to Symfony

http://traintosymfony.com12 Emanuele Gaspari

# app/config/routing.yml

homepage: path: / defaults: { _controller: TtsDemoBundle:Default:homepage }

# app/config/routing.yml

homepage: path: / defaults: { _controller: TtsDemoBundle:Default:homepage }

# src/Tts/DemoBundle/Controller/DefaultController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller{

public function homepageAction() { return $this->render( 'TtsDemoBundle:Default:homepage.html.twig' );

}}

# src/Tts/DemoBundle/Controller/DefaultController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller{

public function homepageAction() { return $this->render( 'TtsDemoBundle:Default:homepage.html.twig' );

}}

/

Page 13: Routing (2/3) | Train to Symfony

http://traintosymfony.com13 Emanuele Gaspari

# app/config/routing.yml

index_catalogo: path: /catalogo defaults: { _controller: TtsDemoBundle:Catalogo:index }

# app/config/routing.yml

index_catalogo: path: /catalogo defaults: { _controller: TtsDemoBundle:Catalogo:index }

# src/Tts/DemoBundle/Controller/CatalogoController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class CatalogoController extends Controller{

public function indexAction(){

[...] }}

# src/Tts/DemoBundle/Controller/CatalogoController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class CatalogoController extends Controller{

public function indexAction(){

[...] }}

/catalogo

Page 14: Routing (2/3) | Train to Symfony

http://traintosymfony.com14 Emanuele Gaspari

Routes

Controller e Action

specificare una Route

Routes parametriche

annotation @Route

collisione di urls

Controller Naming Pattern

Request

oggetto Request

i parametri

Response

oggetto Response

redirect

parametri per il template

ROUTING

Page 15: Routing (2/3) | Train to Symfony

http://traintosymfony.com15 Emanuele Gaspari

stabilisco che una parte del path è variabile

Routes {parametriche}

le parti variabili sono comprese tra { } e vengono passateall'azione come argomenti

Page 16: Routing (2/3) | Train to Symfony

http://traintosymfony.com16 Emanuele Gaspari

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Smfony\Bundle\FrameworkBundle\Controller\Controller;

class ProdottoController extends Controller{

public function showAction($codice){

$em = $this->getDoctrine()->getManager();$entity = $em->getRepository('TtsDemoBundle:Prodotto')->find($codice);[...]

}}

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Smfony\Bundle\FrameworkBundle\Controller\Controller;

class ProdottoController extends Controller{

public function showAction($codice){

$em = $this->getDoctrine()->getManager();$entity = $em->getRepository('TtsDemoBundle:Prodotto')->find($codice);[...]

}}

# app/config/routing.yml

prodotto_show: path: /prodotto/{codice} defaults: { _controller: TtsDemoBundle:Prodotto:show }

# app/config/routing.yml

prodotto_show: path: /prodotto/{codice} defaults: { _controller: TtsDemoBundle:Prodotto:show }

/prodotto/{codice}

Page 17: Routing (2/3) | Train to Symfony

http://traintosymfony.com17 Emanuele Gaspari

# app/config/routing.yml

prodotto_show: path: /prodotto/{categoria}/{codice}/{slug} defaults: { _controller: TtsDemoBundle:Prodotto:show }

# app/config/routing.yml

prodotto_show: path: /prodotto/{categoria}/{codice}/{slug} defaults: { _controller: TtsDemoBundle:Prodotto:show }

/prodotto/{categoria}/{codice}/{slug}

Page 18: Routing (2/3) | Train to Symfony

http://traintosymfony.com18 Emanuele Gaspari

GET /prodotto/147?mobile_layout=trueGET /prodotto/147?mobile_layout=true

# app/config/routing.yml

prodotto_show: path: /prodotto/{codice} defaults: { _controller: TtsDemoBundle:Prodotto:show }

# app/config/routing.yml

prodotto_show: path: /prodotto/{codice} defaults: { _controller: TtsDemoBundle:Prodotto:show }

<?php

public function showAction($codice){ $request = $this->getRequest(); $mobileLayout = $request->get('mobile_layout');

// oppure, più estesamente $mobileLayout = $request->query->get('mobile_layout', 'false');

[…]}

<?php

public function showAction($codice){ $request = $this->getRequest(); $mobileLayout = $request->get('mobile_layout');

// oppure, più estesamente $mobileLayout = $request->query->get('mobile_layout', 'false');

[…]}

passaggio di parametri $_GET

Page 19: Routing (2/3) | Train to Symfony

http://traintosymfony.com19 Emanuele Gaspari

Routes

Controller e Action

specificare una Route

Routes parametriche

annotation @Route

collisione di urls

Controller Naming Pattern

Request

oggetto Request

i parametri

Response

oggetto Response

redirect

parametri per il template

ROUTING

Page 20: Routing (2/3) | Train to Symfony

http://traintosymfony.com20 Emanuele Gaspari

al posto di definire una Route per ogni (sintassi di) url in un file yml

posso usare l'annotazione @Route direttamente nel controller

Page 21: Routing (2/3) | Train to Symfony

http://traintosymfony.com21 Emanuele Gaspari

=

# src/Tts/DemoBundle/Controller/DefaultController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class DefaultController extends Controller{

/** * @Route("/", name=”homepage”) */ public function homepageAction() { [...] }}

# src/Tts/DemoBundle/Controller/DefaultController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class DefaultController extends Controller{

/** * @Route("/", name=”homepage”) */ public function homepageAction() { [...] }}

# app/config/routing.yml

homepage: path: / defaults: { _controller: TtsDemoBundle:Default:homepage }

Page 22: Routing (2/3) | Train to Symfony

http://traintosymfony.com22 Emanuele Gaspari

# app/config/routing.yml

index_catalogo: path: /catalogo defaults: { _controller: TtsDemoBundle:Catalogo:index }

# src/Tts/DemoBundle/Controller/CatalogoController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class CatalogoController extends Controller{ /** * @Route("/catalogo", name=”index_catalogo”) */ public function indexAction() { [...] }}

# src/Tts/DemoBundle/Controller/CatalogoController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class CatalogoController extends Controller{ /** * @Route("/catalogo", name=”index_catalogo”) */ public function indexAction() { [...] }}

=

Page 23: Routing (2/3) | Train to Symfony

http://traintosymfony.com23 Emanuele Gaspari

# app/config/routing.yml

prodotto_show: path: /prodotto/{codice} defaults: { _controller: TtsDemoBundle:Prodotto:show }

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class ProdottoController extends Controller{ /** * @Route("/prodotto/{codice}", name=”prodotto_show”) */ public function showAction($codice) { [...] }}

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class ProdottoController extends Controller{ /** * @Route("/prodotto/{codice}", name=”prodotto_show”) */ public function showAction($codice) { [...] }}

=

Page 24: Routing (2/3) | Train to Symfony

http://traintosymfony.com24 Emanuele Gaspari

# app/config/routing.yml

prodotto_show: path: /prodotto/{categoria}/{codice}/{slug} defaults: { _controller: TtsDemoBundle:Prodotto:show }

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class ProdottoController extends Controller{ /** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”) */ public function showAction($categoria, $codice, $slug) { [...] }}

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;

class ProdottoController extends Controller{ /** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”) */ public function showAction($categoria, $codice, $slug) { [...] }}

=

Page 25: Routing (2/3) | Train to Symfony

http://traintosymfony.com25 Emanuele Gaspari

definisco in app/config/routing.yml quali controller caricare

Page 26: Routing (2/3) | Train to Symfony

http://traintosymfony.com26 Emanuele Gasparitype: annotation

# app/config/config.yml

# TtsDemoBundle Default controllerdefault: resource: “@TtsDemoBundle/Controller/DefaultController.php” type: annotation

# TtsDemoBundle Catalogo controllercatalogo: resource: “@TtsDemoBundle/Controller/CatalogoController.php” type: annotation

# TtsDemoBundle Prodotto controllerprodotto: resource: “@TtsDemoBundle/Controller/ProdottoController.php” type: annotation

# app/config/config.yml

# TtsDemoBundle Default controllerdefault: resource: “@TtsDemoBundle/Controller/DefaultController.php” type: annotation

# TtsDemoBundle Catalogo controllercatalogo: resource: “@TtsDemoBundle/Controller/CatalogoController.php” type: annotation

# TtsDemoBundle Prodotto controllerprodotto: resource: “@TtsDemoBundle/Controller/ProdottoController.php” type: annotation

Page 27: Routing (2/3) | Train to Symfony

http://traintosymfony.com27 Emanuele Gasparitype: annotation (2)

# app/config/config.yml

# TtsDemoBundletts_demo: resource: “@TtsDemoBundle/Controller/” type: annotation

# app/config/config.yml

# TtsDemoBundletts_demo: resource: “@TtsDemoBundle/Controller/” type: annotation

o, semplicemente, specifico la cartella che li contiene tutti

Page 28: Routing (2/3) | Train to Symfony

http://traintosymfony.com28 Emanuele Gaspari

Routes

Controller e Action

specificare una Route

Routes parametriche

annotation @Route

collisione di urls

Controller Naming Pattern

Request

oggetto Request

i parametri

Response

oggetto Response

redirect

parametri per il template

ROUTING

Page 29: Routing (2/3) | Train to Symfony

http://traintosymfony.com29 Emanuele Gaspari

best practice

far corrispondere ad ogni url una sola route

Page 30: Routing (2/3) | Train to Symfony

http://traintosymfony.com30 Emanuele Gaspari

GET /prodotto/EG-124 => prodotto_showGET /prodotto/index => prodotto_show, prodotto_index

# app/config/routing.yml

prodotto_show: path: /prodotto/{codice} defaults: { _controller: TtsDemoBundle:Prodotto:show }

prodotto_index: path: /prodotto/index defaults: { _controller: TtsDemoBundle:Prodotto:index }

# app/config/routing.yml

prodotto_show: path: /prodotto/{codice} defaults: { _controller: TtsDemoBundle:Prodotto:show }

prodotto_index: path: /prodotto/index defaults: { _controller: TtsDemoBundle:Prodotto:index }

collisione di urls

Page 31: Routing (2/3) | Train to Symfony

http://traintosymfony.com31 Emanuele Gaspari

sfrutto l'ordine con cui vengono definite le Routes

il controller si ferma alla prima Route abbinata all'url

è sufficiente definire prima la Route che non contiene parametri

GET /prodotto/indexGET /prodotto/EG-124

# app/config/routing.yml

prodotto_index: path: /prodotto/index

prodotto_show: path: /prodotto/{codice}

# app/config/routing.yml

prodotto_index: path: /prodotto/index

prodotto_show: path: /prodotto/{codice}

soluzione 1, ordine delle Routes

Page 32: Routing (2/3) | Train to Symfony

http://traintosymfony.com32 Emanuele Gaspari

rimane ancora il problema della collisione di urls verso più di una Route

basarsi sull'ordine con cui vengono esaminate le Routes non è sufficiente:dopo un anno che il sito è in produzione, mi ricordo che la

posizione di quella specifica Route è vitale?

anche usando l'annotazione @Route, posso non volere cheall'interno di un Controller una funzione venga spostata

in alto solo perché la Route venga esaminata prima

l'ordine non basta

Page 33: Routing (2/3) | Train to Symfony

http://traintosymfony.com33 Emanuele Gaspari

sfrutto il parametro requirements

# app/config/routing.yml

prodotto_show: path: /prodotto/{codice} requirements: codice: [A-Z]{2}-[0-9]+

prodotto_index: path: /prodotto/index

# app/config/routing.yml

prodotto_show: path: /prodotto/{codice} requirements: codice: [A-Z]{2}-[0-9]+

prodotto_index: path: /prodotto/index

GET /prodotto/indexGET /prodotto/EG-124

non c'è più collisione tra Routesnon mi affido più all'ordine di caricamento

soluzione 2, parametro requirements

pongo dei vincoli sul formato di un parametro di una Route

Page 34: Routing (2/3) | Train to Symfony

http://traintosymfony.com34 Emanuele Gaspari

Routes

Controller e Action

specificare una Route

Routes parametriche

annotation @Route

collisione di urls

Controller Naming Pattern

Request

oggetto Request

i parametri

Response

oggetto Response

redirect

parametri per il template

ROUTING

Page 35: Routing (2/3) | Train to Symfony

http://traintosymfony.com35 Emanuele Gaspari

Symfony associa il nome logico ad unaspecifica classe e metodo (Controller e Action)

bundle:controller:action

nome logico di un Controllersintassi per riferirsi ad un'azione da qualunque punto dell'applicazione

Controller Naming Pattern

Page 36: Routing (2/3) | Train to Symfony

http://traintosymfony.com36 Emanuele Gaspari

TtsDemoBundle:Default:homepage

Bundle Controller MetodoTtsDemoBundleTtsDemoBundle DefaultControllerDefaultController homepageAction()homepageAction()

# src/Tts/DemoBundle/Controller/DefaultController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller{

public function homepageAction() { […] }}

# src/Tts/DemoBundle/Controller/DefaultController.php

<?phpnamespace Tts\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class DefaultController extends Controller{

public function homepageAction() { […] }}

Controller Naming Pattern

Page 37: Routing (2/3) | Train to Symfony

http://traintosymfony.com37 Emanuele Gaspari

# template twig

{{ render(controller(“TtsDemoBundle:Blog:latestPosts”, {“max”: 5})) }}

# template twig

{{ render(controller(“TtsDemoBundle:Blog:latestPosts”, {“max”: 5})) }}

esempio

Page 38: Routing (2/3) | Train to Symfony

http://traintosymfony.com38 Emanuele Gaspari

$ php app/console router:debug$ php app/console router:debug

$ php app/console router:match /prodotto/EG-124$ php app/console router:match /prodotto/EG-124

tips

stampare a console l'elenco di tutte le Routes caricate

verificare se un path è associato da Symfony ad una Route

Page 39: Routing (2/3) | Train to Symfony

http://traintosymfony.com39 Emanuele Gaspari

Routes

Controller e Action

specificare una Route

Routes parametriche

annotation @Route

collisione di urls

Controller Naming Pattern

Request

oggetto Request

i parametri

Response

oggetto Response

redirect

parametri per il template

ROUTING

Page 40: Routing (2/3) | Train to Symfony

http://traintosymfony.com40 Emanuele Gasparioggetto Request

Symfony\Component\HttpFoundation\Request

oggetto che ho a disposizione all'interno di ogni azioneper gestire tutti i parametri della richiesta

Symfony utilizza un oggetto Request per modellare una richiesta HTTP

Page 41: Routing (2/3) | Train to Symfony

http://traintosymfony.com41 Emanuele Gaspariaccedere ad un oggetto Request

<?php

public function homepageAction(){

$request = $this->getRequest();}

<?php

public function homepageAction(){

$request = $this->getRequest();}

use Symfony\Component\HttpFoundation\Request;

$request = Request::createFromGlobals();

use Symfony\Component\HttpFoundation\Request;

$request = Request::createFromGlobals();

accedere a Request in una Action:

accedere a Request da qualunque punto dell'applicazione (in PHP):

$this->getRequest() => 0.04 KbRequest::createFromGlobals() => 7.07 Kb

{{ app.request }}{{ app.request }}

accedere a Request da twig:

Page 42: Routing (2/3) | Train to Symfony

http://traintosymfony.com42 Emanuele Gasparipanoramica

$_GET$request->query

$_POST$request->request

$_COOKIE$request->cookies

$_FILE$request->files

$_SERVER$request->server

http://api.symfony.com/master/Symfony/Component/HttpFoundation/Request.html

$request

->getPathInfo() ->getMethod() ->getLanguages()

->getRequestUri() ->getClientIp() ->getPreferredLanguage()

->getScriptName() ->getSession() ->isXmlHttpRequest()

Page 43: Routing (2/3) | Train to Symfony

http://traintosymfony.com43 Emanuele Gaspari

Routes

Controller e Action

specificare una Route

Routes parametriche

annotation @Route

collisione di urls

Controller Naming Pattern

Request

oggetto Request

i parametri

Response

oggetto Response

redirect

parametri per il template

ROUTING

Page 44: Routing (2/3) | Train to Symfony

http://traintosymfony.com44 Emanuele Gaspari

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”) */public function showAction($codice, $slug, $categoria){ [...]}

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”) */public function showAction($codice, $slug, $categoria){ [...]}

url con parametri

200 GET /prodotto/nuovi/EG-124/eg-124-new-hammer

non importa l'ordinepossono non essere specificati tutti

l'ordine è importante, per associare i parametri dell'url

404 GET /prodotto/nuovi/EG-124404 GET /prodotto/nuovi/EG-124/

Page 45: Routing (2/3) | Train to Symfony

http://traintosymfony.com45 Emanuele Gasparidefaults (1)

200 GET /prodotto/nuovi/EG-124/eg-124-new-hammer200 GET /prodotto/nuovi/EG-124

404 GET /prodotto/nuovi/EG-124/

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”, defaults={“slug”: “-”}) */public function showAction($codice, $categoria, $slug) { [...] }

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”, defaults={“slug”: “-”}) */public function showAction($codice, $categoria) { [...] }

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”) */public function showAction($codice, $categoria, $slug = “-”) { [...] }

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”, defaults={“slug”: “-”}) */public function showAction($codice, $categoria, $slug) { [...] }

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”, defaults={“slug”: “-”}) */public function showAction($codice, $categoria) { [...] }

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”) */public function showAction($codice, $categoria, $slug = “-”) { [...] }

Page 46: Routing (2/3) | Train to Symfony

http://traintosymfony.com46 Emanuele Gaspariaccesso ai parametri

200 GET /prodotto/nuovi/EG-124/eg-124-new-hammer?color=red200 GET /prodotto/nuovi/EG-124?color=red

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”) */public function showAction($codice, $slug = “-”, $categoria){

$request = $this->getRequest();

// nell'url $codice; $codice = $request->get(“codice”);

// in $_GET $color = $request->get(“color”); $color = $request->query->get(“color”);

[...]}

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”) */public function showAction($codice, $slug = “-”, $categoria){

$request = $this->getRequest();

// nell'url $codice; $codice = $request->get(“codice”);

// in $_GET $color = $request->get(“color”); $color = $request->query->get(“color”);

[...]}

Page 47: Routing (2/3) | Train to Symfony

http://traintosymfony.com47 Emanuele Gaspari?get= o /{param}

● parametro essenziale?● eleganza degli url● cambio successivo degli url● indicizzazione dei motori di ricerca● multilingua

quando passare un parametro come ?get=

e quando come/{param}

Page 48: Routing (2/3) | Train to Symfony

http://traintosymfony.com48 Emanuele Gaspari

Routes

Controller e Action

specificare una Route

Routes parametriche

annotation @Route

collisione di urls

Controller Naming Pattern

Request

oggetto Request

i parametri

Response

oggetto Response

redirect

parametri per il template

ROUTING

Page 49: Routing (2/3) | Train to Symfony

http://traintosymfony.com49 Emanuele GaspariResponse

ogni Action restituisce sempre un oggetto Response

real life: molte volte la Action che implementerai restituiràsemplicemente un array di variabili, utilizzabili

in un template che viene scelto più o meno “automaticamente”

Page 50: Routing (2/3) | Train to Symfony

http://traintosymfony.com50 Emanuele Gasparireturn array

la situazione più semplice è quella in cui utilizzol'annotation @Template e la mia Action restituisce

semplicemente un array

Page 51: Routing (2/3) | Train to Symfony

http://traintosymfony.com51 Emanuele Gasparireturn array

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?php

use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class ProdottoController extends Controller{ /** * @Route(“/prodotto/{categoria}/{codice}/{slug}”, name=”prodotto_show”) * @Template() */ public function showAction($codice, $slug, $categoria) {

$entity = $this->getRepository('TtsDemoBundle:Prodotto')->findOneBy( array(“codice” => $codice) );

return array('entity' => $entity); }

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?php

use Symfony\Bundle\FrameworkBundle\Controller\Controller;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class ProdottoController extends Controller{ /** * @Route(“/prodotto/{categoria}/{codice}/{slug}”, name=”prodotto_show”) * @Template() */ public function showAction($codice, $slug, $categoria) {

$entity = $this->getRepository('TtsDemoBundle:Prodotto')->findOneBy( array(“codice” => $codice) );

return array('entity' => $entity); }

Page 52: Routing (2/3) | Train to Symfony

http://traintosymfony.com52 Emanuele Gasparirender()

posso fare in modo che l'azione restituisca un template TWIG compilato,ad esempio perché è diverso in base alla logica interna dell'azione

utlizzo la funzione $this->render() specificando il template

Page 53: Routing (2/3) | Train to Symfony

http://traintosymfony.com53 Emanuele Gaspari

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?php

class ProdottoController extends Controller{

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”) */public function showAction($codice, $slug, $categoria){ $entity = $this->getRepository('TtsDemoBundle:Prodotto')->findOneBy(

array(“codice” => $codice) );

return $this->render('TtsDemoBundle:Prodotto:show_offer.html.twig', array('entity' => $entity

));}

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?php

class ProdottoController extends Controller{

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”) */public function showAction($codice, $slug, $categoria){ $entity = $this->getRepository('TtsDemoBundle:Prodotto')->findOneBy(

array(“codice” => $codice) );

return $this->render('TtsDemoBundle:Prodotto:show_offer.html.twig', array('entity' => $entity

));}

$this->render()

Page 54: Routing (2/3) | Train to Symfony

http://traintosymfony.com54 Emanuele Gasparicostruire una Response

è possibile anche costruire un oggetto Response

utile nel caso in cui abbia necessità di costruire la rispostain più passaggi a seconda di variabili

o di effettuare delle operazioni successivamente

Page 55: Routing (2/3) | Train to Symfony

http://traintosymfony.com55 Emanuele Gasparicostruire una Response

utilizzo la funzione $this->renderView() per memorizzareun contenuto HTML in una variabile

creo un oggetto Response con quella variabile come primo argomentoimpostando

Page 56: Routing (2/3) | Train to Symfony

http://traintosymfony.com56 Emanuele Gaspari

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?php

use Symfony\Component\HttpFoundation\Response;

class ProdottoController extends Controller{

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”) */public function showAction($codice, $slug, $categoria){ $entity = [...]

$content = $this->renderView('TtsDemoBundle:Prodotto:show.html.twig', array('entity' => $entity

));

[...]

return new Response($content);}

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?php

use Symfony\Component\HttpFoundation\Response;

class ProdottoController extends Controller{

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”) */public function showAction($codice, $slug, $categoria){ $entity = [...]

$content = $this->renderView('TtsDemoBundle:Prodotto:show.html.twig', array('entity' => $entity

));

[...]

return new Response($content);}

Page 57: Routing (2/3) | Train to Symfony

http://traintosymfony.com57 Emanuele Gaspari

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?php

use Symfony\Component\HttpFoundation\Response;

class ProdottoController extends Controller{

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”) */public function showAction($codice, $slug, $categoria){ $entity = [...]

$response = new Response($entity->getCodice(), 200, array('content-type' => 'text/html'

));

$response->prepare($this->getRequest());$response->send();

}

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?php

use Symfony\Component\HttpFoundation\Response;

class ProdottoController extends Controller{

/** * @Route("/prodotto/{categoria}/{codice}/{slug}", name=”prodotto_show”) */public function showAction($codice, $slug, $categoria){ $entity = [...]

$response = new Response($entity->getCodice(), 200, array('content-type' => 'text/html'

));

$response->prepare($this->getRequest());$response->send();

}

Page 58: Routing (2/3) | Train to Symfony

http://traintosymfony.com58 Emanuele Gasparijson

anche restituire una risposta in formato json è semplice

Page 59: Routing (2/3) | Train to Symfony

http://traintosymfony.com59 Emanuele Gasparijson Response

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?php

use Symfony\Component\HttpFoundation\Response;use Symfony\Component\HttpFoundation\JsonResponse;

public function jsonAction($codice, $slug, $categoria){ $entity = [...]

$jsonResponse = array(“codice” => $entity->getCodice(), [...]);

// crea una risposta JSON$response = new Response(json_encode($jsonResponse));$response->headers->set('Content-Type', 'application/json');return $response;

// crea una risposta JSON utilizzando la classe JsonResponse (Symfony >= 2.1)$response = new JsonResponse();$response->setData($jsonResponse);return $response;

}

# src/Tts/DemoBundle/Controller/ProdottoController.php

<?php

use Symfony\Component\HttpFoundation\Response;use Symfony\Component\HttpFoundation\JsonResponse;

public function jsonAction($codice, $slug, $categoria){ $entity = [...]

$jsonResponse = array(“codice” => $entity->getCodice(), [...]);

// crea una risposta JSON$response = new Response(json_encode($jsonResponse));$response->headers->set('Content-Type', 'application/json');return $response;

// crea una risposta JSON utilizzando la classe JsonResponse (Symfony >= 2.1)$response = new JsonResponse();$response->setData($jsonResponse);return $response;

}

Page 60: Routing (2/3) | Train to Symfony

http://traintosymfony.com60 Emanuele Gaspaririassunto

● un array● $this->render()● $this->renderView()● un oggetto Response● un oggetto JsonResponse

abbiamo visto che un'azione può utilizzare:

...e può fare molto altro!

Page 61: Routing (2/3) | Train to Symfony

http://traintosymfony.com61 Emanuele Gaspari

Routes

Controller e Action

specificare una Route

Routes parametriche

annotation @Route

collisione di urls

Controller Naming Pattern

Request

oggetto Request

i parametri

Response

oggetto Response

redirect

parametri per il template

ROUTING

Page 62: Routing (2/3) | Train to Symfony

http://traintosymfony.com62 Emanuele Gaspariredirect

il redirect è un messaggio al browsercambia l'url perché è effettivamente una nuova richiesta

in caso di:● redirect temporaneo (302, default) o permanente (301)● invio corretto di un form: redirezione ad una pagina di conferma● se il sito è multilingua, si può effettuare un redirect dopo aver scelto la lingua

in base al browser

Page 63: Routing (2/3) | Train to Symfony

http://traintosymfony.com63 Emanuele Gaspariredirect temporaneo

# src/Tts/DemoBundle/Controller/DefaultController.php

<?php

class DefaultController extends Controller{

/** * @Route("/", name=”homepage”)

*/public function homepageAction(){

return $this->redirect($this->generateUrl('homepage_natale'));}

}

# src/Tts/DemoBundle/Controller/DefaultController.php

<?php

class DefaultController extends Controller{

/** * @Route("/", name=”homepage”)

*/public function homepageAction(){

return $this->redirect($this->generateUrl('homepage_natale'));}

}

redirect temporaneo ad un altro url

Page 64: Routing (2/3) | Train to Symfony

http://traintosymfony.com64 Emanuele GaspariRedirectResponse

c'è un oggetto dedicato (che sorpresa!) che la Action può restituire in caso di redirect: RedirectResponse

Page 65: Routing (2/3) | Train to Symfony

http://traintosymfony.com65 Emanuele GaspariRedirectResponse

# src/Tts/DemoBundle/Controller/DefaultController.php

<?php

use Symfony\Component\HttpFoundation\RedirectResponse

class DefaultController extends Controller{

/** * @Route(“/”, name=”homepage”)

*/public function homepageAction(){

$respose = new RedirectResponse($this->generateUrl('homepage_natale'));

[..]

return $response;}

}

# src/Tts/DemoBundle/Controller/DefaultController.php

<?php

use Symfony\Component\HttpFoundation\RedirectResponse

class DefaultController extends Controller{

/** * @Route(“/”, name=”homepage”)

*/public function homepageAction(){

$respose = new RedirectResponse($this->generateUrl('homepage_natale'));

[..]

return $response;}

}

Page 66: Routing (2/3) | Train to Symfony

http://traintosymfony.com66 Emanuele Gaspari

# src/Tts/DemoBundle/Controller/DefaultController.php

<?php

class DefaultController extends Controller{

/** * @Route("/chisiamo", name=”chisiamo”)

*/public function chisiamoAction(){

return $this->redirect($this->generateUrl('homepage_contatti'), 301);}

}

# src/Tts/DemoBundle/Controller/DefaultController.php

<?php

class DefaultController extends Controller{

/** * @Route("/chisiamo", name=”chisiamo”)

*/public function chisiamoAction(){

return $this->redirect($this->generateUrl('homepage_contatti'), 301);}

}

redirect permanente

redirect permanente con codice di stato HTTP 301

Page 67: Routing (2/3) | Train to Symfony

http://traintosymfony.com67 Emanuele Gaspari

Routes

Controller e Action

specificare una Route

Routes parametriche

annotation @Route

collisione di urls

Controller Naming Pattern

Request

oggetto Request

i parametri

Response

oggetto Response

redirect

parametri per il template

ROUTING

Page 68: Routing (2/3) | Train to Symfony

http://traintosymfony.com68 Emanuele Gaspari

l'azione può passare delle variabili al template restituendo un array

public function showAction($codice){

[...]return array(

'entity' => $entity,'show_extended_version' => true

);}

public function showAction($codice){

[...]return array(

'entity' => $entity,'show_extended_version' => true

);}

utilizzabili nel template twig

{% if show_extended_version %}[...]

{% else %}<a href=”...”>

{{ entity.codice }}</a>

{% endif %}

{% if show_extended_version %}[...]

{% else %}<a href=”...”>

{{ entity.codice }}</a>

{% endif %}

Page 69: Routing (2/3) | Train to Symfony

TRAINTO SYMFONY

Verona, 13•14 Aprile 2013

the frameworkshop

http://traintosymfony.com@TrainToSymfony

Media partner:©Copyright Emanuele Gaspari Castelletti