Symfony Components 2.0 on PHP 5.3

108
Symfony Components What's in for you? Fabien Potencier

Transcript of Symfony Components 2.0 on PHP 5.3

Page 1: Symfony Components 2.0 on PHP 5.3

Symfony Components What's in for you?

Fabien Potencier

Page 2: Symfony Components 2.0 on PHP 5.3

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

Page 3: Symfony Components 2.0 on PHP 5.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

Page 4: Symfony Components 2.0 on PHP 5.3

Fabien Potencier

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

•  Follow me on Twitter: @fabpot

•  Fork my code on Github: http://github.com/fabpot/

Page 5: Symfony Components 2.0 on PHP 5.3

How many of you use symfony?

Page 6: Symfony Components 2.0 on PHP 5.3

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

Page 7: Symfony Components 2.0 on PHP 5.3

But wait, symfony is a monolithic framework, right?

Page 8: Symfony Components 2.0 on PHP 5.3

A bit of history

symfony 1.0 (January 2007) started as a glue between existing Open-Source libraries

Page 9: Symfony Components 2.0 on PHP 5.3

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, …

platform

sfEventDispatcher

sfRequest sfResponsesfRouting sfUser

sfStorage sfCache

sfI18N

sfForm

sfLogger

sfDatabase

sfValidator sfWidget

sfYAML

sfCoreAutoload

sfOutputEscaper

Page 10: Symfony Components 2.0 on PHP 5.3

The symfony (1.2/1.3/1.4) MVC framework is based on a set of cohesive but decoupled classes, the symfony components

Page 11: Symfony Components 2.0 on PHP 5.3

Symfony Components

•  Announced in May 2009 •  Standalone components •  Packaged individually •  No dependencies •  Release cycle independent of Symfony, the framework

Page 12: Symfony Components 2.0 on PHP 5.3

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

Page 13: Symfony Components 2.0 on PHP 5.3

Symfony Components

They have been migrated to PHP 5.3

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

Page 14: Symfony Components 2.0 on PHP 5.3

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/

Page 15: Symfony Components 2.0 on PHP 5.3

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

Page 16: Symfony Components 2.0 on PHP 5.3

Symfony Components

•  Coming soon… –  Request Handler –  Form –  Command Line Tools –  Routing –  Security –  Cache –  Debug – …

Page 17: Symfony Components 2.0 on PHP 5.3

Symfony Components Using them in your project

Page 18: Symfony Components 2.0 on PHP 5.3

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

Page 19: Symfony Components 2.0 on PHP 5.3

Symfony 2.0 Namespaces

Symfony\Components

Symfony\Foundation

Symfony\Framework

Page 20: Symfony Components 2.0 on PHP 5.3

Autoloader

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

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

$loader = new Symfony\Foundation\ClassLoader('Symfony', $path);

$loader->register();

Page 21: Symfony Components 2.0 on PHP 5.3

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

Page 22: Symfony Components 2.0 on PHP 5.3

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 :)

Page 23: Symfony Components 2.0 on PHP 5.3

Symfony Components YAML

Page 24: Symfony Components 2.0 on PHP 5.3

Symfony\Components\YAML

Page 25: Symfony Components 2.0 on PHP 5.3

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

Page 26: Symfony Components 2.0 on PHP 5.3

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)

Page 27: Symfony Components 2.0 on PHP 5.3

config: key: value foo: [foo, bar] bar: { foo: bar } foobar: { foo: [foo, bar] }

Page 28: Symfony Components 2.0 on PHP 5.3

use Symfony\Components\YAML\YAML;

// 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);

Page 29: Symfony Components 2.0 on PHP 5.3

Symfony Components Event Dispatcher

Page 30: Symfony Components 2.0 on PHP 5.3

Symfony\Components\EventDispatcher

Page 31: Symfony Components 2.0 on PHP 5.3

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 –  Inject the Web Debug Toolbar –  Inject methods into core Objects –  I18n management – …

platform

sfEventDispatcher

sfRequest sfResponsesfRouting sfUser

