Your SlideShare is downloading. ×
0
Symfony Components
What's in for you?

Fabien Potencier
Fabien Potencier
•  Serial entrepreneur and developer by passion
•  Founder of Sensio (in 1998)
   –  A services and consu...
Fabien Potencier
•  Creator and lead developer of symfony…
•  and creator and lead developer of some more OSS:
   –  symfo...
Fabien Potencier

•  Read my technical blog: http://fabien.potencier.org/

•  Follow me on Twitter: @fabpot

•  Fork my co...
How many of you use
symfony?
symfony
•  Full-stack framework (MVC architecture)
•  symfony provides the infrastructure/tools needed for 95% of the web
...
But wait,
symfony is a monolithic
framework, right?
A bit of history
symfony 1.0 (January 2007) started as a glue between existing
  Open-Source libraries
A bit of history
symfony 1.1 (June 2008) was a big refactoring of the code base
   –  Decoupled the main component: like F...
The symfony (1.2/1.3/1.4) MVC
framework is based on a set of
cohesive but decoupled classes,
the symfony components
Symfony Components




•    Announced in May 2009
•    Standalone components
•    Packaged individually
•    No dependenci...
Symfony Components




Dedicated website for each component (with code and documentation)
          http://components.symf...
Symfony Components




        They have been migrated to PHP 5.3

http://svn.symfony-project.com/branches/2.0/lib/Symfony...
Symfony Components




Each “old” PHP 5.2 symfony component has been branched
           and a 1.0 version will be release...
Symfony Components
•  Extracted from symfony 1
   –  Event Dispatcher
   –  YAML
   –  Output Escaper
•  Written from scra...
Symfony Components
•  Coming soon…
  –  Request Handler
  –  Form
  –  Command Line Tools
  –  Routing
  –  Security
  –  ...
Symfony Components
Using them in your project
Which version?
•  This presentation is about the components based on PHP 5.3
•  The stable 1.0 branch based on PHP 5.2 has...
Symfony 2.0 Namespaces


SymfonyComponents

SymfonyFoundation

SymfonyFramework
Autoloader


$path = '/path/to/SymfonyComponents/lib';

require_once $path.'/Symfony/Foundation/ClassLoader.php';

$loader...
PHP 5.3 technical interoperability standards

             « … describes the mandatory requirements
                      ...
What does this mean?
•  PHP libraries will finally be 100% technically interoperable and have
   optimum autoloading perfor...
