114
Introduction à Symfony2

Introduction à Symfony2

Embed Size (px)

DESCRIPTION

Cette nouvelle version du framework a été entièrement réécrite afin de tirer profit de PHP 5.3 d'une part mais également de corriger les erreurs du passé avec symfony 1.x.Cette nouvelle version regorge de fonctionnalités puissantes pour vous aider à bâtir des applications web maintenables, pérennes, performantes et évolutives.Cette présentation donne un aperçu des nouvelles fonctionnalités de Symfony2 comme l'architecture MVC, les tests automatisés ou bien encore l'envoi d'emails.

Citation preview

Page 1: Introduction à Symfony2

Introduction à Symfony2

Page 2: Introduction à Symfony2

•  Hugo HAMON (@hhamon)

•  Responsable des formations Sensio Labs •  Secrétaire Général de l’AFUP

•  10 ans de développement web dont 8 avec PHP •  Coauteur d’ouvrages Eyrolles •  Apprendre-PHP.com / HugoHamon.com

Page 3: Introduction à Symfony2

Qu’est-ce que Symfony2 ?

Page 4: Introduction à Symfony2

Un framework web

Page 5: Introduction à Symfony2

PHP 5.3

Page 6: Introduction à Symfony2

Objectifs ?

Page 7: Introduction à Symfony2

•  Développer plus vite et mieux •  Faciliter le travail en équipe •  Pérenniser les applications •  Simpli!er la maintenance et les évolutions •  Se concentrer sur la logique métier

•  Ne pas réinventer la roue !

Page 8: Introduction à Symfony2

Symfony2 intègre les meilleurs outils Open-Source PHP

Page 9: Introduction à Symfony2

Symfony Components

Dependency Injection Container Request Handler Event Dispatcher

Console YAML

Page 10: Introduction à Symfony2

Zend Framework PHPUnit

Doctrine2 Swift Mailer

Twig

Page 11: Introduction à Symfony2

Différences avec symfony 1.x ?

Page 12: Introduction à Symfony2

Même philosophie, Même outillage,

Moins de concepts, Plus de #exibilité

Performances accrues

Page 13: Introduction à Symfony2

Où en est-on aujourd’hui ?

Page 14: Introduction à Symfony2

•  Version ALPHA

•  Briques logicielles manquantes

•  Documentation incomplète

•  L’API peut encore beaucoup évoluer

•  Version stable repoussée à début Mars 2011

Page 15: Introduction à Symfony2

Je veux tester Symfony2 ! git clone http://github.com/symfony/symfony-sandbox.git

http://www.symfony-reloaded.org

Page 16: Introduction à Symfony2

Je veux développer un projet client maintenant avec Symfony2 ?

A ta place, je ne ferai pas ça…

Page 17: Introduction à Symfony2

Quel outillage ?

Page 18: Introduction à Symfony2

•  Sécurité •  Architecture MVC •  URLs élégantes •  DBAL & ORM •  Outils de débogage •  Formulaires •  Con!guration

•  Extensibilité •  I18N & L10N •  Authenti!cation et ACLs •  Tests unitaires •  Tests fonctionnels •  Cache •  Admin Generator

Page 19: Introduction à Symfony2

Architecture d’un projet Symfony2

Page 20: Introduction à Symfony2

Un Projet Symfony2 est un répertoire qui se compose d’une Application, d’un

jeu de Bundles et de librairies.

Page 21: Introduction à Symfony2

. |-- LICENSE |-- README |-- app/ | |-- AppCache.php | |-- AppKernel.php | |-- cache/ | |-- config/ | |-- console | |-- logs/ | |-- phpunit.xml.dist | `-- views/ |-- bin/ | |-- create_sandbox.sh | |-- install_vendors.sh | |-- prepare_vendors.sh | `-- update_vendors.sh |-- src/ | |-- Application/ | |-- Bundle/ | |-- autoload.php | `-- vendor/ `-- web/ |-- bundles/ |-- check.php |-- index.php `-- index_dev.php

Répertoire  de  l’Applica0on  

Code  de  l’Applica0on  +    Bundles  +    

Librairies  externes  

Dossier  public  

Page 22: Introduction à Symfony2

Une Application est un répertoire qui contient la con!guration pour un jeu de

Bundles donné.

Page 23: Introduction à Symfony2

app/ |-- AppCache.php |-- AppKernel.php |-- cache/ |-- config/ | |-- config.yml | |-- config_dev.yml | |-- config_test.yml | |-- routing.yml | `-- routing_dev.yml |-- console |-- logs/ | `-- dev.log |-- phpunit.xml.dist `-- views/ |-- layout.php

