Symfony2 - Un Framework PHP 5 Performant

Post on 11-May-2015

9.053 views 3 download

description

L’arrivée de PHP 5.3 en milieu d’année 2009 a bouleversé la manière de développer des applications web. En effet, cette nouvelle version a apporté de nouveaux outils au langage tels que les espaces de nommage qui favorisent la réutilisabilité du code lorsqu’ils sont employés à bon escient. Les nouveaux frameworks de développement rapide ont aussi suivi le mouvement et reposent sur la base de PHP 5.3. C’est le cas de Symfony2 dont la version stable est prévue prochainement.Cette présentation offre un tour d’horizon de la nouvelle architecture du framework qui s’articule autour de “bundles”, de librairies externes et de nombreux composants indépendants tels que le conteneur d’injection de dépendances. Nous dresserons un panorama des principales fonctionnalités offertes par le framework telles que la couche d’ORM Doctrine 2, le moteur de templating Twig et la gestion des formulaires. Nous nous intéresserons également à la gestion du cache HTTP, à la couche de sécurité ainsi qu’aux outils de débogage destinés à améliorer la productivité du développeur et la maintenance de l’application.

Transcript of Symfony2 - Un Framework PHP 5 Performant

Construire des applications web performantes et élégantes avec

Symfony2@hhamon - WebEvent La Ferme du Web – Lyon – 7 mai 2011

R&D

Développement

Formation & Coaching

Audit & Conseil

Media

Composants indépendants et

découplés du framework…

Framework « full-stack »

Composants Bibliothèques

Core Bundles + Bridges

Bundles Standards

BundlesMétiers

Bundles Tiers

Configuration

« Un Bundle est un répertoire qui contient une

structure bien précise et qui

héberge tous les fichiers d’une même

fonctionnalité.  »

Un framework simple et unique !

Respectueux des standards

et bonnes pratiques

- RFC2616- PHPUnit

- Jinja Templates- Spring Security- Design Patterns

Simplifier l’installation et la

configuration

http://symfony.com/download

Télécharger l’Edition Standard qui héberge le framework, les bibliothèques tierces et les bundles standards

Distributions disponibles

Configuration simplifiée

Configuration de la base de données.

Démarrage immédiat avec Symfony2.Happy coding

Envie de l’essayer ?

La philosophie de Symfony2

« Convertir une Requête

entrante en une Réponse »

Générer une réponse brute

class DefaultController extends Controller{ /** @Route("/hello/{name}") */ public function indexAction($name) { // ... do things with $name

return new Response('Hello '. $name); }}

Générer un template

class DefaultController extends Controller{ /** @Route("/hello/{name}") */ public function indexAction($name) { // ... do things with $name

return $this->render( 'AcmeHelloBundle:Default:index.html.twig', array('name' => $name) ); }}

Puissance des annotations

