2. Cos'e ?
Symfony2 è un insieme di componenti PHP
disaccopiati e coesi utili per la risoluzione di
problemi comuni.
Symfony2 è anche un framework completo
3. Cos'e ?
Symfony2 è un insieme di componenti PHP
disaccopiati e coesi utili per la risoluzione di
problemi comuni.
Symfony2 è anche un framework completo
# indipendenti da altri componenti
(modificando A non rompo B)
4. Symfony2 è un insieme di componenti PHP
disaccopiati e coesi utili per la risoluzione di
problemi comuni.
Symfony2 è anche un framework completo
# singola responsabilità (quindi un unico
motivo per essere modificati)
Cos'e ?
5. Symfony2 non è un framework ma un progetto
Possiamo scegliere se utilizzare alcune
componenti o tutto il full-stack framework
Cos'e ?
6. Non è un MVC framework
Il core non fornisce la parte del model.
Possiamo decidere se implementarla con un
ORM (Doctrine), o in qualsiasi altro modo
Garantisce la separazione della logica dalla
presentazione
Cos'e ?
7. Possiamo definire Symfony2 come un HTTP
Request/Response framework
Riceve richieste HTTP da un client, le elabora
ed invia la risposta al server
Può implementare un pattern MVC per
l'organizzazione interna dell'applicazione.
Cos'e ?
8. E' stato pensato e costruito intorno alle
specifice HTTP
La logica di applicazioni moderne è sempre più
spostata nel browser
Ci serve quindi qualcosa in grado di gestire
richieste e inviare risposte
Cos'e ?
9. HTTP Request
GET /contact HTTP/1.1
Host: xkcd.com
Accept: text/html
User-Agent: Mozilla/5.0
(Macintosh)
VERBO
Header
HTTP
10. HTTP Request / VERBI
HEAD RECUPERA GLI HEADER DELLA
RISORSA( no body )
GET RECUPERA LA RISORSA DAL SERVER
POST CREA LA RISORSA SUL SERVER
PUT MODIFICA LA RISORSA SUL SERVER
DELETE CANCELLA LA RISORSA DAL SERVER
13. ● Youporn
● Utilizzato per tanti progetti importanti (BBC,
CBS ..)
● Sta diventando la base di molti progetti
Open Source (silex, phpunit, behat, assetic,
doctrine, propel, phpBB, Drupal8, ezPublish)
● Tutto questo utilizzo inevitabilmente migliora
l'interoperabilità tra questi progetti (ci si
avvicina ad uno standard)
● Vasta comunità ( > 1600 bundles sviluppati
solo nell'ultimo anno)
Perchè ?
14. ● Molti eventi e gruppi
● Documentazione molto esaustiva e in
continuo aggiornamento
● Abbraccia la filosofia "don't reinvent the
wheel" fornendo una stretta integrazione
con molti progetti open source
● Abbraccia a pieno PHP 5.3
● Dependency Injection
● Twig Template engine (che verrà utilizzato
da Drupal ed ezPublish)
● Built-in web profiler e console
Perchè ?
15. ● Codice robusto (ben scritto, testato)
● Tag @api (api pubblica stabile)
● introduce l'utilizzo di tool fantastici come
Composer
Perchè ?
18. namespace SymfonyComponentHttpFoundation;
namespace SymfonyComponentHttpKernel;
namespace PugMarcheRound1Esempi
use SymfonyComponentDependencyInjectionContainerInterface;
use SymfonyComponentDependencyInjectionContainerBuilder;
Rappresentano un modo di creare insiemi di classi, interfacce,
funzioni e costanti legate tra loro dal comune obiettivo di risolvere un
problema
Namespace
19. Sono stati creati principalmente per risolvere
due problematiche legate alla creazione di
classi e codice riutilizzabile:
1. collisione dei nomi tra le classi (due classi
con lo stesso nome nello stesso progetto)
2. possibilità di creare alias
(PugMarcheRound1EsempiPrimoEsempi
o as Es1), per accorciare i nomi delle
classi e migliolare la leggibilità del codice
Namespace
20. Grazie ai namespace e alla possibilità di
definire funzioni di autoloading, il codice
diventa indipendente da dove sono definiti i
suoi elementi all'interno del filesystem
PRS-0 definisce lo standard di utilizzo per i
namespace
Autoloading (PSR-0)
21. In symfony2 viene caricato app/autoload.php che ha il
compito di includere tutti i file src/ e vendor/
Non si avrà mai bisogno di includere file "a mano".
Symfony2 utilizza i namespace e la convezione psr-0 per
auto-includere tutti i file che serviranno
Nome della classe:
PugMarcheRound1HelloBundleControllerHelloController
Percorso:
src/PugMarche/Round1/HelloBundle/Controller/HelloController.php
Autoloading (PSR-0)
22. Funzione anonima (o lambda) che può
essere definita in qualsiasi momento
Non possiede un nome
Permette di creare una funzione "al volo" e
passarla come parametro in altri costrutti del
linguaggio
Closure
23. $string = "Hello";
$closure = function($name) use ($string) {
echo "$string $name";
};
$closure("Riccardo");
Prima :
$hello = create_function('$name, $string', 'echo "$string $name"' );
Rispetto ad una funziona anonima, la closure
può accedere a variabili definite al di fuori
della closure stessa
Closure
24. Quando viene eseguita, nel suo stack di
esecuzione si porta dietro l'ambiente che ha
intorno al punto dove viene definita (ovvero può
referenziare variabili/oggetti che ha intorno e
modificarli - quindi è in grado di modifcare lo
stato di tali oggetti)
Closure
25. $input = array(1, 2, 3, 4);
$output = array_filter($input, function($v) {
return $v >2;
});
Risultato : array(3, 4)
Utilizzata principalmente all'interno di
chiamate di callback
Closure
26. Closure
Vantaggi :
● migliore leggibilità rispetto a
create_function
● migliora le prestazioni: compilate durante
la fase di parsing del codice sorgente
(create_function eseguita a run-time non
può essere messa in cache)
27. Symfony dalla versione 2.1 adotta Composer
per la gestione delle dipendenze (vendors) ed
eventualmente anche per l'installazione. Dalla
versione 2.1 viene utilizzato anche
l'autoloader di composer.
http://symfony.com/download
http://symfony.com/doc/current/book/installation.html
http://getcomposer.org/
Installazione e config.
28. Download composer e symfony da dentro la cartella del progetto:
curl -s https://getcomposer.org/installer | php
php composer.phar create-project symfony/framework-standard-edition path/
2.1.2
Aggiornare i vendors:
php composer.phar install
Check configurazione:
http://symfony.com/doc/current/book/installation.html#configuration-and-setup
Escludere i vendors dal repository:
.gitignore >> /vendor/
Installazione e config.
29. Partiamo dalla creazione di un bundle che
conterrà tutto il sorgente della nostra
applicazione
php app/console generate:bundle --
namespace=PugMarche/Round1/HelloBundle
Creazione di una pagina - #1
30. Viene creata la cartella:
src/PugMarche/Round1/HelloBundle
In app/AppKernel.php viene aggiunto :
public function registerBundles()
{
$bundles = array(
// ...
new PugMarcheRound1HelloBundlePugMarcheHelloBundle(),
);
// ...
return $bundles;
}
Creazione di una pagina - #1
31. Creazione di un controllore:
// src/PugMarche/Round1/HelloBundle/Controller/HelloController.php
namespace PugMarcheRound1HelloBundleController;
use SymfonyComponentHttpFoundationResponse;
class HelloController
{
public function indexAction($name)
{
return new Response('<html><body>Ciao '.$name.'!</body></html>');
}
}
Ha il compito di elaborare la richiesta che arriva e restituire una risposta. Il
controllore deve sempre tornare un oggetto Response.
Creazione di una pagina - #2
32. Creazione di un rotte:
// src/PugMarche/Round1/HelloBundle/Controller/HelloController.php
namespace PugMarcheRound1HelloBundleController;
use SymfonyComponentHttpFoundationResponse;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
class HelloController
{
/**
* @Route("/hello/{name}", name="hello_action")
*/
public function indexAction($name)
{
return new Response('<html><body>Ciao '.$name.'!</body></html>');
}
}
Creazione di una pagina - #2
possiamo accedere
all'oggetto Request
33. Creazione di una rotta:
// app/config/routing.yml
pug_marche_round1_hello:
resource: "@PugMarcheRound1HelloBundle/Controller/"
type: annotation
prefix: /
Definire una rotta significa semplicemente
definire un mapping tra un URL della nostra
applicazione con una action nel controllore
(ovvero con un metodo)
Creazione di una pagina - #2
34. Template engine
VELOCE
ogni template è compilato in una classe PHP con codice
ottimizzato. L'overhead di compilazione è minimo. La classe
viene eseguita a runtime (app/cache/{env}/twig)
FACILE
Pensato per essere facile da leggere anche da parte dei
grafici (semplice da imparare)
TWIG
35. Template engine
SICURO
Possibilità di impostare un escape automatico su ogni output;
lo sviluppatore può definire una sandbox per i template dove
l'utente ha un accesso limitato ai tags, filtri, oggetti e funzioni
FLESSIBILE
Possibilità di creare tags, filtri, funzioni, operatori. Ereditarietà
tra i template
TWIG
36. Esempio di utilizzo del tag "for":
<ul>
{% for user in users %}
<li>{{ user.username }}</li>
{% else %}
<li>Nessun utente trovato</li>
{% endfor %}
</ul>
.. altri tags: if, filter, extends .. http://twig.sensiolabs.org/doc/tags/index.html
Esempio di utilizzo filtro "upper":
{{ title | upper }} -> possibilità di creare dei fitri custom
..altri filtri: date, url_encode, json_encode, capitalize .. http://twig.sensiolabs.
org/doc/filters/index.html
TWIG
37. Creazione di un vista (twig):
// src/PugMarche/Round1/HelloBundle/Controller/HelloController.php
namespace PugMarcheRound1HelloBundleController;
use SymfonyComponentHttpFoundationResponse;
use SymfonyBundleFrameworkBundleControllerController;
use SensioBundleFrameworkExtraBundleConfigurationRoute;
class HelloController extends Controller
{
/**
* @Route("/hello/{name}")
*/
public function indexAction($name)
{
return $this->render('AcmeHelloBundle:Hello:index.html.twig', array('name' => $name));
}
}
Creazione di una pagina - #2
38. Con un template riusciamo a spostare tutta la presentazione (HTML) in un file
separato e di poterlo riutilizzare (o riutilizzare porzioni) per diverse pagine
render() restituisce un oggetto Response popolato con il contenuto del template
dato.
Per utilizzare render() il controllore deve estendere la classe Controller, che
aggiunge degli helper (come render) alla nostra classe
NomeBundle:NomeControllore:NomeTemplate
/percorso/di/NomeBundle/Resources/views/NomeControllore/NomeTemplate
Creazione di una pagina - #2
39. Il nostro template Twig:
{# src/PugMarche/Round1/HelloBundle/Resources/views/Hello/index.
html.twig #}
{% extends '::base.html.twig' %}
{% block body %}
Ciao {{ name }}!
{% endblock %}
{% %} -> esegue qualcosa
{{ }} -> stampa qualcosa
Creazione di una pagina - #2
40. Il padre:
{# app/Resources/views/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>{% block title %}Benvenuto!{% endblock %}</title>
{% block stylesheets %}{% endblock %}
<link rel="shortcut icon" href="{{ asset('favicon.ico') }}" />
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html>
Creazione di una pagina - #2
41. app : configurazione dell' applicazione
src : tutto il codice php della nostra applicazione
vendor : librerie dei venditori
web : cartella accessibile pubblicamente (contiene i
frontcontroller che eseguono il bootstrap e inviano la
richiesta al kernel; assets)
Struttura cartelle