The  AppKernel  class  is  the    main  class  of  the  applica0on  

Configura0on  files  

Logs  and  applica0on  templates  

Structure d’une application

Page 24: Introduction à Symfony2

Un Bundle est un ensemble structuré et cohérent de !chiers qui implémentent une fonctionnalité

(un blog, un forum, …) et qui peut facilement être partagé avec d’autres développeurs.

Page 25: Introduction à Symfony2

symfony 1.x => Plugins Symfony 2.x => Bundles

Page 26: Introduction à Symfony2

+ BlogBundle/ |-- Controller/ | `-- BlogController.php |-- Entity/ | `-- Post.php |-- Form/ | `-- PostForm.php |-- BlogBundle.php |-- Model/ | `-- PostRepository.php |-- Resources/ | |-- config/ | | `-- routing.yml | |-- views/ | | `-- Blog/ | | |-- showPost.php | | `-- listPost.php | `-- public/ | `-- css/ | `-- blog.css `-- Tests/ `-- Controller/ `-- BlogControllerTest.php

Le  fichier  BlogBundle.php  est  obligatoire  et  con0ent  la  classe  qui  

déclare  le  bundle.  

Un  bundle  peut  contenir  de  la  configura0on,  des  templates  et  des  

ressources  web.  

Un  bundle  peut  aussi  contenir  des  scripts  de  tests  PHPUnit.  

Code  source  du  bundle  :  contrôleurs  modèles,  formulaires…  

Page 27: Introduction à Symfony2

Sécurité

Page 28: Introduction à Symfony2

XSS CSRF

SQL Injections

Page 29: Introduction à Symfony2

Le dossier web/ du projet est le seul accessible depuis un navigateur web

Page 30: Introduction à Symfony2

Routage et URLs

Page 31: Introduction à Symfony2

Le système de routage a pour rôle de convertir une URL en une réponse web.

Page 32: Introduction à Symfony2

Elles sont propres et élégantes a!n d’exposer des informations pertinentes et de masquer

l’implémentation technique…

http://www.domain.com/blog/2010/09/15/symfony2-rocks

Page 33: Introduction à Symfony2

Con!guration des URLs en YAML # src/Bundle/BlogBundle/Resources/config/routing.yml

post_details: pattern: /blog/:year/:month/:day/:slug defaults: { _controller: BlogBundle:Blog:showPost }

Exemple d’URL générée http://www.domain.com/blog/2010/09/15/symfony2-rocks

Page 34: Introduction à Symfony2

Association URL et Code ?

Page 35: Introduction à Symfony2

# src/Application/HelloBundle/Resources/config/routing.yml

hello: pattern: /hello/:name defaults: { _controller: HelloBundle:Hello:index }

# src/Application/HelloBundle/Controller/HelloController.php

namespace Application\HelloBundle\Controller;

class HelloController extends Controller { public function indexAction($name) { // ... } }

Page 36: Introduction à Symfony2

# src/Application/HelloBundle/Resources/config/routing.yml

hello: pattern: /hello/:name defaults: { _controller: HelloBundle:Hello:index }

# src/Application/HelloBundle/Controller/HelloController.php

namespace Application\HelloBundle\Controller;

class HelloController extends Controller { public function indexAction($name) { // ... } }

Nom  du  Bundle  

Un  dossier  /  namespace  

Page 37: Introduction à Symfony2

# src/Application/HelloBundle/Resources/config/routing.yml

hello: pattern: /hello/:name defaults: { _controller: HelloBundle:Hello:index }

# src/Application/HelloBundle/Controller/HelloController.php

namespace Application\HelloBundle\Controller;

class HelloController extends Controller { public function indexAction($name) { // ... } }

Nom  du  contrôleur  

Une  classe  

Page 38: Introduction à Symfony2

# src/Application/HelloBundle/Resources/config/routing.yml

hello: pattern: /hello/:name defaults: { _controller: HelloBundle:Hello:index }

# src/Application/HelloBundle/Controller/HelloController.php

namespace Application\HelloBundle\Controller;

class HelloController extends Controller { public function indexAction($name) { // ... } }

Nom  de  l’ac0on  

Une  méthode  

Page 39: Introduction à Symfony2

# src/Application/HelloBundle/Resources/config/routing.yml

hello: pattern: /hello/:name defaults: { _controller: HelloBundle:Hello:index }

# src/Application/HelloBundle/Controller/HelloController.php

namespace Application\HelloBundle\Controller;

class HelloController extends Controller { public function indexAction($name) { // ... } }

Page 40: Introduction à Symfony2

post_details: pattern: /blog/:year/:month/:day/:slug defaults: { _controller: BlogBundle:Blog:showPost }

namespace Application\BlogBundle\Controller;

class BlogController extends Controller { public function showPostAction($slug, $year) { // ... } }

Les paramètres peuvent être passés dans un ordre arbitraire

Page 41: Introduction à Symfony2

Architecture MVC

Page 42: Introduction à Symfony2

•  Séparation du code en trois couches – Logique métier dans le Modèle – Logique applicative dans le Contrôleur – Affichage dans la Vue (templates)

•  Modularité et découplage du code •  Maintenance simpli!ée sur le code source •  Code testable unitairement et plus robuste

Page 43: Introduction à Symfony2

Les actions pour la logique applicative.

Elles se situent dans les Contrôleurs.

Page 44: Introduction à Symfony2

# src/Application/BlogBundle/Resources/config/routing.yml

post_show: pattern: /blog/article/:id/show defaults: { _controller: BlogBundle:Blog:show }

๏ Une action est accessible depuis une URL

Page 45: Introduction à Symfony2

# src/Application/BlogBundle/Controller/BlogController.php

namespace Application\BlogBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class BlogController extends Controller { public function showAction($id) { // find the article by its id $post = ...;

// render the view return $this->render('BlogBundle:Blog:show', array('post' => $post)); } }

Template  à  rendre   Variables  du  template  

Paramètres  de  l’url  

Page 46: Introduction à Symfony2

Les templates constituent la couche de présentation des données, la vue.

Page 47: Introduction à Symfony2

# src/Application/BlogBundle/Resources/views/Blog/show.php

<?php $view->extend('::layout') ?>

<h2><?php echo $post->getTitle() ?></h2>

<p> <?php echo $post->getContent() ?> </p>

๏  Syntaxe alternative de PHP ๏  Quelques brèves instructions PHP (echo, if, foreach…) ๏  Echappement automatique des variables

Layout  de  décora0on  

Variables  échappées  =>  pas  de  XSS  !!!  

Page 48: Introduction à Symfony2

Héritage de Vues

Page 49: Introduction à Symfony2

# src/Application/HelloBundle/Resources/views/Hello/index.php

<?php $view->extend('::layout') ?>

Hello <?php echo $name ?>!

# app/views/layout.php <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> <?php $view['slots']->output('title', 'Hello Application') ?> </title> </head> <body> <?php $view['slots']->output('_content') ?> </body> </html>

étend

Page 50: Introduction à Symfony2

Héritage de Vues

_content

layout.php

Hello Hugo!

index.php

Page 51: Introduction à Symfony2

# src/Application/HelloBundle/Resources/views/Hello/index.php <?php $view->extend('HelloBundle::layout') ?> Hello <?php echo $name ?>!

# app/views/layout.php <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title> <?php $view['slots']->output('title', 'Hello Application') ?> </title> </head> <body> <?php $view['slots']->output('_content') ?> </body> </html>

# src/Application/HelloBundle/Resources/views/layout.php <?php $view->extend('::layout') ?> <h1>Hello Application</h1> <div> <?php $view['slots']->output('_content') ?> </div>

Page 52: Introduction à Symfony2

Héritage multiple

_content

_content Hello Hugo!

index.php

HelloBundle::layout.php

::layout.php

Page 53: Introduction à Symfony2

Les Slots sont des fragments dé!nis dans un template et affichés dans un

layout décorant ce dernier.

Page 54: Introduction à Symfony2

# app/views/layout.php <html> <head> <title> <?php $view['slots']->output('title', 'Hello Application') ?> </title> </head> <body> <?php $view['slots']->output('_content') ?> </body> </html>

# src/Application/HelloBundle/Resources/views/Hello/index.php <?php $view['slots']->set('title', 'Hello World app') ?>

Page 55: Introduction à Symfony2

Symfony fournit des mécanismes simples pour évaluer et inclure des templates

dans un autre # src/Application/HelloBundle/Resources/views/Hello/hello.php Hello <?php echo $name ?>!

# Including another template in the current template <?php echo $view->render('HelloBundle:Hello:hello', array('name' => $name)) ?>

src/Bundle/HelloBundle/Resources/views/Hello/hello.php  

Page 56: Introduction à Symfony2

Symfony offre également un moyen d’inclure le rendu d’une action depuis

une vue…

# src/Application/HelloBundle/Resources/views/Hello/index.php

<?php $view['actions']->output('HelloBundle:Hello:fancy', array( 'name' => $name, 'color' => 'green’ )) ?>

Page 57: Introduction à Symfony2

# src/Application/HelloBundle/Controller/HelloController.php

class HelloController extends Controller { public function fancyAction($name, $color) { // create some object, based on the $color variable $object = ...;

return $this->render('HelloBundle:Hello:fancy', array( 'name' => $name, 'object' => $object )); }

// ... }

Page 58: Introduction à Symfony2

Les aides de vue sont des objets accessibles depuis les templates et qui

permettent de simpli!er la logique d’affichage

Page 59: Introduction à Symfony2

Générer une URL avec le router helper <a href="<?php echo $view['router']->generate('hello', array( 'name' => 'Thomas')) ?>">Greet Thomas!</a>

Inclure des feuilles de style <head> <!-- ... --> <?php $view['stylesheets']->add('css/styles.css') ?> <?php echo $view['stylesheets'] ?> </head>

Page 60: Introduction à Symfony2

Inclure des javascripts

<head> <!-- ... --> <?php $view['javascripts']->add('js/libraries.js') ?> <?php echo $view['javascripts'] ?> </head>

Manipuler des ressource web (images, #ash…)

<img src="<?php echo $view['assets']->getUrl('images/logo.png') ?>" src=""/>

Traduire des chaînes de l’interface

<?php echo $view['translator']->trans('Symfony is %what%!', array( '%what%' => 'awesome')) ?>

Page 61: Introduction à Symfony2

Con!guration

Page 62: Introduction à Symfony2

3 formats de con!guration

PHP YAML XML

Page 63: Introduction à Symfony2

Quel format choisir ? Avantages Inconvénients

XML Validation Complétion dans les EDIs Facile à analyser

Verbeux Long à écrire

YAML Concis Facile à lire Facile à modi!er

Besoin du composant YAML Pas de validation Pas d’autocomplétion

PHP Flexible Plus facile à manipuler

Pas de validation

Page 64: Introduction à Symfony2

Con!guration en YML

# app/config/routing.php

homepage: pattern: / defaults: { _controller: FrameworkBundle:Default:index }

hello: resource: HelloBundle/Resources/config/routing.yml

Import  d’une  autre  configura0on  

Page 65: Introduction à Symfony2

Con!guration en PHP # app/config/routing.php

use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route;

$collection = new RouteCollection();

$collection->addRoute('homepage', new Route('/', array( '_controller' => 'FrameworkBundle:Default:index', )));

$collection->addCollection( $loader->import("HelloBundle/Resources/config/routing.php") );

return $collection; Import  d’une  autre  configura0on  

Page 66: Introduction à Symfony2

Con!guration en XML # app/config/routing.xml

<?xml version="1.0" encoding="UTF-8" ?>

<routes xmlns="http://www.symfony-project.org/schema/routing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.symfony-project.org/schema/routing http://www.symfony-project.org/schema/routing/routing-1.0.xsd">

<route id="homepage" pattern="/"> <default key="_controller">FrameworkBundle:Default:index</default> </route>

<import resource="HelloBundle/Resources/config/routing.xml" /> </routes>

Import  d’une  autre  configura0on  

Page 67: Introduction à Symfony2

Import de !chiers INI # app/config/config_dev.yml imports: - { resource: config.yml } - { resource: custom.ini}

zend.logger: priority: debug path: %kernel.root_dir%/logs/%kernel.environment%.log

# app/config/custom.ini [parameters] dice.min = 1 dice.max = 6

Page 68: Introduction à Symfony2

public function diceAction() { // ...

$min = (int) $this->container->getParameter('dice.min'); $max = (int) $this->container->getParameter('dice.max');

// ... }

Accès à la con!guration depuis le code

Page 69: Introduction à Symfony2

Outils de Débogage

Page 70: Introduction à Symfony2

Parce qu’il est important pour un développeur d’identi!er rapidement les

bogues et les problèmes !!!

Page 71: Introduction à Symfony2

Web Debug Toolbar

Page 72: Introduction à Symfony2

Logs

Page 73: Introduction à Symfony2

Trace  de  l’excep0on  courrante  

Trace  pour  une  InvalidArgumentExcep0on  

404  Status  Code  

Traces d’exception

Page 74: Introduction à Symfony2

Afficher  /  masquer  la  trace  d’une  excep0on  

Logs  enregistrés  

Lien  vers  le  profiler  

Page 75: Introduction à Symfony2

Pro!ler

Page 76: Introduction à Symfony2

Trace  de  l’excep0on  

Recherche  dans  les  logs  

Page 77: Introduction à Symfony2

Requêtes SQL

Page 78: Introduction à Symfony2

Extensibilité

Page 79: Introduction à Symfony2

http://www.symfony2bundles.org

Page 80: Introduction à Symfony2

# app/AppKernel.php class AppKernel extends Kernel { // ... public function registerBundles() { $bundles = array( // ... // Register third party bundles new Bundle\TwitterBundle\TwitterBundle(), new Bundle\ForumBundle\ForumBundle() );

// ... return $bundles; } }

Enregistrement de bundles

Page 81: Introduction à Symfony2

DBAL & ORM Doctrine2

Page 82: Introduction à Symfony2

•  Abstraction de base de données relationnelles •  Performance •  Plus de magie •  Manipulation de vrais objets PHP (POPO) •  Génération de code

•  Adapteur MongoDB disponible

Page 83: Introduction à Symfony2

๏ Con!gurer la connexion BDD en YAML

# app/config/config.yml doctrine.dbal: dbname: Blog user: root password: ~

doctrine.orm: ~

// web/.htaccess or in the vhost configuration

SetEnv SYMFONY__DOCTRINE__DBAL__USERNAME "root" SetEnv SYMFONY__DOCTRINE__DBAL__PASSWORD "secret"

๏ Con!gurer la connexion BDD dans Apache

Page 84: Introduction à Symfony2

๏ Dé!nition d’une entité (table) à l’aide d’une classe PHP

namespace Application\BlogBundle\Entity;

/**

* @Entity(repositoryClass="Application\BlogBundle\Model\BlogPostRepository")

* @Table(name="blog_post")

*/

class BlogPost {

/**

* @Id @Column(type="integer")

* @GeneratedValue(strategy="IDENTITY")

*/

protected $id;

/** @Column(length=100) */

protected $title;

/** @Column(type="text") */

protected $content;

}

Annota0ons  

Page 85: Introduction à Symfony2

๏ Génération de la base de données à partir des classes PHP

๏ Chargement des données de test

$ php app/console doctrine:database:create $ php app/console doctrine:schema:create

$ php app/console doctrine:data:load

Page 86: Introduction à Symfony2

# src/Application/BlogBundle/Resources/data/fixtures/doctrine/fixtures.php

use Application\BlogBundle\Entity\BlogPost;

$post1 = new BlogPost(); $post1->setTitle('My first blog post'); $post1->setContent('Lorem ipsum dolor sit amet...');

$post2 = new BlogPost(); $post2->setTitle('My second blog post'); $post2->setContent('Lorem ipsum dolor sit amet...');

$post3 = new BlogPost(); $post3->setTitle('My third blog post'); $post3->setContent('Lorem ipsum dolor sit amet...');

๏ Les données de test sont écrites en pur PHP

Page 87: Introduction à Symfony2

# src/Application/BlogBundle/Model/BlogPostRepository.php namespace Application\BlogBundle\Model; use Doctrine\ORM\EntityRepository;

class BlogPostRepository extends EntityRepository { public function getHomepagePosts() { $query = $this->_em->createQuery(' SELECT u FROM BlogBundle:BlogPost u ORDER BY u.id DESC ');

return $query->getResult(); } }

๏ Ecrire des requêtes DQL dans un modèle Doctrine

Page 88: Introduction à Symfony2

# src/Application/BlogBundle/Controller/BlogController.php // ... class BlogController extends Controller { public function indexAction() { $em = $this['doctrine.orm.entity_manager'];

$posts = $em->getRepository('BlogBundle:BlogPost') ->getHomepagePosts();

return $this->render('BlogBundle:Blog:index', array( 'posts' => $posts )); }

// ... }

๏  Interroger la base de données à l’aide du Modèle Doctrine

Page 89: Introduction à Symfony2

Emails Swift Mailer

Page 90: Introduction à Symfony2

•  API Orientée Objet Open-Source •  Support des connexions SMTP •  Support des pièces jointes •  Support des formats de mails (text, html…) •  Gestion des !les d’attente (spools) •  Facile à con!gurer et à étendre avec des plugins

Page 91: Introduction à Symfony2

Con!gurer Swift Mailer # app/config/config.yml

swift.mailer: transport: smtp encryption: ssl auth_mode: login host: smtp.gmail.com username: your_username password: your_password

Page 92: Introduction à Symfony2

Envoyer un Email public function indexAction($name) { $mailer = $this['mailer'];

$message = \Swift_Message::newInstance() ->setSubject('Hello Email') ->setFrom('[email protected]') ->setTo('[email protected]') ->setBody($this->renderView('HelloBundle:Hello:email', array( 'name' => $name )));

$mailer->send($message);

return $this->render(...); }

Généra0on  du  corps  du  mail  à  l’aide  d’un  template  et  de  la  méthode  

renderView()  

Récupéra0on  du  service  d’envoi  de  mails  

Page 93: Introduction à Symfony2

Tests Automatisés PHPUnit

Page 94: Introduction à Symfony2

•  Tests Unitaires et Couverture de Code

•  Garantir la qualité du code •  Eviter les bugs et les régressions •  Documenter le code

•  Industrialiser et professionnaliser les développements

Page 95: Introduction à Symfony2

# src/Application/BlogBundle/Tests/Entity/BlogPostTest.php namespace Application\BlogBundle\Tests\Entity; use Application\BlogBundle\Entity\BlogPost;

class BlogPostTest extends \PHPUnit_Framework_TestCase { public function testTitleIsSlugifiedOnce() { $slug = 'symfony2-rules-the-world';

$post = new BlogPost(); $post->setTitle('Symfony2 rules the world'); $this->assertEquals($slug, $post->getSlug());

// Slug doesn't change when it's already set $post->setTitle('An other title'); $this->assertEquals($slug, $post->getSlug()); } }

๏ Exemple de script de tests unitaires dans Symfony2

Page 96: Introduction à Symfony2

•  Tests fonctionnels

•  Simuler des scénarios de navigation •  Simuler un client Web (navigateur)

•  Véri!er que l’application respecte le cahier des charges

Page 97: Introduction à Symfony2

class BlogControllerTest extends WebTestCase { // ... public function testAddComment() { $this->client->followRedirects();

$crawler = $this->client->request('GET', '/');

// Get the first link to a post $link = $crawler->filter('h2.post a')->first()->link();

// Click on the link and check there are two comments $crawler = $this->client->click($link); $this->assertTrue($crawler->filter('.comment')->count() == 2); } }

๏ Exemple de script de tests fonctionnels dans Symfony2

Page 98: Introduction à Symfony2

$crawler = $client->request('GET', '/hello/Fabien');

๏  Simuler des requêtes GET

๏  Simuler des requêtes POST $client->request('POST', '/submit', array('name' => 'Fabien')

$client->request('POST', '/submit', array('name' => 'Fabien'), array('photo' => '/path/to/photo') );

๏  Simuler des uploads de !chiers en POST

Page 99: Introduction à Symfony2

$client->request('DELETE', '/post/12', array(), array(), array( 'PHP_AUTH_USER' => 'username', 'PHP_AUTH_PW' => 'pa$$word' ));

๏  Simuler une requête HTTP DELETE avec des entêtes

๏  Désactiver / activer les redirections HTTP

$client->followRedirects(false);

$client->followRedirect();

$client->insulate();

๏  Insoler le client dans un processus séparé

Page 100: Introduction à Symfony2

$client->back();

$client->forward();

$client->reload();

๏  Naviguer dans l’historique comme dans un navigateur web

๏  Réinitialiser le Client

$client->restart();

Page 101: Introduction à Symfony2

๏ Parcourir le DOM avec le DOM Crawler

// Nodes that match the CSS selector $crawler->filter('h1');

// Nodes that match the XPath expression $crawler->filterXpath('h1');

// Node for the specified index $crawler->eq(1);

// First node $crawler->first();

// Last node $crawler->last();

Page 102: Introduction à Symfony2

// Siblings $crawler->siblings();

// All following siblings $crawler->nextAll();

// All preceding siblings $crawler->previousAll();

// Parent nodes $crawler->parents();

// Children $crawler->children();

// Nodes for which the callable, a lambda, returns true $crawler->reduce($lambda);

Page 103: Introduction à Symfony2

// Returns the attribute value for the first node $crawler->attr('class');

// Returns the node value for the first node $crawler->text();

// Extracts an array of attributes for all nodes // (_text returns the node value) $crawler->extract(array('_text', 'href'));

// Executes a lambda for each node // and return an array of results $data = $crawler->each(function ($node, $i) {

return $node->getAttribute('href'); });

๏ Extraire des données sur des noeuds

Page 104: Introduction à Symfony2

๏  Simuler des clics sur des liens ou boutons $crawler->selectLink('Click here');

$link = $crawler->link(); $client->click($link);

$links = $crawler->links();

๏  Poster des formulaires

// Select the submit button of a form $crawler->selectButton('submit');

// Get a form instance $form = $crawler->form();

// Override the default form values $form = $crawler->form(array( 'name' => 'Fabien', 'like_symfony' => true, ));

Page 105: Introduction à Symfony2

Performances

Page 106: Introduction à Symfony2

• PHP 5.3.2 minimum •  “ Cachy framework “ • Cache HTTP & Proxy cache (ESI)

•  Faible consommation mémoire •  Tous les services sont chargés à la demande

Page 107: Introduction à Symfony2

If  the  standalone  parameter  is  set  to  false,  Symfony2  will  render  the  

HTML  content  

// src/Application/BlogBundle/Resources/views/layout.php

$view['actions']->output('BlogBundle:Blog:lastComments', array(), array( 'standalone' => false ));

Page 108: Introduction à Symfony2

<esi:include  src="..."  />  If  the  standalone  parameter  is  set  to  true  and  if  there  is  a  compa0ble  proxy  cache,  Symfony2  will  render  an  ESI  tag  

// src/Application/BlogBundle/Resources/views/layout.php

$view['actions']->output('BlogBundle:Blog:lastComments', array(), array( 'standalone' => true ));

Page 109: Introduction à Symfony2

Edge Side Includes aka ESI...

Page 110: Introduction à Symfony2

Edge Side Includes

Page 111: Introduction à Symfony2
Page 112: Introduction à Symfony2
Page 113: Introduction à Symfony2

Questions ?

Page 114: Introduction à Symfony2

Trainings Business Unit [email protected]

Sensio S.A. 92-98, boulevard Victor Hugo

92 115 Clichy Cedex FRANCE

Tél. : +33 1 40 99 80 80

www.sensiolabs.com - www.symfony-project.org - trainings.sensiolabs.com