SlideShare a Scribd company logo
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 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
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
Fabien Potencier

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

•  Follow me on Twitter: @fabpot

•  Fork my code on Github: http://github.com/fabpot/
How many of you use
symfony?
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
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 Forms, Routing, Cache, YAML, ORMs, …

       sfRequest   sfRouting     sfLogger   sfI18N    sfUser      sfResponse




  sfYAML   sfDatabase   sfForm    sfEventDispatcher   sfStorage     sfCache    sfOutputEscaper



               sfValidator     sfWidget                            sfCoreAutoload
                                                                                     platform
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 dependencies
•    Release cycle independent of Symfony, the framework
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
Symfony Components




        They have been migrated to PHP 5.3

http://svn.symfony-project.com/branches/2.0/lib/Symfony/Components
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/
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
Symfony Components
•  Coming soon…
  –  Request Handler
  –  Form
  –  Command Line Tools
  –  Routing
  –  Security
  –  Cache
  –  Debug
  –  …
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 the same feature set and
   work exactly in the same way, except:
   –  The autoloader
   –  The class names
Symfony 2.0 Namespaces


SymfonyComponents

SymfonyFoundation

SymfonyFramework
Autoloader


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

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

$loader = new SymfonyFoundationClassLoader('Symfony', $path);

$loader->register();
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
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 :)
Symfony Components
YAML
SymfonyComponentsYAML
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
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)
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]
   bar: { foo: bar }
   foobar: { foo: [foo, bar] }
EOF
);

// Dump YAML
echo YAML::dump($config);
Symfony Components
Event Dispatcher
SymfonyComponentsEventDispatcher
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
   –  …
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
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: hook, listener, event, subject, …
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);
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)
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
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, …
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();
    }
}
$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();
Notifiers              Dispatcher                Listeners

                                                       listener connects
1                                                to ‘response.filter_content’

       Response notifies             Calls                 listener
2   ‘response.filter_content’    all listeners            is called
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
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
Notifiers            Dispatcher




  Response notifies        Calls
response.filter_content   nothing

                                    very small overhead
Symfony Components
Templating
SymfonyComponentsTemplating
Symfony Templating


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


•  Can work with Template Engines (Smarty, Twig, …)
New Templating Framework
•  4 sub-components
   –  Template Engine
   –  Template Renderers
   –  Template Loaders
   –  Template Storages
use SymfonyComponentsTemplatingEngine;
use SymfonyComponentsTemplatingLoaderFilesystemLoader;

$loader = new FilesystemLoader(
   '/path/to/templates/%name%.php'
);

$t = new Engine($loader);

echo $t->render('index', array('name' => 'Fabien'));
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');
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(),
));
Template Embedding



Hello <?php echo $name ?>

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

<?php $this->render('smarty:embedded') ?>
Template Inheritance

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

Hello <?php echo $name ?>

<html>
  <head>
  </head>
  <body>
    <?php $this->output('content') ?>
  </body>
</html>
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() ?>
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 into fields. »

http://www.picocontainer.org/injection.html
class Message
{
  public function __construct()
  {
    $this->output = new Output();
  }
}




class Message
{
  public function __construct(OutputInterface $output)
  {
    $this->output = $output;
  }
}
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" : ''));
    }
}
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);
  }
}
DI Hello World example



$output = new FancyOutput();
$message = new Message($output, array('with_newline' => true));
$message->say('Hello World');
A DI container facilitates
objects description and object relationships,
    configures and instantiates objects
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!');
$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
$message = $container->message;


                    is roughly equivalent to

                  $output = new FancyOutput();
$message = new Message($output, array('with_newline' => true));!
$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');
$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');
<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');
<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');
<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');
Loaders & Dumpers
•  IniFileLoader
•  XmlFileLoader
•  YamlFileLoader

•    XmlDumper
•    YamlDumper
                    Make your container
•    PhpDumper      VERY fast
•    GraphvizDumper
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)))
;
$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();
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;
    }
}
use SymfonyComponentsDependencyInjectionDumperGraphvizDumper;

$dumper = new GraphvizDumper($container);
echo $dumper->dump();
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"];
}
Symfony Components 2.0 on PHP 5.3
Symfony Components 2.0 on PHP 5.3
Symfony Components
Output Escaper
SymfonyComponentsOutputEscaper
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
use SymfonyComponentsOutputEscaperEscaper;

$title = 'Foo <br />';

echo Escaper::escape(ESC_SPECIALCHARS, $title);
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";
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()
    }
}
class Author
{
  protected $name;