sfStorage sfCache

sfI18N

sfForm

sfLogger

sfDatabase

sfValidator sfWidget

sfYAML

sfCoreAutoload

sfOutputEscaper

Page 32: Symfony Components 2.0 on PHP 5.3

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

Page 33: Symfony Components 2.0 on PHP 5.3

An event dispatcher is a central object that manages connections

between subjects and observers

Page 34: Symfony Components 2.0 on PHP 5.3

It is a powerful mechanism to extend applications without having to change the objects themselves

Associated words: hook, listener, event, subject, …

Page 35: Symfony Components 2.0 on PHP 5.3

// 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);

use Symfony\Components\EventDispatcher\Event; use Symfony\Components\EventDispatcher\EventDispatcher;

$dispatcher = new EventDispatcher();

Page 36: Symfony Components 2.0 on PHP 5.3

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)

Page 37: Symfony Components 2.0 on PHP 5.3

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

Page 38: Symfony Components 2.0 on PHP 5.3

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, …

Page 39: Symfony Components 2.0 on PHP 5.3

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(); } }

Page 40: Symfony Components 2.0 on PHP 5.3

$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();

Page 41: Symfony Components 2.0 on PHP 5.3

Dispatcher Listeners

listener connects to ‘response.filter_content’

Response notifies ‘response.filter_content’

Notifiers

1

2 Calls all listeners

listener is called

Page 42: Symfony Components 2.0 on PHP 5.3

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

Page 43: Symfony Components 2.0 on PHP 5.3

Dispatcher Listeners

listener connects to response.filter_content

Notifiers

1 Your class connects

to response.filter_content

Response notifies response.filter_content 2 Calls

all listeners listener is called

Your class callback is called

Page 44: Symfony Components 2.0 on PHP 5.3

Dispatcher

Response notifies response.filter_content

Notifiers

Calls nothing

very small overhead

Page 45: Symfony Components 2.0 on PHP 5.3

Symfony Components Templating

Page 46: Symfony Components 2.0 on PHP 5.3

Symfony\Components\Templating

Page 47: Symfony Components 2.0 on PHP 5.3

Symfony Templating

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

•  Can work with Template Engines (Smarty, Twig, …)

Page 48: Symfony Components 2.0 on PHP 5.3

New Templating Framework

•  4 sub-components

–  Template Engine

–  Template Renderers

–  Template Loaders

–  Template Storages

Page 49: Symfony Components 2.0 on PHP 5.3

use Symfony\Components\Templating\Engine; use Symfony\Components\Templating\Loader\FilesystemLoader;

$loader = new FilesystemLoader(

'/path/to/templates/%name%.php'

);

$t = new Engine($loader);

echo $t->render('index', array('name' => 'Fabien'));

Page 50: Symfony Components 2.0 on PHP 5.3

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');

Page 51: Symfony Components 2.0 on PHP 5.3

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(), ));

Page 52: Symfony Components 2.0 on PHP 5.3

Template Embedding

Hello <?php echo $name ?>

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

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

Page 53: Symfony Components 2.0 on PHP 5.3

Template Inheritance

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

Hello <?php echo $name ?>

<html> <head> </head> <body> <?php $this->output('content') ?> </body> </html>

Page 54: Symfony Components 2.0 on PHP 5.3

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() ?>

Page 55: Symfony Components 2.0 on PHP 5.3

Template Multiple Inheritance

A layout can be decorated by another layout

Each layout can override slots

Page 56: Symfony Components 2.0 on PHP 5.3

Templating A CMS example

Page 57: Symfony Components 2.0 on PHP 5.3

http://fabien.potencier.org/talk/33/php-barcelona-symfony-2-0-on-PHP-5-3?position=76

Page 58: Symfony Components 2.0 on PHP 5.3

Symfony Components Dependency Injection

Page 59: Symfony Components 2.0 on PHP 5.3

Symfony\Components\DependencyInjection

Page 60: Symfony Components 2.0 on PHP 5.3