Symfony Components
YAML
SymfonyComponentsYAML
YAML
•  YAML is a human friendly data serialization standard for all
   programming languages (implementations exist in Pe...
YAML

•  Used in symfony for all configuration files
•  Used in Doctrine for schema and fixtures
•  Used in PHPUnit for TAP o...
config:
  key: value
  foo: [foo, bar]
  bar: { foo: bar }
  foobar: { foo: [foo, bar] }
use SymfonyComponentsYAMLYAML;

// Parse YAML
$config = YAML::load(<<<'EOF'
config:
   key: value
   foo: [foo, bar]
   ba...
Symfony Components
Event Dispatcher
SymfonyComponentsEventDispatcher
Event Dispatcher
•  Symfony Event Dispatcher is a PHP library that provides a lightweight
   implementation of the Observe...
An object (the subject)
 maintains a list of its dependents (observers)
  and notifies them automatically of any state
chan...
An event dispatcher is a central object
     that manages connections
  between subjects and observers
It is a powerful mechanism to extend applications
  without having to change the objects themselves

Associated words: hoo...
use SymfonyComponentsEventDispatcherEvent;
use SymfonyComponentsEventDispatcherEventDispatcher;

$dispatcher = new EventDi...
Symfony Event Dispatcher
•  The implementation is simple
   –  No interface to implement
   –  No need to create an event ...
Symfony Event Dispatcher
•  Advantages
   –  Very simple to use
   –  Easy to add new arguments to the listener
   –  Very...
Notifications
•  Notify : all listeners are called in turn, no feedback to the notifier
   –  Logging, …
•  Notify Until : a...
class Response
{
  protected $content, $dispatcher;

    public function __construct(EventDispatcher $dispatcher, $content...
$dispatcher = new EventDispatcher();

// an anonymous listener
$listener = function (Event $event, $content)
{
   return '...
Notifiers              Dispatcher                Listeners

                                                       listene...
The Response object knows nothing about the listeners
The listener objects know nothing about the Response one

They commu...
Notifiers            Dispatcher               Listeners

                                                    listener conn...
Notifiers            Dispatcher




  Response notifies        Calls
response.filter_content   nothing

                  ...
Symfony Components
Templating
SymfonyComponentsTemplating
Symfony Templating


•  Thin layer on top of PHP
   that adds some template-oriented features


•  Can work with Template ...
New Templating Framework
•  4 sub-components
   –  Template Engine
   –  Template Renderers
   –  Template Loaders
   –  T...
use SymfonyComponentsTemplatingEngine;
use SymfonyComponentsTemplatingLoaderFilesystemLoader;

$loader = new FilesystemLoa...
Template Loaders
•  No assumption about where and how templates are to be found
   –  Filesystem
   –  Database
   –  Memo...
Template Renderers
 •  No assumption about the format of the templates
 •  Template names are prefixed with the renderer na...
Template Embedding



Hello <?php echo $name ?>

<?php $this->render('embedded', array('name' => $name)) ?>

<?php $this->...
Template Inheritance

<?php $this->extend('layout') ?>

Hello <?php echo $name ?>

<html>
  <head>
  </head>
  <body>
    ...
Template Slots
<html>
  <head>
    <title><?php $this->output('title') ?></title>
  </head>
  <body>
    <?php $this->outp...
Template Multiple Inheritance



A layout can be decorated by another layout

       Each layout can override slots
Templating
A CMS example
http://fabien.potencier.org/talk/33/php-barcelona-symfony-2-0-on-PHP-5-3?position=76
Symfony Components
Dependency Injection
SymfonyComponentsDependencyInjection
« Dependency Injection is where components
 are given their dependencies through their
constructors, methods, or directly ...
class Message
{
  public function __construct()
  {
    $this->output = new Output();
  }
}




class Message
{
  public f...
DI Hello World example


class Message
{
  public function __construct(OutputInterface $output, array $options)
  {
    $t...
DI Hello World example
interface OutputInterface
{
  public function render($msg);
}

class Output implements OutputInterf...
DI Hello World example



$output = new FancyOutput();
$message = new Message($output, array('with_newline' => true));
$me...
A DI container facilitates
objects description and object relationships,
    configures and instantiates objects
DI Container Hello World example

use SymfonyComponentsDependencyInjectionBuilder;
use SymfonyComponentsDependencyInjectio...
$message = $container->message;

          Get the configuration for the message service

    The Message constructor must ...
$message = $container->message;


                    is roughly equivalent to

                  $output = new FancyOutpu...
$container = new Builder();

$container->register('output', 'FancyOutput');
$container->
  register('message', 'Message')-...
$container = new Builder();

$container->register('output', 'FancyOutput');
$container->
  register('message', 'Message')-...
<container xmlns="http://symfony-project.org/2.0/container">
  <parameters>
    <parameter key="output.class">FancyOutput<...
<container xmlns="http://symfony-project.org/2.0/container">
  <imports>
    <import resource="config.xml" />
  </imports>...
<services>
 <import resource="config.yml" class="SymfonyComponentsDependencyInjection
LoaderYamlFileLoader" />

  <service...
Loaders & Dumpers
•  IniFileLoader
•  XmlFileLoader
•  YamlFileLoader

•    XmlDumper
•    YamlDumper
                    ...
use   SymfonyComponentsDependencyInjectionBuilder;
use   SymfonyComponentsDependencyInjectionReference;
use   SymfonyCompo...
$dumper = new XmlDumper($container);
file_put_contents(__DIR__.'/container.xml', $dumper->dump());

$loader = new XmlFileL...
use SymfonyComponentsDependencyInjectionContainer;
use SymfonyComponentsDependencyInjectionReference;
use SymfonyComponent...
use SymfonyComponentsDependencyInjectionDumperGraphvizDumper;

$dumper = new GraphvizDumper($container);
echo $dumper->dum...
digraph sc {
  ratio="compress"
  node [fontsize="11" fontname="Arial" shape="record"];
  edge [fontsize="9" fontname="Ari...
Symfony Components
Output Escaper
SymfonyComponentsOutputEscaper
Output Escaper
•  Provides automatic XSS protection for your templates
•  By wrapping template variables
•  Works for
    ...
use SymfonyComponentsOutputEscaperEscaper;

$title = 'Foo <br />';

echo Escaper::escape(ESC_SPECIALCHARS, $title);
use SymfonyComponentsOutputEscaperEscaper;

$article = array(
   'title' => 'Foo <br />',
   'author' => array(
     'name...
class Article
{
  protected $title;
  protected $author;

    public $full_title;    public property
    public function _...
class Author
{
  protected $name;

    public function __construct($name) { $this->name = $name; }
    public function get...
use SymfonyComponentsOutputEscaperEscaper;

$article = new Article(
   'foo <br />',
   new Author('Fabien <br />')
);

$a...
Escaping Strategy

                                      explicitly ask
                                      for raw data...
symfony-live.com
           with Matthew Weier O’Pheinney




    I will reveal the first alpha release of Symfony 2.0!
symfony-live.com
          with Matthew Weier O’Pheinney




   … with Matthew Weier O'Phinney as a special guest
Thank you!

My slides on slideshare.com/fabpot
with a bonus: How to use Symfony Components with ZF!
Sensio S.A.
    92-98, boulevard Victor Hugo
        92 115 Clichy Cedex
              FRANCE
       Tél. : +33 1 40 99 80...
BO NUS
         How to use Symfony Components
         within a Zend Framework project?
Symfony components in a ZF project
•  Symfony Components can make your ZF application better
   –  More configurable: symfo...
Symfony Components in a ZF project
•  The examples in this presentation are just to get you started faster

•  So, be crea...
Symfony Components
Event Dispatcher
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
  public function run()
  {
    require_once '/path/to/sfEv...
Symfony Components
Dependency Injection
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
  public function getContainer()
  {
    if (null === $this...
<?xml version="1.0" ?>

<container xmlns="http://symfony-project.org/2.0/container">
  <parameters>
    <parameter key="ma...
parameters:
  mailer.username: foo
  mailer.password: bar
  mailer.class:    Zend_Mail

services:
  mail.transport:
    cl...
class GuestbookController extends Zend_Controller_Action
{
  public function indexAction()
  {
    $guestbook = new Defaul...
Dependency Injection Container
•  By default in ZF, new resources can be added to the container but cannot
   be lazy-load...
Symfony Components
Output Escaper
require_once '/path/to/sfOutputEscaperAutoloader.php';
sfOutputEscaperAutoloader::register();

class My_View extends Zend_...
<dl>
  <?php foreach ($this->entries as $entry): ?>
     <dt><?php echo $this->escape($entry->email) ?></dt>
     <dd><?ph...
Symfony Components 2.0 on PHP 5.3
Symfony Components 2.0 on PHP 5.3
Upcoming SlideShare
Loading in...5
×

Symfony Components 2.0 on PHP 5.3

23,123

Published on

Published in: Technology
0 Comments
13 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
23,123
On Slideshare
0
From Embeds
0
Number of Embeds
6
Actions
Shares
0
Downloads
209
Comments
0
Likes
13
Embeds 0
No embeds

No notes for slide

Transcript of "Symfony Components 2.0 on PHP 5.3"

  1. 1. Symfony Components What's in for you? Fabien Potencier
  2. 2. Fabien Potencier •  Serial entrepreneur and developer by passion •  Founder of Sensio (in 1998) –  A services and consulting company specialized in Web technologies and Internet marketing (France and USA) –  70 people –  Open-Source specialists –  Big corporate customers –  Consulting, training, development, web design, … and more –  Sponsor of a lot of Open-Source projects like symfony and Doctrine
  3. 3. Fabien Potencier •  Creator and lead developer of symfony… •  and creator and lead developer of some more OSS: –  symfony components –  Swift Mailer : Powerful component based mailing library for PHP –  Twig : Fexible, fast, and secure template language for PHP –  Pirum : Simple PEAR Channel Server Manager –  Sismo : PHP continuous integration server –  Lime : Easy to use unit testing library for PHP –  Twitto : A web framework in a tweet –  Twittee : A Dependency Injection Container in a tweet –  Pimple : A small PHP 5.3 dependency injection container
  4. 4. Fabien Potencier •  Read my technical blog: http://fabien.potencier.org/ •  Follow me on Twitter: @fabpot •  Fork my code on Github: http://github.com/fabpot/
  5. 5. How many of you use symfony?
  6. 6. symfony •  Full-stack framework (MVC architecture) •  symfony provides the infrastructure/tools needed for 95% of the web projects •  Open-Source (MIT License) since 2005 •  Based on –  11 years of Sensio experience building websites for its customers –  Existing Open-Source projects
  7. 7. But wait, symfony is a monolithic framework, right?
  8. 8. A bit of history symfony 1.0 (January 2007) started as a glue between existing Open-Source libraries
  9. 9. A bit of history symfony 1.1 (June 2008) was a big refactoring of the code base –  Decoupled the main component: like Forms, Routing, Cache, YAML, ORMs, … sfRequest sfRouting sfLogger sfI18N sfUser sfResponse sfYAML sfDatabase sfForm sfEventDispatcher sfStorage sfCache sfOutputEscaper sfValidator sfWidget sfCoreAutoload platform
  10. 10. The symfony (1.2/1.3/1.4) MVC framework is based on a set of cohesive but decoupled classes, the symfony components
  11. 11. Symfony Components •  Announced in May 2009 •  Standalone components •  Packaged individually •  No dependencies •  Release cycle independent of Symfony, the framework
  12. 12. Symfony Components Dedicated website for each component (with code and documentation) http://components.symfony-project.org/ Dedicated Subversion and Git repository http://svn.symfony-project.com/components/ http://github.com/fabpot
  13. 13. Symfony Components They have been migrated to PHP 5.3 http://svn.symfony-project.com/branches/2.0/lib/Symfony/Components
  14. 14. Symfony Components Each “old” PHP 5.2 symfony component has been branched and a 1.0 version will be released soon http://svn.symfony-project.com/components/
  15. 15. Symfony Components •  Extracted from symfony 1 –  Event Dispatcher –  YAML –  Output Escaper •  Written from scratch for Symfony 2 –  Dependency Injection Container –  Request Handler –  Templating •  We don’t want to duplicate effort done by Zend Framework
  16. 16. Symfony Components •  Coming soon… –  Request Handler –  Form –  Command Line Tools –  Routing –  Security –  Cache –  Debug –  …
  17. 17. Symfony Components Using them in your project
  18. 18. Which version? •  This presentation is about the components based on PHP 5.3 •  The stable 1.0 branch based on PHP 5.2 has the same feature set and work exactly in the same way, except: –  The autoloader –  The class names
  19. 19. Symfony 2.0 Namespaces SymfonyComponents SymfonyFoundation SymfonyFramework
  20. 20. Autoloader $path = '/path/to/SymfonyComponents/lib'; require_once $path.'/Symfony/Foundation/ClassLoader.php'; $loader = new SymfonyFoundationClassLoader('Symfony', $path); $loader->register();
  21. 21. PHP 5.3 technical interoperability standards « … describes the mandatory requirements that must be adhered to for autoloader interoperability » http://groups.google.com/group/php-standards/web/psr-0-final-proposal
  22. 22. What does this mean? •  PHP libraries will finally be 100% technically interoperable and have optimum autoloading performance •  Symfony 2.0 + Doctrine 2.0 + Zend Framework 2.0 •  Load classes from 3 different libraries with one autoloader and one include path •  Also able to load classes implementing the PEAR naming convention •  Share SplClassLoader implementation: –  http://gist.github.com/221634 •  Implement SplClassLoader in C/PHP :)
  23. 23. Symfony Components YAML
  24. 24. SymfonyComponentsYAML
  25. 25. YAML •  YAML is a human friendly data serialization standard for all programming languages (implementations exist in Perl, Ruby, Python, Java, …) •  YAML is a great format for your configuration files •  YAML files are as expressive as XML files and as readable as INI files
  26. 26. YAML •  Used in symfony for all configuration files •  Used in Doctrine for schema and fixtures •  Used in PHPUnit for TAP output and for DataSet (DbUnit)
  27. 27. config: key: value foo: [foo, bar] bar: { foo: bar } foobar: { foo: [foo, bar] }
  28. 28. use SymfonyComponentsYAMLYAML; // Parse YAML $config = YAML::load(<<<'EOF' config: key: value foo: [foo, bar] bar: { foo: bar } foobar: { foo: [foo, bar] } EOF ); // Dump YAML echo YAML::dump($config);
  29. 29. Symfony Components Event Dispatcher
  30. 30. SymfonyComponentsEventDispatcher
  31. 31. Event Dispatcher •  Symfony Event Dispatcher is a PHP library that provides a lightweight implementation of the Observer design pattern •  Based on the Cocoa Notification Center •  Used in symfony to provide hooks and allow customizations of default behaviors sfRequest sfRouting sfLogger sfI18N sfUser sfResponse –  Inject the Web Debug Toolbar sfYAML sfDatabase sfForm sfEventDispatcher sfStorage sfCache sfOutputEscaper –  Inject methods into core Objects sfValidator sfWidget sfCoreAutoload platform –  I18n management –  …
  32. 32. An object (the subject) maintains a list of its dependents (observers) and notifies them automatically of any state changes, usually by calling one of their methods http://en.wikipedia.org/wiki/Observer_pattern
  33. 33. An event dispatcher is a central object that manages connections between subjects and observers
  34. 34. It is a powerful mechanism to extend applications without having to change the objects themselves Associated words: hook, listener, event, subject, …
  35. 35. use SymfonyComponentsEventDispatcherEvent; use SymfonyComponentsEventDispatcherEventDispatcher; $dispatcher = new EventDispatcher(); // an anonymous listener $listener = function (Event $event) { echo "Hello {$event['name']}n"; }; // register the listener (any PHP callable) with the dispatcher $dispatcher->connect('foo', $listener); // notify the event somewhere $event = new Event(null, 'foo', array('name' => 'Fabien')); $dispatcher->notify($event);
  36. 36. Symfony Event Dispatcher •  The implementation is simple –  No interface to implement –  No need to create an event class for each event –  An event is just a unique identifier –  Some conventions (parameter names)
  37. 37. Symfony Event Dispatcher •  Advantages –  Very simple to use –  Easy to add new arguments to the listener –  Very fast –  Very easy to add a new event, just notify it with a unique name •  Disadvantages –  The contract between the listener and the notifier is quite loose
  38. 38. Notifications •  Notify : all listeners are called in turn, no feedback to the notifier –  Logging, … •  Notify Until : all listeners are called until one « processes » the event. The listener that has processed the event can return something to the caller –  Exceptions, Method not found in __call(), … •  Filter : Each listener filters a given value and can change it. The filtered value is returned to the caller –  HTML content, parameters, …
  39. 39. class Response { protected $content, $dispatcher; public function __construct(EventDispatcher $dispatcher, $content) { $this->dispatcher = $dispatcher; $this->content = $content; } public function send() { $event = new Event($this, 'response.filter_content'); $this->dispatcher->filter($event, $this->content); echo $event->getReturnValue(); } }
  40. 40. $dispatcher = new EventDispatcher(); // an anonymous listener $listener = function (Event $event, $content) { return '*'.$content.'*'; }; // register the listener $dispatcher->connect('response.filter_content', $listener); $response = new Response($dispatcher, 'Hello'); $response->send();
  41. 41. Notifiers Dispatcher Listeners listener connects 1 to ‘response.filter_content’ Response notifies Calls listener 2 ‘response.filter_content’ all listeners is called
  42. 42. The Response object knows nothing about the listeners The listener objects know nothing about the Response one They communicate through the Dispatcher object Anybody can listen to the ‘response.filter_content’ event and acts accordingly
  43. 43. Notifiers Dispatcher Listeners listener connects 1 to response.filter_content Your class connects to response.filter_content Response notifies Calls listener 2 response.filter_content all listeners is called Your class callback is called
  44. 44. Notifiers Dispatcher Response notifies Calls response.filter_content nothing very small overhead
  45. 45. Symfony Components Templating
  46. 46. SymfonyComponentsTemplating
  47. 47. Symfony Templating •  Thin layer on top of PHP that adds some template-oriented features •  Can work with Template Engines (Smarty, Twig, …)
  48. 48. New Templating Framework •  4 sub-components –  Template Engine –  Template Renderers –  Template Loaders –  Template Storages
  49. 49. use SymfonyComponentsTemplatingEngine; use SymfonyComponentsTemplatingLoaderFilesystemLoader; $loader = new FilesystemLoader( '/path/to/templates/%name%.php' ); $t = new Engine($loader); echo $t->render('index', array('name' => 'Fabien'));
  50. 50. Template Loaders •  No assumption about where and how templates are to be found –  Filesystem –  Database –  Memory, … •  Built-in loaders: FilesystemLoader, ChainLoader, CacheLoader •  Template names are « logical » names: $loader = new FilesystemLoader('/path/to/templates/%name%.php');
  51. 51. Template Renderers •  No assumption about the format of the templates •  Template names are prefixed with the renderer name: –  index == php:index –  user:index $t = new Engine($loader, array( 'user' => new ProjectTemplateRenderer(), 'php' => new PhpRenderer(), ));
  52. 52. Template Embedding Hello <?php echo $name ?> <?php $this->render('embedded', array('name' => $name)) ?> <?php $this->render('smarty:embedded') ?>
  53. 53. Template Inheritance <?php $this->extend('layout') ?> Hello <?php echo $name ?> <html> <head> </head> <body> <?php $this->output('content') ?> </body> </html>
  54. 54. Template Slots <html> <head> <title><?php $this->output('title') ?></title> </head> <body> <?php $this->output('content') ?> </body> </html> <?php $this->set('title', 'Hello World! ') ?> <?php $this->start('title') ?> Hello World! <?php $this->stop() ?>
  55. 55. Template Multiple Inheritance A layout can be decorated by another layout Each layout can override slots
  56. 56. Templating A CMS example
  57. 57. http://fabien.potencier.org/talk/33/php-barcelona-symfony-2-0-on-PHP-5-3?position=76
  58. 58. Symfony Components Dependency Injection
  59. 59. SymfonyComponentsDependencyInjection
  60. 60. « Dependency Injection is where components are given their dependencies through their constructors, methods, or directly into fields. » http://www.picocontainer.org/injection.html
  61. 61. class Message { public function __construct() { $this->output = new Output(); } } class Message { public function __construct(OutputInterface $output) { $this->output = $output; } }
  62. 62. DI Hello World example class Message { public function __construct(OutputInterface $output, array $options) { $this->output = $output; $this->options = array_merge(array('with_newline' => false), $options); } public function say($msg) { $this->output->render($msg.($this->options['with_newline'] ? "n" : '')); } }
  63. 63. DI Hello World example interface OutputInterface { public function render($msg); } class Output implements OutputInterface { public function render($msg) { echo $msg; } } class FancyOutput implements OutputInterface { public function render($msg) { echo sprintf("033[33m%s033[0m", $msg); } }
  64. 64. DI Hello World example $output = new FancyOutput(); $message = new Message($output, array('with_newline' => true)); $message->say('Hello World');
  65. 65. A DI container facilitates objects description and object relationships, configures and instantiates objects
  66. 66. DI Container Hello World example use SymfonyComponentsDependencyInjectionBuilder; use SymfonyComponentsDependencyInjectionReference; $container = new Builder(); $container->register('output', 'FancyOutput'); $container-> register('message', 'Message')-> setArguments(array(new Reference('output'), array('with_newline' => true))) ; $container->message->say('Hello World!');
  67. 67. $message = $container->message; Get the configuration for the message service The Message constructor must be given an output service Get the output object from the container Create a Message object by passing the constructor arguments
  68. 68. $message = $container->message; is roughly equivalent to $output = new FancyOutput(); $message = new Message($output, array('with_newline' => true));!
  69. 69. $container = new Builder(); $container->register('output', 'FancyOutput'); $container-> register('message', 'Message')-> setArguments(array(new Reference('output'), array('with_newline' => true))) ; $container->message->say('Hello World!'); PHP <container xmlns="http://symfony-project.org/2.0/container"> <services> XML <service id="output" class="FancyOutput" /> <service id="message" class="Message"> XML is validated <argument type="service" id="output" /> against an XSD <argument type="collection"> <argument key="with_newline">true</argument> </argument> </service> </services> </container> $container = new Builder(); $loader = new XmlFileLoader($container); $loader->load('services.xml');
  70. 70. $container = new Builder(); $container->register('output', 'FancyOutput'); $container-> register('message', 'Message')-> setArguments(array(new sfServiceReference('output'), array('with_newline' => true))) ; $container->message->say('Hello World!'); PHP services: output: { class: FancyOutput } message: YAML class: Message arguments: - @output - { with_newline: true } $container = new Builder(); $loader = new YamlFileLoader($container); $loader->load('services.yml');
  71. 71. <container xmlns="http://symfony-project.org/2.0/container"> <parameters> <parameter key="output.class">FancyOutput</parameter> <parameter key="message.options" type="collection"> <parameter key="with_newline">true</parameter> </parameter> </parameters> <services> <service id="output" class="%output.class%" /> <service id="message" class="Message"> <argument type="service" id="output" /> <argument>%message.options%</argument> </service> </services> </container> $container = new Builder(); $loader = new XmlFileLoader($container); $loader->load('services.xml');
  72. 72. <container xmlns="http://symfony-project.org/2.0/container"> <imports> <import resource="config.xml" /> </imports> <services> <service id="output" class="%output.class%" /> <service id="message" class="Message"> <argument type="service" id="output" /> <argument>%message.options%</argument> </service> </services> </container> <container xmlns="http://symfony-project.org/2.0/container"> <parameters> <parameter key="output.class">FancyOutput</parameter> <parameter key="message.options" type="collection"> <parameter key="with_newline">true</parameter> </parameter> </parameters> </container> $container = new Builder(); $loader = new FileXmlFileLoader($container); $loader->load('services.xml');
  73. 73. <services> <import resource="config.yml" class="SymfonyComponentsDependencyInjection LoaderYamlFileLoader" /> <service id="output" class="%output.class%" /> <service id="message" class="Message"> <argument type="service" id="output" /> <argument>%message.options%</argument> </service> </services> parameters: output.class: FancyOutput message.options: { with_newline: true } $container = new Builder(); $loader = new XmlFileLoader($container); $loader->load('services.xml');
  74. 74. Loaders & Dumpers •  IniFileLoader •  XmlFileLoader •  YamlFileLoader •  XmlDumper •  YamlDumper Make your container •  PhpDumper VERY fast •  GraphvizDumper
  75. 75. use SymfonyComponentsDependencyInjectionBuilder; use SymfonyComponentsDependencyInjectionReference; use SymfonyComponentsDependencyInjectionDumperXmlDumper; use SymfonyComponentsDependencyInjectionDumperYamlDumper; use SymfonyComponentsDependencyInjectionDumperPhpDumper; use SymfonyComponentsDependencyInjectionLoaderXmlFileLoader; use SymfonyComponentsDependencyInjectionLoaderYamlFileLoader; $container = new Builder(); $container->register('output', 'FancyOutput'); $container-> register('message', 'Message')-> setArguments(array(new Reference('output'), array('with_newline' => true))) ;
  76. 76. $dumper = new XmlDumper($container); file_put_contents(__DIR__.'/container.xml', $dumper->dump()); $loader = new XmlFileLoader($container); $loader->load(__DIR__.'/container.xml'); $dumper = new YamlDumper($container); file_put_contents(__DIR__.'/container.yml', $dumper->dump()); $loader = new YamlFileLoader($container); $loader->load(__DIR__.'/container.yml'); $dumper = new PhpDumper($container); echo $dumper->dump();
  77. 77. use SymfonyComponentsDependencyInjectionContainer; use SymfonyComponentsDependencyInjectionReference; use SymfonyComponentsDependencyInjectionParameter; class ProjectServiceContainer extends Container { protected $shared = array(); protected function getOutputService() { if (isset($this->shared['output'])) return $this->shared['output']; $instance = new FancyOutput(); return $this->shared['output'] = $instance; } protected function getMessageService() { if (isset($this->shared['message'])) return $this->shared['message']; $instance = new Message($this->getService('output'), array('with_newline' => true)); return $this->shared['message'] = $instance; } }
  78. 78. use SymfonyComponentsDependencyInjectionDumperGraphvizDumper; $dumper = new GraphvizDumper($container); echo $dumper->dump();
  79. 79. digraph sc { ratio="compress" node [fontsize="11" fontname="Arial" shape="record"]; edge [fontsize="9" fontname="Arial" color="grey" arrowhead="open" arrowsize="0.5"]; node_output [label="outputnFancyOutputn", shape=record, fillcolor="#eeeeee", style="filled"]; node_message [label="messagenMessagen", shape=record, fillcolor="#eeeeee", style="filled"]; node_service_container [label="service_containernSymfonyComponentsDependencyInjectionBuilder n", shape=record, fillcolor="#9999ff", style="filled"]; node_message -> node_output [label="" style="filled"]; }
  80. 80. Symfony Components Output Escaper
  81. 81. SymfonyComponentsOutputEscaper
  82. 82. Output Escaper •  Provides automatic XSS protection for your templates •  By wrapping template variables •  Works for –  strings –  arrays –  objects •  properties •  methods •  __call(), __get(), … •  Iterators, Coutables, … •  … •  Works for deep method calls
  83. 83. use SymfonyComponentsOutputEscaperEscaper; $title = 'Foo <br />'; echo Escaper::escape(ESC_SPECIALCHARS, $title);
  84. 84. use SymfonyComponentsOutputEscaperEscaper; $article = array( 'title' => 'Foo <br />', 'author' => array( 'name' => 'Fabien <br/>', ) ); $article = Escaper::escape(ESC_SPECIALCHARS, $article); echo $article['title']."n"; echo $article['author']['name']."n";
  85. 85. class Article { protected $title; protected $author; public $full_title; public property public function __construct($title, Author $author) { $this->title = $title; $this->full_title = $title; $this->author = $author; } public method public function getTitle() { return $this->title; } public method returning public function getAuthor() { return $this->author; } public function __get($key) { return $this->$key; } another object public function __call($method, $arguments) magic __get() { return $this->{'get'.$method}(); magic __call() } }
  86. 86. class Author { protected $name; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } }
  87. 87. use SymfonyComponentsOutputEscaperEscaper; $article = new Article( 'foo <br />', new Author('Fabien <br />') ); $article = Escaper::escape(ESC_SPECIALCHARS, $article); echo $article->getTitle()."n"; echo $article->getAuthor()->getName()."n"; echo $article->full_title."n"; echo $article->title."n"; echo $article->title()."n";
  88. 88. Escaping Strategy explicitly ask for raw data echo $article->getHtmlContent(ESC_RAW); echo $article->getTitle(ESC_JS); change the default escaping strategy
  89. 89. symfony-live.com with Matthew Weier O’Pheinney I will reveal the first alpha release of Symfony 2.0!
  90. 90. symfony-live.com with Matthew Weier O’Pheinney … with Matthew Weier O'Phinney as a special guest
  91. 91. Thank you! My slides on slideshare.com/fabpot with a bonus: How to use Symfony Components with ZF!
  92. 92. Sensio S.A. 92-98, boulevard Victor Hugo 92 115 Clichy Cedex FRANCE Tél. : +33 1 40 99 80 80 Contact Fabien Potencier fabien.potencier at sensio.com http://www.sensiolabs.com/ http://www.symfony-project.org/ http://fabien.potencier.org/
  93. 93. BO NUS How to use Symfony Components within a Zend Framework project?
  94. 94. Symfony components in a ZF project •  Symfony Components can make your ZF application better –  More configurable: symfony YAML –  More flexible: symfony Event Dispatcher –  Faster: symfony Dependency Injection –  More secure: symfony Output Escaper •  … and more fun of course
  95. 95. Symfony Components in a ZF project •  The examples in this presentation are just to get you started faster •  So, be creative with them. They open all kind of opportunities for your next Zend Framework project •  And please, give me feedback, and tell me what you do with the Symfony Components
  96. 96. Symfony Components Event Dispatcher
  97. 97. class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { public function run() { require_once '/path/to/sfEventDispatcher.php'; $dispatcher = new sfEventDispatcher(); $event = new sfEvent(null, 'bootstrap.prerun'); $dispatcher->notify($event); parent::run(); $event = new sfevent(null, 'bootstrap.postrun'); $dispatcher->notify($event); } }
  98. 98. Symfony Components Dependency Injection
  99. 99. class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { public function getContainer() { if (null === $this->_container) { $this->setContainer($this->_initContainer()); } return $this->_container; } protected function _initContainer() { require_once '/path/to/sfServiceContainerAutoloader.php'; sfServiceContainerAutoloader::register(); Example from Ben Eberlei (he rocks!): http://www.whitewashing.de/blog/articles/118 $container = new sfServiceContainerBuilder(); $loader = new sfServiceContainerLoaderFileXml($container); $loader->load(dirname(__FILE__).'/configs/resources.xml'); return $container; } }
  100. 100. <?xml version="1.0" ?> <container xmlns="http://symfony-project.org/2.0/container"> <parameters> <parameter key="mailer.username">foo</parameter> <parameter key="mailer.password">bar</parameter> <parameter key="mailer.class">Zend_Mail</parameter> </parameters> <services> <service id="mail.transport" class="Zend_Mail_Transport_Smtp" shared="false"> <argument>smtp.gmail.com</argument> <argument type="collection"> <argument key="auth">login</argument> <argument key="username">%mailer.username%</argument> <argument key="password">%mailer.password%</argument> <argument key="ssl">ssl</argument> <argument key="port">465</argument> </argument> </service> <service id="mailer" class="%mailer.class%"> <call method="setDefaultTransport"> <argument type="service" id="mail.transport" /> </call> </service> </services> </container>
  101. 101. parameters: mailer.username: foo mailer.password: bar mailer.class: Zend_Mail services: mail.transport: class: Zend_Mail_Transport_Smtp arguments: [smtp.gmail.com, { auth: login, username: %mailer.username%, password: %mailer.password%, ssl: ssl, port: 465 }] shared: false mailer: class: %mailer.class% calls: - [setDefaultTransport, [@mail.transport]]
  102. 102. class GuestbookController extends Zend_Controller_Action { public function indexAction() { $guestbook = new Default_Model_Guestbook(); $this->view->entries = $guestbook->fetchAll(); $container = $this->getInvokeArg('bootstrap')->getContainer(); $mailer = $container->mailer; } }
  103. 103. Dependency Injection Container •  By default in ZF, new resources can be added to the container but cannot be lazy-loaded –  All resources used by Zend_Application are loaded on every request •  By using symfony Service Container, the resources are lazy-loaded –  Instances and their dependencies are created the first time you get them •  Interesting for resources like DB
  104. 104. Symfony Components Output Escaper
  105. 105. require_once '/path/to/sfOutputEscaperAutoloader.php'; sfOutputEscaperAutoloader::register(); class My_View extends Zend_View { public function __set($key, $val) { if ('_' === substr($key, 0, 1)) { // throw an exception } $this->$key = sfOutputEscaper::escape(array($this, 'escape'), $val); } }
  106. 106. <dl> <?php foreach ($this->entries as $entry): ?> <dt><?php echo $this->escape($entry->email) ?></dt> <dd><?php echo $this->escape($entry->comment) ?></dd> <?php endforeach ?> </dl> <dl> <?php foreach ($this->entries as $entry): ?> <dt><?php echo $entry->email ?></dt> <dd><?php echo $entry->comment ?></dd> <?php endforeach ?> </dl> <?php echo $entry->getRawValue()->comment ?> <?php echo $entry->getComment(ESC_RAW) ?>
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×