    public function __construct($name) { $this->name = $name; }
    public function getName() { return $this->name; }
}
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";
Escaping Strategy

                                      explicitly ask
                                      for raw data

echo $article->getHtmlContent(ESC_RAW);



echo $article->getTitle(ESC_JS);

                        change the default
                        escaping strategy
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 80

               Contact
           Fabien Potencier
    fabien.potencier at sensio.com




  http://www.sensiolabs.com/
http://www.symfony-project.org/
 http://fabien.potencier.org/
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: symfony YAML
   –  More flexible: symfony Event Dispatcher
   –  Faster: symfony Dependency Injection
   –  More secure: symfony Output Escaper
•  … and more fun of course
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
Symfony Components
Event Dispatcher
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);
    }
}
Symfony Components
Dependency Injection
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;
    }
}
<?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>
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]]
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;
    }
}
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
Symfony Components
Output Escaper
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);
    }
}
<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) ?>
Ad

More Related Content

What's hot (17)

Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!
Ryan Weaver
 
The Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaThe Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony Barcelona
Matthias Noback
 
Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2
Hugo Hamon
 
TWIG: the flexible, fast and secure template language for PHP
TWIG: the flexible, fast and secure template language for PHPTWIG: the flexible, fast and secure template language for PHP
TWIG: the flexible, fast and secure template language for PHP
Cesare D'Amico
 
PHP 7 Crash Course - php[world] 2015
PHP 7 Crash Course - php[world] 2015PHP 7 Crash Course - php[world] 2015
PHP 7 Crash Course - php[world] 2015
Colin O'Dell
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHP
Wim Godden
 
Introduction to web and php mysql
Introduction to web and php mysqlIntroduction to web and php mysql
Introduction to web and php mysql
Programmer Blog
 
Php my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.netPhp my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.net
Programmer Blog
 
Love Twig
Love TwigLove Twig
Love Twig
Antonio Peric-Mazar
 
Ecto and Phoenix: Doing Web With Elixir
Ecto and Phoenix: Doing Web With ElixirEcto and Phoenix: Doing Web With Elixir
Ecto and Phoenix: Doing Web With Elixir
Yurii Bodarev
 
Sphinx: Leveraging Scalable Search in Drupal
Sphinx: Leveraging Scalable Search in DrupalSphinx: Leveraging Scalable Search in Drupal
Sphinx: Leveraging Scalable Search in Drupal
elliando dias
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
Jussi Pohjolainen
 
Twig, the flexible, fast, and secure template language for PHP
Twig, the flexible, fast, and secure template language for PHPTwig, the flexible, fast, and secure template language for PHP
Twig, the flexible, fast, and secure template language for PHP
Fabien Potencier
 
Building Cloud Castles
Building Cloud CastlesBuilding Cloud Castles
Building Cloud Castles
Ben Scofield
 
Flask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuthFlask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuth
Eueung Mulyana
 
O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010
O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010
O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010
Plataformatec
 
Silex: From nothing to an API
Silex: From nothing to an APISilex: From nothing to an API
Silex: From nothing to an API
chrisdkemper
 
Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!Twig: Friendly Curly Braces Invade Your Templates!
Twig: Friendly Curly Braces Invade Your Templates!
Ryan Weaver
 
The Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaThe Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony Barcelona
Matthias Noback
 
Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2
Hugo Hamon
 
TWIG: the flexible, fast and secure template language for PHP
TWIG: the flexible, fast and secure template language for PHPTWIG: the flexible, fast and secure template language for PHP
TWIG: the flexible, fast and secure template language for PHP
Cesare D'Amico
 
PHP 7 Crash Course - php[world] 2015
PHP 7 Crash Course - php[world] 2015PHP 7 Crash Course - php[world] 2015
PHP 7 Crash Course - php[world] 2015
Colin O'Dell
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHP
Wim Godden
 
Introduction to web and php mysql
Introduction to web and php mysqlIntroduction to web and php mysql
Introduction to web and php mysql
Programmer Blog
 
Php my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.netPhp my sql - functions - arrays - tutorial - programmerblog.net
Php my sql - functions - arrays - tutorial - programmerblog.net
Programmer Blog
 
Ecto and Phoenix: Doing Web With Elixir
Ecto and Phoenix: Doing Web With ElixirEcto and Phoenix: Doing Web With Elixir
Ecto and Phoenix: Doing Web With Elixir
Yurii Bodarev
 
Sphinx: Leveraging Scalable Search in Drupal
Sphinx: Leveraging Scalable Search in DrupalSphinx: Leveraging Scalable Search in Drupal
Sphinx: Leveraging Scalable Search in Drupal
elliando dias
 