« Dependency Injection is where components are given their dependencies through their

constructors, methods, or directly into fields. »

http://www.picocontainer.org/injection.html

Page 61: Symfony Components 2.0 on PHP 5.3

class Message { public function __construct() { $this->output = new Output(); } }

class Message { public function __construct(OutputInterface $output) { $this->output = $output; } }

Page 62: Symfony Components 2.0 on PHP 5.3

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" : '')); } }

Page 63: Symfony Components 2.0 on PHP 5.3

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%s\033[0m", $msg); } }

Page 64: Symfony Components 2.0 on PHP 5.3

DI Hello World example

$output = new FancyOutput(); $message = new Message($output, array('with_newline' => true)); $message->say('Hello World');

Page 65: Symfony Components 2.0 on PHP 5.3

A DI container facilitates objects description and object relationships,

configures and instantiates objects

Page 66: Symfony Components 2.0 on PHP 5.3

use Symfony\Components\DependencyInjection\Builder; use Symfony\Components\DependencyInjection\Reference;

$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!');

DI Container Hello World example

Page 67: Symfony Components 2.0 on PHP 5.3

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;

Page 68: Symfony Components 2.0 on PHP 5.3

$message = $container->message;

is roughly equivalent to

$output = new FancyOutput(); $message = new Message($output, array('with_newline' => true));!

Page 69: Symfony Components 2.0 on PHP 5.3

$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!');

<container xmlns="http://symfony-project.org/2.0/container"> <services> <service id="output" class="FancyOutput" />

<service id="message" class="Message"> <argument type="service" id="output" /> <argument type="collection"> <argument key="with_newline">true</argument> </argument> </service> </services> </container>

$container = new Builder(); $loader = new XmlFileLoader($container); $loader->load('services.xml');

PHP

XML XML is validated against an XSD

Page 70: Symfony Components 2.0 on PHP 5.3

$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!');

services: output: { class: FancyOutput } message: class: Message arguments: - @output - { with_newline: true }

$container = new Builder(); $loader = new YamlFileLoader($container); $loader->load('services.yml');

PHP

YAML

Page 71: Symfony Components 2.0 on PHP 5.3

<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');

Page 72: Symfony Components 2.0 on PHP 5.3

<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');

Page 73: Symfony Components 2.0 on PHP 5.3

<services> <import resource="config.yml" class="Symfony\Components\DependencyInjection\Loader\YamlFileLoader" />

<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');

Page 74: Symfony Components 2.0 on PHP 5.3

Loaders & Dumpers

•  IniFileLoader •  XmlFileLoader •  YamlFileLoader

•  XmlDumper •  YamlDumper •  PhpDumper •  GraphvizDumper

Make your container VERY fast

Page 75: Symfony Components 2.0 on PHP 5.3

use Symfony\Components\DependencyInjection\Builder; use Symfony\Components\DependencyInjection\Reference; use Symfony\Components\DependencyInjection\Dumper\XmlDumper; use Symfony\Components\DependencyInjection\Dumper\YamlDumper; use Symfony\Components\DependencyInjection\Dumper\PhpDumper; use Symfony\Components\DependencyInjection\Loader\XmlFileLoader; use Symfony\Components\DependencyInjection\Loader\YamlFileLoader;

$container = new Builder();

$container->register('output', 'FancyOutput');

$container-> register('message', 'Message')-> setArguments(array(new Reference('output'), array('with_newline' => true))) ;

Page 76: Symfony Components 2.0 on PHP 5.3

$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();

Page 77: Symfony Components 2.0 on PHP 5.3

use Symfony\Components\DependencyInjection\Container; use Symfony\Components\DependencyInjection\Reference; use Symfony\Components\DependencyInjection\Parameter;

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; } }

Page 78: Symfony Components 2.0 on PHP 5.3

use Symfony\Components\DependencyInjection\Dumper\GraphvizDumper;

$dumper = new GraphvizDumper($container); echo $dumper->dump();