class DefaultController extends Controller{ /** * @Route("/schedule") * @Template */ public function indexAction() { $title = 'WebEvent 2011 Schedule';

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

Templating avec Twig

{% extends "ConfooConferenceBundle::layout.html.twig" %}

{% block content %}

<h1> {{ title }} </h1>

<ul> <li>Caching on the Edge, by Fabien Potencier</li> <li>HipHop for PHP, by Scott Mac Vicar</li> <li>XDebug, by Derick Rethans</li> <li>...</li> </ul>

{% endblock %}

Le moteur de template Twig

Twig est un moteur de templating moderne Rapide

Syntaxe concise et riche Echappement automatique Fonctionnalités modernes Extensible Flexible

Héritage de template

{% extends "ConfooConferenceBundle::layout.html.twig" %}

{% block content %}

<h1> {{ title }} </h1>

<ul> <li>Caching on the Edge, by Fabien Potencier</li> <li>HipHop for PHP, by Scott Mac Vicar</li> <li>XDebug, by Derick Rethans</li> <li>...</li> </ul>

{% endblock %}

index.html.t

wig

Héritage de template

{% extends "::base.html.twig" %}

{% block body %}

<img src="/images/logo.gif" alt="Confoo 2011"/>

{% block content %}{% endblock %}

{% endblock %}

layout.html.t

wig

Héritage de templates

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

base.html.tw

ig

Héritage de template

layout.html.twig

index.html.twig

base.html.twig

Simplifier la définition des URLs

URLs propres

Les URLs classiques

ça craint !!!

URLs propres

Système de routage natif

URL propres

class DefaultController extends Controller{ /** * @Route("/{year}/talk/{month}/{day}/{slug}") * @Template */ public function showAction($slug, $day, $month, $year) { // Get a talk object from the database $talk = ...;

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

Conversion automatique des paramètres

class DefaultController extends Controller{ /** * @Route("/talk/{id}") * @Template */ public function showAction(Talk $talk) { return array('talk' => $talk); }}

Simplifier le Débogage

La barre de débogage

Symfony2 version

PHP environmen

t

Current environment

Current response

Recorded logs

Timers

Memory

Queries

Les traces d’exception

Traces d’exception

Journalisation interne

L’application Profiler

L’application Profiler

Simplifier les interactions avec la BDD

Bibliothèque Doctrine 2

Abstraction de Base de

Données (DBAL)

Mapping Objet Relationnel

(ORM)

Support des Migrations

Mapping Objet Document

(ODM - MongoDB)

Mapping Objet XML (OXM -

XML databases)

Définition des entités Doctrine 2/** @Entity */class Talk{ /** * @Id * @GeneratedValue * @Column(type="integer") */ public $id;

/** @Column(length=80, nullable=false) */ public $title;

/** @Column(type="datetime") */ public $schedule;

/** @ManyToMany(targetEntity="Speaker", mappedBy="talks") */ public $speakers;}

Persistance des entités en BDDclass TalkController extends Controller{ /** @Route("/talks/new") */ public function createAction() { $em = $this->get('registry')->getEntityManager();

$talk = new Talk(); $talk->setTitle('Symfony2, a professional framework'); $talk->setSchedule(new \DateTime('2011-03-12 16:00')); $talk->addSpeaker(new Speaker('Hugo Hamon')); $talk->addSpeaker(new Speaker('Fabien Potencier'));

$em->persist($talk); $em->flush(); }}

Simplifier la validation

des données

Validation

POPOs

Annotations

Extensible

Formulaires

Valider des objets PHP

class ContactRequest{ /** @NotBlank */ public $message;

/** * @Email * @NotBlank */ public $sender;}

Simplifier la gestion des

formulaires

Traitement des formulaires

Valider des objets de Domaine

Protection CSRF Validation Templating avec Twig

class ShopController extends Controller{ public function indexAction() { $product = new Product(); $product->name = 'Test product'; $product->setPrice('50.00');

$form = $this->get('form.factory') ->createBuilder('form', $product) ->add('name', 'text') ->add('price', 'money', array('currency' => 'USD')) ->getForm();

return array('form' => $form->createView()); }}

Traitement du formulairepublic function indexAction(){ $product = new Product(); $form = ...;

$request = $this->get('request'); if ('POST' === $request->getMethod()) {

$form->bindRequest($request);

if ($form->isValid()) { // handle data, persist the object to the database... } }

return array('form' => $form->createView());}

Prototypage avec Twig

<form action="#" method="post">

{{ form_widget(form) }}

<button type="submit"> Create the product

</button>

</form>

Fonctions de rendu avec TwigName Description{{ form_enctype(form) }} Rend un attribut « enctype »

{{ form_errors(form) }}

Rend les erreurs globales du formulaire

{{ form_label(form.age) }}

Rend le label d’un champ « age »

{{ form_errors(form.age) }}

Rend les erreurs d’un champ « age »

{{ form_widget(form.age) }}

Rend le widget d’un champ « age »

{{ form_row(form.age)) }}

Rend une ligne complète d’un champ « age »

{{ form_rest(form) }} Rend les champs non rendus

Simplifier les tests fonctionnels

Tests fonctionnelsSimuler un véritable

navigateur et réaliser des parcours de

navigation sur l’application

Tests Fonctionnels

class DefaultControllerTest extends WebTestCase{ public function testIndex() { $client = $this->createClient(); $crawler = $client->request('GET', '/schedule');

$this->assertTrue( $crawler->filter('html:contains("Fabien")')->count() > 0 );

$response = $client->getResponse(); $this->assertTrue($response->headers->has('expires')); }}

Simplifier le cache des pages

Expiration & Validation

Expiration avec Expires

class DefaultController extends Controller{ /** * @Route("/schedule") * @Template * @Cache(expires="tomorrow") */ public function indexAction() { $title = 'Confoo 2011 Conferences Schedule';

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

Expiration avec Cache-Control

class DefaultController extends Controller{ /** * @Route("/schedule") * @Template * @Cache(maxage="20") */ public function indexAction() { $title = 'Confoo 2011 Conferences Schedule';

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

PHPVarnishSquid

http://www.varnish-cache.org

Edge Side Includes

<esi:include src="http://..." />

Authentification

Authorization

Merci !

Sensio Labs recrute !