Twig, the flexible, fast, and secure template language for PHP
Twig, the flexible, fast, and secure template language for PHPTwig, the flexible, fast, and secure template language for PHP
Twig, the flexible, fast, and secure template language for PHP
Fabien Potencier
 
Building Cloud Castles
Building Cloud CastlesBuilding Cloud Castles
Building Cloud Castles
Ben Scofield
 
Flask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuthFlask RESTful Flask HTTPAuth
Flask RESTful Flask HTTPAuth
Eueung Mulyana
 
O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010
O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010
O que há de novo no Rails 3 - Ruby on Rails no Mundo Real - 23may2010
Plataformatec
 
Silex: From nothing to an API
Silex: From nothing to an APISilex: From nothing to an API
Silex: From nothing to an API
chrisdkemper
 

Viewers also liked (10)

Debugging and Profiling Symfony Apps
Debugging and Profiling Symfony AppsDebugging and Profiling Symfony Apps
Debugging and Profiling Symfony Apps
Alvaro Videla
 
symfony Live 2010 - Using Doctrine Migrations
symfony Live 2010 -  Using Doctrine Migrationssymfony Live 2010 -  Using Doctrine Migrations
symfony Live 2010 - Using Doctrine Migrations
D
 
Symfony Components
Symfony ComponentsSymfony Components
Symfony Components
Fabien Potencier
 
Dockerizing Symfony Applications - Symfony Live Berlin 2014
Dockerizing Symfony Applications - Symfony Live Berlin 2014Dockerizing Symfony Applications - Symfony Live Berlin 2014
Dockerizing Symfony Applications - Symfony Live Berlin 2014
D
 
Tomáš Votruba - Hot news! PHP 7.0, 7.1 a Symfony 3.1, 3.2 a 3.3
Tomáš Votruba - Hot news! PHP 7.0, 7.1 a Symfony 3.1, 3.2 a 3.3Tomáš Votruba - Hot news! PHP 7.0, 7.1 a Symfony 3.1, 3.2 a 3.3
Tomáš Votruba - Hot news! PHP 7.0, 7.1 a Symfony 3.1, 3.2 a 3.3
Tomáš Votruba
 
The Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsThe Wonderful World of Symfony Components
The Wonderful World of Symfony Components
Ryan Weaver
 
30 Symfony Best Practices
30 Symfony Best Practices30 Symfony Best Practices
30 Symfony Best Practices
Nicolas Perriault
 
Doctrine 2 - Not The Same Old Php Orm
Doctrine 2 - Not The Same Old Php OrmDoctrine 2 - Not The Same Old Php Orm
Doctrine 2 - Not The Same Old Php Orm
Jonathan Wage
 
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
Javier Eguiluz
 
Symfony tips and tricks
Symfony tips and tricksSymfony tips and tricks
Symfony tips and tricks
Javier Eguiluz
 
Debugging and Profiling Symfony Apps
Debugging and Profiling Symfony AppsDebugging and Profiling Symfony Apps
Debugging and Profiling Symfony Apps
Alvaro Videla
 
symfony Live 2010 - Using Doctrine Migrations
symfony Live 2010 -  Using Doctrine Migrationssymfony Live 2010 -  Using Doctrine Migrations
symfony Live 2010 - Using Doctrine Migrations
D
 
Dockerizing Symfony Applications - Symfony Live Berlin 2014
Dockerizing Symfony Applications - Symfony Live Berlin 2014Dockerizing Symfony Applications - Symfony Live Berlin 2014
Dockerizing Symfony Applications - Symfony Live Berlin 2014
D
 
Tomáš Votruba - Hot news! PHP 7.0, 7.1 a Symfony 3.1, 3.2 a 3.3
Tomáš Votruba - Hot news! PHP 7.0, 7.1 a Symfony 3.1, 3.2 a 3.3Tomáš Votruba - Hot news! PHP 7.0, 7.1 a Symfony 3.1, 3.2 a 3.3
Tomáš Votruba - Hot news! PHP 7.0, 7.1 a Symfony 3.1, 3.2 a 3.3
Tomáš Votruba
 
The Wonderful World of Symfony Components
The Wonderful World of Symfony ComponentsThe Wonderful World of Symfony Components
The Wonderful World of Symfony Components
Ryan Weaver
 
Doctrine 2 - Not The Same Old Php Orm
Doctrine 2 - Not The Same Old Php OrmDoctrine 2 - Not The Same Old Php Orm
Doctrine 2 - Not The Same Old Php Orm
Jonathan Wage
 
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)New Symfony Tips & Tricks (SymfonyCon Paris 2015)
New Symfony Tips & Tricks (SymfonyCon Paris 2015)
Javier Eguiluz
 
