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
8. http://traintosymfony.com8
Emanuele Gaspari
actions: esempi
# src/Tts/DemoBundle/Controller/DefaultController.php
<?php
namespace TtsDemoBundleController;
use SymfonyBundleFrameworkBundleControllerController;
class DefaultController extends Controller
{
public function homepageAction()
{
[...]
}
public function contattiAction()
{
[...]
}
public function chiSiamoAction()
{
[...]
}
}
# src/Tts/DemoBundle/Controller/DefaultController.php
<?php
namespace TtsDemoBundleController;
use SymfonyBundleFrameworkBundleControllerController;
class DefaultController extends Controller
{
public function homepageAction()
{
[...]
}
public function contattiAction()
{
[...]
}
public function chiSiamoAction()
{
[...]
}
}
9. http://traintosymfony.com9
Emanuele Gaspari
scopo di un'azione
lo scopo di un'azione è di preparare i dati
che verranno mostrati nel template
le azioni non dovrebbero essere molto estese
se un'azione lo è, chiediti se la logica debba essere
ridistribuita in altri servizi, repository, entities
10. 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
31. 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/index
GET /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
32. 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 che
all'interno di un Controller una funzione venga spostata
in alto solo perché la Route venga esaminata prima
l'ordine non basta
33. 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/index
GET /prodotto/EG-124
non c'è più collisione tra Routes
non mi affido più all'ordine di caricamento
soluzione 2, parametro requirements
pongo dei vincoli sul formato di un parametro di una Route
34. 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
35. http://traintosymfony.com35
Emanuele Gaspari
Symfony associa il nome logico ad una
specifica classe e metodo (Controller e Action)
bundle:controller:action
nome logico di un Controller
sintassi per riferirsi ad un'azione da qualunque punto dell'applicazione
Controller Naming Pattern
36. http://traintosymfony.com36
Emanuele Gaspari
TtsDemoBundle:Default:homepage
Bundle Controller Metodo
TtsDemoBundleTtsDemoBundle DefaultControllerDefaultController homepageAction()homepageAction()
# src/Tts/DemoBundle/Controller/DefaultController.php
<?php
namespace TtsDemoBundleController;
use SymfonyBundleFrameworkBundleControllerController;
class DefaultController extends Controller
{
public function homepageAction()
{
[…]
}
}
# src/Tts/DemoBundle/Controller/DefaultController.php
<?php
namespace TtsDemoBundleController;
use SymfonyBundleFrameworkBundleControllerController;
class DefaultController extends Controller
{
public function homepageAction()
{
[…]
}
}
Controller Naming Pattern
38. 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
39. 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
41. http://traintosymfony.com41
Emanuele Gaspari
accedere ad un oggetto Request
<?php
public function homepageAction()
{
$request = $this->getRequest();
}
<?php
public function homepageAction()
{
$request = $this->getRequest();
}
use SymfonyComponentHttpFoundationRequest;
$request = Request::createFromGlobals();
use SymfonyComponentHttpFoundationRequest;
$request = Request::createFromGlobals();
accedere a Request in una Action:
accedere a Request da qualunque punto dell'applicazione (in PHP):
$this->getRequest() => 0.04 Kb
Request::createFromGlobals() => 7.07 Kb
{{ app.request }}{{ app.request }}
accedere a Request da twig:
43. 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
44. 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'ordine
possono non essere specificati tutti
l'ordine è importante, per associare i parametri dell'url
404 GET /prodotto/nuovi/EG-124
404 GET /prodotto/nuovi/EG-124/
45. http://traintosymfony.com45
Emanuele Gaspari
defaults (1)
200 GET /prodotto/nuovi/EG-124/eg-124-new-hammer
200 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 = “-”) { [...] }
46. http://traintosymfony.com46
Emanuele Gaspari
accesso ai parametri
200 GET /prodotto/nuovi/EG-124/eg-124-new-hammer?color=red
200 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”);
[...]
}
47. 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}
48. 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
49. http://traintosymfony.com49
Emanuele Gaspari
Response
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”
54. http://traintosymfony.com54
Emanuele Gaspari
costruire una Response
è possibile anche costruire un oggetto Response
utile nel caso in cui abbia necessità di costruire la risposta
in più passaggi a seconda di variabili
o di effettuare delle operazioni successivamente
55. http://traintosymfony.com55
Emanuele Gaspari
costruire una Response
utilizzo la funzione $this->renderView() per memorizzare
un contenuto HTML in una variabile
creo un oggetto Response con quella variabile come primo
argomentoimpostando
56. http://traintosymfony.com56
Emanuele Gaspari
# src/Tts/DemoBundle/Controller/ProdottoController.php
<?php
use SymfonyComponentHttpFoundationResponse;
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 SymfonyComponentHttpFoundationResponse;
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);
}
57. http://traintosymfony.com57
Emanuele Gaspari
# src/Tts/DemoBundle/Controller/ProdottoController.php
<?php
use SymfonyComponentHttpFoundationResponse;
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 SymfonyComponentHttpFoundationResponse;
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();
}
61. 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
62. http://traintosymfony.com62
Emanuele Gaspari
redirect
il redirect è un messaggio al browser
cambia 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
63. http://traintosymfony.com63
Emanuele Gaspari
redirect 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