Page 79: Symfony Components 2.0 on PHP 5.3

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="output\nFancyOutput\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_message [label="message\nMessage\n", shape=record, fillcolor="#eeeeee", style="filled"]; node_service_container [label="service_container\nSymfony\\Components\\DependencyInjection\\Builder\n", shape=record, fillcolor="#9999ff", style="filled"]; node_message -> node_output [label="" style="filled"]; }

Page 80: Symfony Components 2.0 on PHP 5.3
Page 81: Symfony Components 2.0 on PHP 5.3
Page 82: Symfony Components 2.0 on PHP 5.3

Symfony Components Output Escaper

Page 83: Symfony Components 2.0 on PHP 5.3

Symfony\Components\OutputEscaper

Page 84: Symfony Components 2.0 on PHP 5.3

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

Page 85: Symfony Components 2.0 on PHP 5.3

use Symfony\Components\OutputEscaper\Escaper;

$title = 'Foo <br />';

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

Page 86: Symfony Components 2.0 on PHP 5.3

use Symfony\Components\OutputEscaper\Escaper;

$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";

Page 87: Symfony Components 2.0 on PHP 5.3

class Article { protected $title; protected $author;

public $full_title;

public function __construct($title, Author $author) { $this->title = $title; $this->full_title = $title; $this->author = $author; }

public function getTitle() { return $this->title; } public function getAuthor() { return $this->author; } public function __get($key) { return $this->$key; } public function __call($method, $arguments) { return $this->{'get'.$method}(); } }

public property

public method

public method returning another object

magic __get() magic __call()

Page 88: Symfony Components 2.0 on PHP 5.3

class Author { protected $name;

public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } }

Page 89: Symfony Components 2.0 on PHP 5.3

use Symfony\Components\OutputEscaper\Escaper;

$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";

Page 90: Symfony Components 2.0 on PHP 5.3

Escaping Strategy

echo $article->getHtmlContent(ESC_RAW);

echo $article->getTitle(ESC_JS);

explicitly ask for raw data

change the default escaping strategy

Page 91: Symfony Components 2.0 on PHP 5.3

with Matthew Weier O’Pheinney

I will reveal the first alpha release of Symfony 2.0!

symfony-live.com

Page 92: Symfony Components 2.0 on PHP 5.3

with Matthew Weier O’Pheinney

… with Matthew Weier O'Phinney as a special guest

symfony-live.com

Page 93: Symfony Components 2.0 on PHP 5.3

Thank you!

My slides on slideshare.com/fabpot with a bonus: How to use Symfony Components with ZF!

Page 94: Symfony Components 2.0 on PHP 5.3

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/

Page 95: Symfony Components 2.0 on PHP 5.3

How to use Symfony Components within a Zend Framework project?

BONUS

Page 96: Symfony Components 2.0 on PHP 5.3

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

Page 97: Symfony Components 2.0 on PHP 5.3

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

Page 98: Symfony Components 2.0 on PHP 5.3

Symfony Components Event Dispatcher

Page 99: Symfony Components 2.0 on PHP 5.3

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); } }

Page 100: Symfony Components 2.0 on PHP 5.3

Symfony Components Dependency Injection

Page 101: Symfony Components 2.0 on PHP 5.3

Example from Ben Eberlei (he rocks!): http://www.whitewashing.de/blog/articles/118

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();

$container = new sfServiceContainerBuilder();

$loader = new sfServiceContainerLoaderFileXml($container); $loader->load(dirname(__FILE__).'/configs/resources.xml');

return $container; } }

Page 102: Symfony Components 2.0 on PHP 5.3

<?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>

Page 103: Symfony Components 2.0 on PHP 5.3

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]]

Page 104: Symfony Components 2.0 on PHP 5.3

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; } }

Page 105: Symfony Components 2.0 on PHP 5.3

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

Page 106: Symfony Components 2.0 on PHP 5.3

Symfony Components Output Escaper

Page 107: Symfony Components 2.0 on PHP 5.3

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); } }

Page 108: Symfony Components 2.0 on PHP 5.3

<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) ?>