Symfony tips and tricks
Symfony tips and tricksSymfony tips and tricks
Symfony tips and tricks
Javier Eguiluz
 
Ad

Similar to Symfony Components 2.0 on PHP 5.3 (20)

Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3Symfony 2.0 on PHP 5.3
Symfony 2.0 on PHP 5.3
Fabien Potencier
 
Hands-on with the Symfony2 Framework
Hands-on with the Symfony2 FrameworkHands-on with the Symfony2 Framework
Hands-on with the Symfony2 Framework
Ryan Weaver
 
Symfony Live 09 Symfony 2
Symfony Live 09 Symfony 2Symfony Live 09 Symfony 2
Symfony Live 09 Symfony 2
narkoza
 
25 Intro to Symfony #burningkeyboards
25 Intro to Symfony #burningkeyboards25 Intro to Symfony #burningkeyboards
25 Intro to Symfony #burningkeyboards
Denis Ristic
 
Fabien Potencier "Symfony 4 in action"
Fabien Potencier "Symfony 4 in action"Fabien Potencier "Symfony 4 in action"
Fabien Potencier "Symfony 4 in action"
Fwdays
 
Symfony 4: A new way to develop applications #ipc19
Symfony 4: A new way to develop applications #ipc19Symfony 4: A new way to develop applications #ipc19
Symfony 4: A new way to develop applications #ipc19
Antonio Peric-Mazar
 
Symfony 4: A new way to develop applications #phpsrb
 Symfony 4: A new way to develop applications #phpsrb Symfony 4: A new way to develop applications #phpsrb
Symfony 4: A new way to develop applications #phpsrb
Antonio Peric-Mazar
 
PHP 5.3 in practice
PHP 5.3 in practicePHP 5.3 in practice
PHP 5.3 in practice
Fabien Potencier
 
Unit testing symfony plugins with php unit
Unit testing symfony plugins with php unitUnit testing symfony plugins with php unit
Unit testing symfony plugins with php unit
Christian Schaefer
 
How Symfony changed my life (#SfPot, Paris, 19th November 2015)
How Symfony changed my life (#SfPot, Paris, 19th November 2015)How Symfony changed my life (#SfPot, Paris, 19th November 2015)
How Symfony changed my life (#SfPot, Paris, 19th November 2015)
Matthias Noback
 
Nice performance using Sf2 cache wrapping Sf1 application
Nice performance using Sf2 cache wrapping Sf1 applicationNice performance using Sf2 cache wrapping Sf1 application
Nice performance using Sf2 cache wrapping Sf1 application
Marc Weistroff
 
Simplify your professional web development with symfony
Simplify your professional web development with symfonySimplify your professional web development with symfony
Simplify your professional web development with symfony
Francois Zaninotto
 
Creating your own framework on top of Symfony2 Components
Creating your own framework on top of Symfony2 ComponentsCreating your own framework on top of Symfony2 Components
Creating your own framework on top of Symfony2 Components
Deepak Chandani
 
How Symfony Changed My Life
How Symfony Changed My LifeHow Symfony Changed My Life
How Symfony Changed My Life
Matthias Noback
 
Symfony Components
Symfony ComponentsSymfony Components
Symfony Components
guest0de7c2
 
Ran Mizrahi - Symfony2 meets Drupal8
Ran Mizrahi - Symfony2 meets Drupal8Ran Mizrahi - Symfony2 meets Drupal8
Ran Mizrahi - Symfony2 meets Drupal8
Ran Mizrahi
 
симфони это не страшно
симфони   это не страшносимфони   это не страшно
симфони это не страшно
DrupalCamp Kyiv Рысь
 
Symfony2 revealed
Symfony2 revealedSymfony2 revealed
Symfony2 revealed
Fabien Potencier
 
Automating Security Response with Serverless
Automating Security Response with ServerlessAutomating Security Response with Serverless
Automating Security Response with Serverless
Michael Ducy
 
Dependency management with Composer
Dependency management with ComposerDependency management with Composer
Dependency management with Composer
Jason Grimes
 
Hands-on with the Symfony2 Framework
Hands-on with the Symfony2 FrameworkHands-on with the Symfony2 Framework
Hands-on with the Symfony2 Framework
Ryan Weaver
 
Symfony Live 09 Symfony 2
Symfony Live 09 Symfony 2Symfony Live 09 Symfony 2
Symfony Live 09 Symfony 2
narkoza
 
25 Intro to Symfony #burningkeyboards
25 Intro to Symfony #burningkeyboards25 Intro to Symfony #burningkeyboards
25 Intro to Symfony #burningkeyboards
Denis Ristic
 
Fabien Potencier "Symfony 4 in action"
Fabien Potencier "Symfony 4 in action"Fabien Potencier "Symfony 4 in action"
Fabien Potencier "Symfony 4 in action"
Fwdays
 
Symfony 4: A new way to develop applications #ipc19
Symfony 4: A new way to develop applications #ipc19Symfony 4: A new way to develop applications #ipc19
Symfony 4: A new way to develop applications #ipc19
Antonio Peric-Mazar
 
Symfony 4: A new way to develop applications #phpsrb
 Symfony 4: A new way to develop applications #phpsrb Symfony 4: A new way to develop applications #phpsrb
Symfony 4: A new way to develop applications #phpsrb
Antonio Peric-Mazar
 
Unit testing symfony plugins with php unit
Unit testing symfony plugins with php unitUnit testing symfony plugins with php unit
Unit testing symfony plugins with php unit
Christian Schaefer
 
How Symfony changed my life (#SfPot, Paris, 19th November 2015)
How Symfony changed my life (#SfPot, Paris, 19th November 2015)How Symfony changed my life (#SfPot, Paris, 19th November 2015)
How Symfony changed my life (#SfPot, Paris, 19th November 2015)
Matthias Noback
 
Nice performance using Sf2 cache wrapping Sf1 application
Nice performance using Sf2 cache wrapping Sf1 applicationNice performance using Sf2 cache wrapping Sf1 application
Nice performance using Sf2 cache wrapping Sf1 application
Marc Weistroff
 
Simplify your professional web development with symfony
Simplify your professional web development with symfonySimplify your professional web development with symfony
Simplify your professional web development with symfony
Francois Zaninotto
 
Creating your own framework on top of Symfony2 Components
Creating your own framework on top of Symfony2 ComponentsCreating your own framework on top of Symfony2 Components
Creating your own framework on top of Symfony2 Components
Deepak Chandani
 
How Symfony Changed My Life
How Symfony Changed My LifeHow Symfony Changed My Life
How Symfony Changed My Life
Matthias Noback
 
Symfony Components
Symfony ComponentsSymfony Components
Symfony Components
guest0de7c2
 
Ran Mizrahi - Symfony2 meets Drupal8
Ran Mizrahi - Symfony2 meets Drupal8Ran Mizrahi - Symfony2 meets Drupal8
Ran Mizrahi - Symfony2 meets Drupal8
Ran Mizrahi
 
Automating Security Response with Serverless
Automating Security Response with ServerlessAutomating Security Response with Serverless
Automating Security Response with Serverless
Michael Ducy
 
Dependency management with Composer
Dependency management with ComposerDependency management with Composer
Dependency management with Composer
Jason Grimes
 
Ad

More from Fabien Potencier (20)

Varnish
VarnishVarnish
Varnish
Fabien Potencier
 
Look beyond PHP
Look beyond PHPLook beyond PHP
Look beyond PHP
Fabien Potencier
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4
Fabien Potencier
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010
Fabien Potencier
 
Caching on the Edge
Caching on the EdgeCaching on the Edge
Caching on the Edge
Fabien Potencier
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
Fabien Potencier
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010
Fabien Potencier
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
Fabien Potencier
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010
Fabien Potencier
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
Fabien Potencier
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
Fabien Potencier
 
Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010
Fabien Potencier
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
Fabien Potencier
 
Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Caching on the Edge with Symfony2
Caching on the Edge with Symfony2
Fabien Potencier
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2
Fabien Potencier
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
Fabien Potencier
 
Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010
Fabien Potencier
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
Fabien Potencier
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3
Fabien Potencier
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
Fabien Potencier
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4
Fabien Potencier
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010
Fabien Potencier
 
Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3Design patterns revisited with PHP 5.3
Design patterns revisited with PHP 5.3
Fabien Potencier
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010
Fabien Potencier
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010
Fabien Potencier
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
Fabien Potencier
 
Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Caching on the Edge with Symfony2
Caching on the Edge with Symfony2
Fabien Potencier
 
Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2
Fabien Potencier
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
Fabien Potencier
 
Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010
Fabien Potencier
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3
Fabien Potencier
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
Fabien Potencier
 

Recently uploaded (20)

UiPath Agentic Automation: Community Developer Opportunities
UiPath Agentic Automation: Community Developer OpportunitiesUiPath Agentic Automation: Community Developer Opportunities
UiPath Agentic Automation: Community Developer Opportunities
DianaGray10
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
AI You Can Trust: The Critical Role of Governance and Quality.pdf
AI You Can Trust: The Critical Role of Governance and Quality.pdfAI You Can Trust: The Critical Role of Governance and Quality.pdf
AI You Can Trust: The Critical Role of Governance and Quality.pdf
Precisely
 
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
BookNet Canada
 
UiPath Agentic Automation: Community Developer Opportunities
UiPath Agentic Automation: Community Developer OpportunitiesUiPath Agentic Automation: Community Developer Opportunities
UiPath Agentic Automation: Community Developer Opportunities
DianaGray10
 
Unlocking Generative AI in your Web Apps
Unlocking Generative AI in your Web AppsUnlocking Generative AI in your Web Apps
Unlocking Generative AI in your Web Apps
Maximiliano Firtman
 
Connect and Protect: Networks and Network Security
Connect and Protect: Networks and Network SecurityConnect and Protect: Networks and Network Security
Connect and Protect: Networks and Network Security
VICTOR MAESTRE RAMIREZ
 
Financial Services Technology Summit 2025
Financial Services Technology Summit 2025Financial Services Technology Summit 2025
Financial Services Technology Summit 2025
Ray Bugg
 
Zilliz Cloud Monthly Technical Review: May 2025
Zilliz Cloud Monthly Technical Review: May 2025Zilliz Cloud Monthly Technical Review: May 2025
Zilliz Cloud Monthly Technical Review: May 2025
Zilliz
 
AsyncAPI v3 : Streamlining Event-Driven API Design
AsyncAPI v3 : Streamlining Event-Driven API DesignAsyncAPI v3 : Streamlining Event-Driven API Design
AsyncAPI v3 : Streamlining Event-Driven API Design
leonid54
 
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptxReimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
John Moore
 
AI 3-in-1: Agents, RAG, and Local Models - Brent Laster
AI 3-in-1: Agents, RAG, and Local Models - Brent LasterAI 3-in-1: Agents, RAG, and Local Models - Brent Laster
AI 3-in-1: Agents, RAG, and Local Models - Brent Laster
All Things Open
 
Hybridize Functions: A Tool for Automatically Refactoring Imperative Deep Lea...
Hybridize Functions: A Tool for Automatically Refactoring Imperative Deep Lea...Hybridize Functions: A Tool for Automatically Refactoring Imperative Deep Lea...
Hybridize Functions: A Tool for Automatically Refactoring Imperative Deep Lea...
Raffi Khatchadourian
 
The Microsoft Excel Parts Presentation.pdf
The Microsoft Excel Parts Presentation.pdfThe Microsoft Excel Parts Presentation.pdf
The Microsoft Excel Parts Presentation.pdf
YvonneRoseEranista
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
GyrusAI - Broadcasting & Streaming Applications Driven by AI and ML
GyrusAI - Broadcasting & Streaming Applications Driven by AI and MLGyrusAI - Broadcasting & Streaming Applications Driven by AI and ML
GyrusAI - Broadcasting & Streaming Applications Driven by AI and ML
Gyrus AI
 
Viam product demo_ Deploying and scaling AI with hardware.pdf
Viam product demo_ Deploying and scaling AI with hardware.pdfViam product demo_ Deploying and scaling AI with hardware.pdf
Viam product demo_ Deploying and scaling AI with hardware.pdf
camilalamoratta
 
Vibe Coding_ Develop a web application using AI (1).pdf
Vibe Coding_ Develop a web application using AI (1).pdfVibe Coding_ Develop a web application using AI (1).pdf
Vibe Coding_ Develop a web application using AI (1).pdf
Baiju Muthukadan
 
The Changing Compliance Landscape in 2025.pdf
The Changing Compliance Landscape in 2025.pdfThe Changing Compliance Landscape in 2025.pdf
The Changing Compliance Landscape in 2025.pdf
Precisely
 
Web and Graphics Designing Training in Rajpura
Web and Graphics Designing Training in RajpuraWeb and Graphics Designing Training in Rajpura
Web and Graphics Designing Training in Rajpura
Erginous Technology
 
UiPath Agentic Automation: Community Developer Opportunities
UiPath Agentic Automation: Community Developer OpportunitiesUiPath Agentic Automation: Community Developer Opportunities
UiPath Agentic Automation: Community Developer Opportunities
DianaGray10
 
Cybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure ADCybersecurity Identity and Access Solutions using Azure AD
Cybersecurity Identity and Access Solutions using Azure AD
VICTOR MAESTRE RAMIREZ
 
AI You Can Trust: The Critical Role of Governance and Quality.pdf
AI You Can Trust: The Critical Role of Governance and Quality.pdfAI You Can Trust: The Critical Role of Governance and Quality.pdf
AI You Can Trust: The Critical Role of Governance and Quality.pdf
Precisely
 
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
Transcript: #StandardsGoals for 2025: Standards & certification roundup - Tec...
BookNet Canada
 
UiPath Agentic Automation: Community Developer Opportunities
UiPath Agentic Automation: Community Developer OpportunitiesUiPath Agentic Automation: Community Developer Opportunities
UiPath Agentic Automation: Community Developer Opportunities
DianaGray10
 
Unlocking Generative AI in your Web Apps
Unlocking Generative AI in your Web AppsUnlocking Generative AI in your Web Apps
Unlocking Generative AI in your Web Apps
Maximiliano Firtman
 
Connect and Protect: Networks and Network Security
Connect and Protect: Networks and Network SecurityConnect and Protect: Networks and Network Security
Connect and Protect: Networks and Network Security
VICTOR MAESTRE RAMIREZ
 
Financial Services Technology Summit 2025
Financial Services Technology Summit 2025Financial Services Technology Summit 2025
Financial Services Technology Summit 2025
Ray Bugg
 
Zilliz Cloud Monthly Technical Review: May 2025
Zilliz Cloud Monthly Technical Review: May 2025Zilliz Cloud Monthly Technical Review: May 2025
Zilliz Cloud Monthly Technical Review: May 2025
Zilliz
 
AsyncAPI v3 : Streamlining Event-Driven API Design
AsyncAPI v3 : Streamlining Event-Driven API DesignAsyncAPI v3 : Streamlining Event-Driven API Design
AsyncAPI v3 : Streamlining Event-Driven API Design
leonid54
 
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptxReimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
Reimagine How You and Your Team Work with Microsoft 365 Copilot.pptx
John Moore
 
AI 3-in-1: Agents, RAG, and Local Models - Brent Laster
AI 3-in-1: Agents, RAG, and Local Models - Brent LasterAI 3-in-1: Agents, RAG, and Local Models - Brent Laster
AI 3-in-1: Agents, RAG, and Local Models - Brent Laster
All Things Open
 
Hybridize Functions: A Tool for Automatically Refactoring Imperative Deep Lea...
Hybridize Functions: A Tool for Automatically Refactoring Imperative Deep Lea...Hybridize Functions: A Tool for Automatically Refactoring Imperative Deep Lea...
Hybridize Functions: A Tool for Automatically Refactoring Imperative Deep Lea...
Raffi Khatchadourian
 
The Microsoft Excel Parts Presentation.pdf
The Microsoft Excel Parts Presentation.pdfThe Microsoft Excel Parts Presentation.pdf
The Microsoft Excel Parts Presentation.pdf
YvonneRoseEranista
 
Generative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in BusinessGenerative Artificial Intelligence (GenAI) in Business
Generative Artificial Intelligence (GenAI) in Business
Dr. Tathagat Varma
 
GyrusAI - Broadcasting & Streaming Applications Driven by AI and ML
GyrusAI - Broadcasting & Streaming Applications Driven by AI and MLGyrusAI - Broadcasting & Streaming Applications Driven by AI and ML
GyrusAI - Broadcasting & Streaming Applications Driven by AI and ML
Gyrus AI
 
Viam product demo_ Deploying and scaling AI with hardware.pdf
Viam product demo_ Deploying and scaling AI with hardware.pdfViam product demo_ Deploying and scaling AI with hardware.pdf
Viam product demo_ Deploying and scaling AI with hardware.pdf
camilalamoratta
 
Vibe Coding_ Develop a web application using AI (1).pdf
Vibe Coding_ Develop a web application using AI (1).pdfVibe Coding_ Develop a web application using AI (1).pdf
Vibe Coding_ Develop a web application using AI (1).pdf
Baiju Muthukadan
 
The Changing Compliance Landscape in 2025.pdf
The Changing Compliance Landscape in 2025.pdfThe Changing Compliance Landscape in 2025.pdf
The Changing Compliance Landscape in 2025.pdf
Precisely
 
Web and Graphics Designing Training in Rajpura
Web and Graphics Designing Training in RajpuraWeb and Graphics Designing Training in Rajpura
Web and Graphics Designing Training in Rajpura
Erginous Technology
 

Symfony Components 2.0 on PHP 5.3

  • 1. Symfony Components What's in for you? Fabien Potencier
  • 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. 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. 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. How many of you use symfony?
  • 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. But wait, symfony is a monolithic framework, right?
  • 8. A bit of history symfony 1.0 (January 2007) started as a glue between existing Open-Source libraries
  • 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. The symfony (1.2/1.3/1.4) MVC framework is based on a set of cohesive but decoupled classes, the symfony components
  • 11. Symfony Components •  Announced in May 2009 •  Standalone components •  Packaged individually •  No dependencies •  Release cycle independent of Symfony, the framework
  • 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. Symfony Components They have been migrated to PHP 5.3 http://svn.symfony-project.com/branches/2.0/lib/Symfony/Components
  • 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. 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. Symfony Components •  Coming soon… –  Request Handler –  Form –  Command Line Tools –  Routing –  Security –  Cache –  Debug –  …
  • 17. Symfony Components Using them in your project
  • 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
  • 20. Autoloader $path = '/path/to/SymfonyComponents/lib'; require_once $path.'/Symfony/Foundation/ClassLoader.php'; $loader = new SymfonyFoundationClassLoader('Symfony', $path); $loader->register();
  • 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. 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 :)
  • 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. 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. config: key: value foo: [foo, bar] bar: { foo: bar } foobar: { foo: [foo, bar] }
  • 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);
  • 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. 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. An event dispatcher is a central object that manages connections between subjects and observers
  • 34. It is a powerful mechanism to extend applications without having to change the objects themselves Associated words: hook, listener, event, subject, …
  • 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. 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. 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. 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. 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. $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. Notifiers Dispatcher Listeners listener connects 1 to ‘response.filter_content’ Response notifies Calls listener 2 ‘response.filter_content’ all listeners is called
  • 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. 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. Notifiers Dispatcher Response notifies Calls response.filter_content nothing very small overhead
  • 47. Symfony Templating •  Thin layer on top of PHP that adds some template-oriented features •  Can work with Template Engines (Smarty, Twig, …)
  • 48. New Templating Framework •  4 sub-components –  Template Engine –  Template Renderers –  Template Loaders –  Template Storages
  • 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. 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. 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. Template Embedding Hello <?php echo $name ?> <?php $this->render('embedded', array('name' => $name)) ?> <?php $this->render('smarty:embedded') ?>
  • 53. Template Inheritance <?php $this->extend('layout') ?> Hello <?php echo $name ?> <html> <head> </head> <body> <?php $this->output('content') ?> </body> </html>
  • 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. Template Multiple Inheritance A layout can be decorated by another layout Each layout can override slots
  • 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. class Message { public function __construct() { $this->output = new Output(); } } class Message { public function __construct(OutputInterface $output) { $this->output = $output; } }
  • 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. 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. DI Hello World example $output = new FancyOutput(); $message = new Message($output, array('with_newline' => true)); $message->say('Hello World');
  • 65. A DI container facilitates objects description and object relationships, configures and instantiates objects
  • 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. $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. $message = $container->message; is roughly equivalent to $output = new FancyOutput(); $message = new Message($output, array('with_newline' => true));!
  • 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. $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. <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. <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. <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. Loaders & Dumpers •  IniFileLoader •  XmlFileLoader •  YamlFileLoader •  XmlDumper •  YamlDumper Make your container •  PhpDumper VERY fast •  GraphvizDumper
  • 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. $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. 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. use SymfonyComponentsDependencyInjectionDumperGraphvizDumper; $dumper = new GraphvizDumper($container); echo $dumper->dump();
  • 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"]; }
  • 84. 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
  • 85. use SymfonyComponentsOutputEscaperEscaper; $title = 'Foo <br />'; echo Escaper::escape(ESC_SPECIALCHARS, $title);
  • 86. 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";
  • 87. 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() } }
  • 88. class Author { protected $name; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } }
  • 89. 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";
  • 90. Escaping Strategy explicitly ask for raw data echo $article->getHtmlContent(ESC_RAW); echo $article->getTitle(ESC_JS); change the default escaping strategy
  • 91. symfony-live.com with Matthew Weier O’Pheinney I will reveal the first alpha release of Symfony 2.0!
  • 92. symfony-live.com with Matthew Weier O’Pheinney … with Matthew Weier O'Phinney as a special guest
  • 93. Thank you! My slides on slideshare.com/fabpot with a bonus: How to use Symfony Components with ZF!
  • 94. 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/
  • 95. BO NUS How to use Symfony Components within a Zend Framework project?
  • 96. 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
  • 97. 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
  • 99. 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); } }
  • 101. 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; } }
  • 102. <?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>
  • 103. 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]]
  • 104. 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; } }
  • 105. 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
  • 107. 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); } }
  • 108. <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) ?>