SlideShare ist ein Scribd-Unternehmen logo
1 von 148
Downloaden Sie, um offline zu lesen
The Symfony Components – Fabien Potencier
Serial entrepreneur
Developer by passion
Founder of Sensio
Creator and lead developer of Symfony
On Twitter @fabpot
On github http://www.github.com/fabpot

            http://fabien.potencier.org/
             The Symfony Components – Fabien Potencier
Standalone components for PHP 5.3

       No dependency between them

Used extensively in Symfony 2, the framework

              The Symfony Components – Fabien Potencier
Low-level libraries
needed by most websites

      The Symfony Components – Fabien Potencier
Event Dispatcher                                              Stable

Output Escaper                                                Stable
                                                                       Extracted from symfony 1
YAML                                                          Stable

Routing                                                       Beta

Console                                                       Stable
Dependency Injection Container                                Stable   Written from scratch
                                                                       for Symfony 2
Request Handler                                               Stable

Templating                                                    Stable

                  The Symfony Components – Fabien Potencier
YAML
Event Dispatcher
                                                              PHP Quebec 2009
Templating
Dependency Injection Container
Console
Routing                                                       ConFoo 2010
Output Escaper
Request Handler
                  The Symfony Components – Fabien Potencier
Download / Installation




The Symfony Components – Fabien Potencier
git clone git://github.com/symfony/symfony.git




                                                            Main repository


                The Symfony Components – Fabien Potencier
svn checkout http://svn.symfony-project.org/branches/2.0/


                                                                  Git Mirror
                                                                Synchronized
                                                               every 15 minutes


                   The Symfony Components – Fabien Potencier
curl -O http://github.com/symfony/symfony/tarball/master
tar zxpf symfony-symfony-XXXXXXX.tar.gz

curl -O http://github.com/symfony/symfony/zipball/master
unzip symfony-symfony-XXXXXXX.zip



                                                               Nightly build


                   The Symfony Components – Fabien Potencier
app/
  .../
     Symfony/
       Components/
       Foundation/
       Framework/
        The Symfony Components – Fabien Potencier
Autoloading Classes




The Symfony Components – Fabien Potencier
Before PHP 5.3
PEAR naming convention
      The Symfony Components – Fabien Potencier
PEAR_Log                >      PEAR/Log.php
            Zend_Log                >      Zend/Log.php
  Swift_Mime_Message                >      Swift/Mime/Message.php
Doctrine_Pager_Range                >      Doctrine/Pager/Range.php
       Twig_Node_For                >      Twig/Node/For.php




               The Symfony Components – Fabien Potencier
PEAR_Log                >      PEAR/Log.php
            Zend_Log                >      Zend/Log.php
  Swift_Mime_Message                >      Swift/Mime/Message.php
Doctrine_Pager_Range                >      Doctrine/Pager/Range.php
       Twig_Node_For                >      Twig/Node/For.php

                                                           Vendor name

               The Symfony Components – Fabien Potencier
As of PHP 5.3
    PHP 5.3 technical
interoperability standards
       The Symfony Components – Fabien Potencier
SymfonyFoundationKernel > Symfony/Foundation/Kernel.php
     DoctrineDBALDriver > Doctrine/DBAL/Driver.php
pdependreflectionReflectionSession > pdepend/reflection/ReflectionSession.php




                         The Symfony Components – Fabien Potencier
SymfonyFoundationKernel > Symfony/Foundation/Kernel.php
     DoctrineDBALDriver > Doctrine/DBAL/Driver.php
pdependreflectionReflectionSession > pdepend/reflection/ReflectionSession.php




                                                                     Vendor name

                         The Symfony Components – Fabien Potencier
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




                      The Symfony Components – Fabien Potencier
use SymfonyFoundationUniversalClassLoader;




              The Symfony Components – Fabien Potencier
require_once '.../Symfony/Foundation/UniversalClassLoader.php';

use SymfonyFoundationUniversalClassLoader;

$loader = new UniversalClassLoader();
$loader->registerNamespace(
   'Symfony', __DIR__.'/src/symfony/src'
);
$loader->register();

// use any Symfony class




                      The Symfony Components – Fabien Potencier
$loader->registerNamespaces(array(
  'Symfony' => '/path/to/symfony/src',
  'Doctrine' => '/path/to/doctrine/lib',
  'pdepend' => '/path/to/reflection/source',
));

                                                                PHP 5.3 technical
                                                            interoperability standards


                The Symfony Components – Fabien Potencier
$loader->registerPrefixes(array(
  'Swift_' => '/path/to/swiftmailer/lib/classes',
  'Zend_' => '/path/to/vendor/zend/library',
));


                                                             PEAR style


                 The Symfony Components – Fabien Potencier
require_once '.../Symfony/Foundation/UniversalClassLoader.php';

use SymfonyFoundationUniversalClassLoader;

$loader = new UniversalClassLoader();
$loader->registerNamespaces(array(
  'Symfony' => '/path/to/symfony/src',
  'Doctrine' => '/path/to/doctrine/lib',
));
$loader->registerPrefixes(array(
  'Swift_' => '/path/to/swiftmailer/lib/classes',
  'Zend_' => '/path/to/vendor/zend/library',
));
$loader->register();

// use any class

                     The Symfony Components – Fabien Potencier
Console




The Symfony Components – Fabien Potencier
Console




The Symfony Components – Fabien Potencier
Automate things
   code generators
     deployment

   The Symfony Components – Fabien Potencier
Long running tasks
          deployment
get « things » from the Internet

        The Symfony Components – Fabien Potencier
Batches
cleanup a database from time to time
    migrate a DB to a new schema

          The Symfony Components – Fabien Potencier
These tasks should never
  be run from a browser

       The Symfony Components – Fabien Potencier
But PHP is
a web language, right?
      The Symfony Components – Fabien Potencier
So, why not use the right tool
         for the job?

   … like Perl or Python?
         The Symfony Components – Fabien Potencier
Don’t want to use/learn another language
          Want to share code


            The Symfony Components – Fabien Potencier
PHP natively supports
 the CLI environment

      The Symfony Components – Fabien Potencier
<?php

// ...



         The Symfony Components – Fabien Potencier
#!/usr/bin/env php
<?php

// ...
                                                      $ ./foo …

          The Symfony Components – Fabien Potencier
$ ./foobar Fabien

$name = $argv[1];
echo 'Hello '.$name;


          The Symfony Components – Fabien Potencier
… but the complexity lies in the details



            The Symfony Components – Fabien Potencier
option / arguments handling
          exit codes
             shell
     output colorization
             tests
       error messages
              …
     The Symfony Components – Fabien Potencier
$ ./life foo "foo bar" --foo foobar -b

Array
(
    [0]   =>   ./life
    [1]   =>   foo
    [2]   =>   foo bar
    [3]   =>   --foo
    [4]   =>   foobar
    [5]   =>   -b
)

                    The Symfony Components – Fabien Potencier
don’t reinvent the wheel…
     use a “framework”

       The Symfony Components – Fabien Potencier
Console




The Symfony Components – Fabien Potencier
Let’s create a CLI tool
  to get the weather
anywhere in the world
      The Symfony Components – Fabien Potencier
The Symfony Components – Fabien Potencier
use LifeYahooWeather;

$weather = new YahooWeather('API_KEY', $argv[1]);
echo $weather->getTitle()."n";

$attrs = $weather->getCurrentConditions();

echo "Current conditions:n";
echo sprintf(" %s, %sCn", $attrs['text'], $attrs['temp']);

$attrs = $weather->getForecast();

echo sprintf("nForecast for %sn", $attrs['date']);
echo sprintf(" %s, low: %s, high: %sn", $attrs['text'],
$attrs['low'], $attrs['high']);


                         The Symfony Components – Fabien Potencier
use SymfonyComponentsConsoleApplication;

$application = new Application();
$application->run();




                The Symfony Components – Fabien Potencier
$command = new Command('weather');
$command->setCode(
   function ($input, $output)
   {
     // do something
   }
);

$application->addCommand($command);


                The Symfony Components – Fabien Potencier
use SymfonyComponentsConsoleApplication;

$application = new Application();
$application->addCommand(new WeatherCommand());
$application->run();




                The Symfony Components – Fabien Potencier
use SymfonyComponentsConsoleCommandCommand;
use SymfonyComponentsConsoleInputInputInterface;
use SymfonyComponentsConsoleOutputOutputInterface;

class WeatherCommand extends Command
{
  protected function configure()
  {
    $this->setName('weather');
  }

  protected function execute(InputInterface $input, OutputInterface
$output)
  {
    // do something
  }
}


                        The Symfony Components – Fabien Potencier
Console

    The Output



The Symfony Components – Fabien Potencier
$output->writeln($weather->getTitle());




                  The Symfony Components – Fabien Potencier
$output->writeln(
   sprintf('<info>%s</info>', $weather->getTitle())
);

$output->writeln("<comment>Conditions</comment>");




                  The Symfony Components – Fabien Potencier
The Symfony Components – Fabien Potencier
The Symfony Components – Fabien Potencier
Console

    Getting help



The Symfony Components – Fabien Potencier
The Symfony Components – Fabien Potencier
$application = new Application('Life Tool', '0.1');




                  The Symfony Components – Fabien Potencier
class WeatherCommand extends Command
{
  protected function configure()
  {
    $this->setName('weather')
      ->setDescription('Displays weather forecast')
      ->setHelp(<<<EOF
The <info>weather</info> command displays
weather forecast for a given city:

  <info>./life weather Paris</info>

You can also change the default degree unit
with the <comment>--unit</comment> option:

  <info>./life weather Paris --unit=c</info>
  <info>./life weather Paris -u c</info>
EOF
    );
  }

                         The Symfony Components – Fabien Potencier
The Symfony Components – Fabien Potencier
The Symfony Components – Fabien Potencier
$ ./life weather
$ ./life weath
$ ./life w
      The Symfony Components – Fabien Potencier
Console

    The Input



The Symfony Components – Fabien Potencier
class WeatherCommand extends Command
{
  protected function configure()
  {
    $definition = array(
      new InputArgument('place',
InputArgument::OPTIONAL, 'The place name', 'Paris'),

       new InputOption('unit', 'u',
InputOption::PARAMETER_REQUIRED, 'The degree unit',
'c'),
    );

    $this->setDefinition($definition);

                   The Symfony Components – Fabien Potencier
The Symfony Components – Fabien Potencier
protected function execute(InputInterface $input,
OutputInterface $output)
{
  $city = $input->getArgument('place');
  $unit = $input->getOption('unit');

    $output->writeln("<comment>Conditions</comment>");
}




                    The Symfony Components – Fabien Potencier
Console

    Error codes / Exit status



The Symfony Components – Fabien Potencier
The Symfony Components – Fabien Potencier
The Symfony Components – Fabien Potencier
protected function execute(InputInterface $input,
OutputInterface $output)
{
  $city = $input->getArgument('place');
  $unit = $input->getOption('unit');

    $output->writeln("<comment>Conditions</comment>");

    return 120;
}



                    The Symfony Components – Fabien Potencier
Console

    Interact with the user



The Symfony Components – Fabien Potencier
protected function interact($input, $output)
{
  $city = $this->dialog->ask(
     $output,
     '<comment>Which city?</comment> (Paris)',
     'Paris’
  );

    $input->setArgument('place', $city);
}



                    The Symfony Components – Fabien Potencier
./life weather --no-interaction




           The Symfony Components – Fabien Potencier
dialog
  ask()
  askConfirmation()
  askAndValidate()

formatter
  formatSection()
  formatBlock()

... your own



                The Symfony Components – Fabien Potencier
class WeatherHelper extends Helper
{
  public function __construct()
  {
    Output::setStyle('weather_hot', array('bg' => 'red', 'fg' => 'yellow'));
    Output::setStyle('weather_cold', array('bg' => 'blue', 'fg' => 'white'));
  }

    public function formatTemperature($temperature, $unit)
    {
      $style = $temperature < 0 ? 'weather_cold' : 'weather_hot';

    return sprintf("<%s> %s%s </%s>", $style, $temperature, strtoupper($unit),
$style);
  }

    public function getName()
    {
      return 'weather';
    }
}

                                The Symfony Components – Fabien Potencier
$output->writeln(sprintf(
  " %s, low: %s, high: %s",
  $attrs['text'],
  $this->weather->formatTemperature(
    $attrs['low'],
    $input->getOption('unit')),
  $this->weather->formatTemperature(
    $attrs['high'],
    $input->getOption('unit'))
));



                  The Symfony Components – Fabien Potencier
The Symfony Components – Fabien Potencier
Console

    Testing



The Symfony Components – Fabien Potencier
$input = new ArrayInput(
   array('place' => 'Paris', '--unit' => 'C')
);
$application->run($input);

$input = new StringInput('Paris --unit=C');
$application->run($input);



                The Symfony Components – Fabien Potencier
$stream = fopen('php://memory', 'a', false);
$output = new StreamOutput($stream);

$application->run($input, $output);

rewind($output->getStream());
echo stream_get_contents($output->getStream());



                The Symfony Components – Fabien Potencier
$application = new Application();

// for testing
$application->setCatchExceptions(false);
$application->setAutoExit(false);



             The Symfony Components – Fabien Potencier
echo $application->asXml();




           The Symfony Components – Fabien Potencier
$command = new WeatherCommand();
echo $command->asXml();




           The Symfony Components – Fabien Potencier
Create a PHAR archive
  out of your CLI tool
    for distribution
     The Symfony Components – Fabien Potencier
$pharFile = 'life.phar’;
if (file_exists($pharFile))
  unlink($pharFile);

$phar = new Phar($pharFile, 0, $this->application->getName());
$phar->setSignatureAlgorithm(Phar::SHA1);
$phar->startBuffering();

// CLI Component files
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__.'/../symfony/src/Symfony/Components/
Console'), RecursiveIteratorIterator::LEAVES_ONLY) as $file)
{
  $phar['Symfony/Components/Console'.str_replace(__DIR__.'/../symfony/src/Symfony/Components/Console', '', $file)] =
file_get_contents($file);
}
// Life stuff
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__.'/../Life'),
RecursiveIteratorIterator::LEAVES_ONLY) as $file)
{
  $phar['Life'.str_replace(__DIR__.'/../Life', '', $file)] = file_get_contents($file);
}
// Autoloader
$phar['Symfony/Foundation/UniversalClassLoader.php'] = file_get_contents(__DIR__.'/../symfony/src/Symfony/Foundation/
UniversalClassLoader.php');

// Stubs
$phar['_cli_stub.php'] = $this->getCliStub();
$phar['_web_stub.php'] = $this->getWebStub();
$phar->setDefaultStub('_cli_stub.php', '_web_stub.php');
$phar->stopBuffering();
$phar->compressFiles(Phar::GZ);
unset($phar);

                                       The Symfony Components – Fabien Potencier
git clone http://github.com/fabpot/confoo2010




                The Symfony Components – Fabien Potencier
Routing

    Pretty and Smart URLs



The Symfony Components – Fabien Potencier
http://example.com/article.php?id=44

http://example.com/article/confoo-2010




            The Symfony Components – Fabien Potencier
Routing is a two-way process
   Matching incoming requests (URLs)
           Generating URLs


           The Symfony Components – Fabien Potencier
The architecture
is difficult to get right

     The Symfony Components – Fabien Potencier
Symfony one is built
with performance in mind

      The Symfony Components – Fabien Potencier
Routing

    Describing your routes



The Symfony Components – Fabien Potencier
use SymfonyComponentsRoutingRouteCollection;
use SymfonyComponentsRoutingRoute;

$routes = new RouteCollection();
$route = new Route(
   '/',
   array('to' => function () { echo "Home!"; })
);
$routes->addRoute('home', $route);


                The Symfony Components – Fabien Potencier
$route = new Route(
   '/:year/:month/:day/:slug',
   array('to' => function ($params) { var_export
($params); }),
   array('year' => 'd{4}')
);
$routes->addRoute('blog_post', $route);



                The Symfony Components – Fabien Potencier
Routing

    Matching URLs



The Symfony Components – Fabien Potencier
use SymfonyComponentsRoutingMatcherUrlMatcher;

$matcher = new UrlMatcher($routes);

if (false === $params = $matcher->match('/'))
{
  throw new Exception('No route matches.');
}

$params['to']();


                   The Symfony Components – Fabien Potencier
$params = $matcher->match('/2010/03/10/confoo');
if (false === $params)
{
  throw new Exception('No route matches.');
}

$params['to']($params);



                The Symfony Components – Fabien Potencier
array (
  'to' =>
  Closure::__set_state(array(
  )),
  'year' => '2010',
  'month' => '03',
  'day' => '10',
  'slug' => 'confoo',
  '_route' => 'blog_post',
)

                The Symfony Components – Fabien Potencier
$params = $matcher->match('/yyyy/03/10/confoo');
if (false === $params)
{
  throw new Exception('No route matches.');
}

$params['to']($params);

Uncaught exception 'Exception' with message 'No
route matches.'


                The Symfony Components – Fabien Potencier
Routing

    Generating URLs



The Symfony Components – Fabien Potencier
use SymfonyComponentsRoutingGeneratorUrlGenerator;

$generator = new UrlGenerator($routes);

echo $generator->generate('home', array());




                  The Symfony Components – Fabien Potencier
$params =    array(
   'year'    => 2010,
   'month'   => 10,
   'day'     => 10,
   'slug'    => 'another-one'
);

echo $generator->generate('blog_post', $params);



                   The Symfony Components – Fabien Potencier
$params =    array(
   'year'    => 'yyyy',
   'month'   => 10,
   'day'     => 10,
);

echo $generator->generate('blog_post', $params);

Uncaught exception 'InvalidArgumentException'
with message 'The "blog_post" route has some
missing mandatory parameters (:slug).'

                   The Symfony Components – Fabien Potencier
use SymfonyComponentsRoutingGeneratorUrlGenerator;

$generator = new UrlGenerator($routes);

echo $generator->generate('home', array('foo' =>
'bar'));


/?foo=bar



                  The Symfony Components – Fabien Potencier
$generator = new   UrlGenerator($routes, array(
  'base_url' =>    '/myapp',
  'host'      =>   'www.example.com',
  'is_secure' =>   false,
));

echo $generator->generate('home', array(), true);


http://www.example.com/myapp/


                   The Symfony Components – Fabien Potencier
The context
        makes the routing
decoupled from the rest of the world

                      base_url
                        host
                     is_secure
                       method

      The Symfony Components – Fabien Potencier
Routing

    Describing your routes with XML or YAML



The Symfony Components – Fabien Potencier
home:
  pattern: /
  defaults: { controller: home, action: index }

blog_post:
  pattern: /:year/:month/:day/:slug
  defaults:
    controller: blog
    action:     show
  requirements:
    year: d{4}


                The Symfony Components – Fabien Potencier
use SymfonyComponentsRoutingLoaderYamlFileLoader;

$loader = new YamlFileLoader();

$routes = $loader->load('routes.yml');




                  The Symfony Components – Fabien Potencier
<?xml version="1.0" encoding="UTF-8" ?>

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

  <route id="blog_post" pattern="/:year/:month/:day/:slug">
    <default key="controller">blog</default>
    <default key="action">show</default>
    <requirement key="year">d{4}</requirement>
  </route>

  <route id="home" pattern="/">
    <default key="controller">home</default>
    <default key="action">index</default>
  </route>
</routes>

                       The Symfony Components – Fabien Potencier
use SymfonyComponentsRoutingLoaderXmlFileLoader;

$loader = new XmlFileLoader();

$routes = $loader->load('routes.xml');




                  The Symfony Components – Fabien Potencier
<?xml version="1.0" encoding="UTF-8" ?>

<routes>
  <route id="home" pattern="/">
    <default key="controller">home</default>
    <default key="action">index</default>
  </route>

  <import resource="blog.yml" prefix="/blog" />
  <import resource="forum.xml" prefix="/forum" />
</routes>

                 The Symfony Components – Fabien Potencier
home:
  pattern: /
  defaults: { controller: home, action: index }

import:
  - { resource: blog.yml, prefix: /blog }
  - { resource: forum.xml, prefix: /forum }



                The Symfony Components – Fabien Potencier
$yamlLoader = new YamlFileLoader();
$xmlLoader = new XmlFileLoader();

$routes = new RouteCollection();
$route = new Route(
   '/',
   array('to' => function () { echo "Home!"; })
);
$routes->addRoute('home', $route);

$routes->addCollection(
  $yamlLoader->load('blog.yml'), '/blog');

$routes->addCollection(
  $xmlLoader->load('forum.xml'), '/forum');
                   The Symfony Components – Fabien Potencier
/blog/2010/03/10/confoo
 prefix                                      pattern




         The Symfony Components – Fabien Potencier
Routing

    Make it simple & fast



The Symfony Components – Fabien Potencier
use SymfonyComponentsRoutingRouter;

$router = new Router($loader, $options, $context);




                  The Symfony Components – Fabien Potencier
$loader = function ()
{
  $routes = new RouteCollection();
  // ...

  return $routes;
};

$context = array(
   'base_url' => '/myapp',
   'host'      => 'www.example.com',
   'is_secure' => false,
);

$options = array(
   'cache_dir' => '/tmp/routing',
   'debug'     => true,
);
                       The Symfony Components – Fabien Potencier
$router = new Router($loader, $options, $context);

if (false === $params = $router->match('/'))
{
  throw new Exception('No route matches.');
}

echo $router->generate('home', array());




                  The Symfony Components – Fabien Potencier
class ProjectUrlMatcher extends SymfonyComponentsRouting
MatcherUrlMatcher
{
  // ...

    public function match($url)
    {
      $url = $this->normalizeUrl($url);

      if (preg_match('#^/$#x', $url, $matches))
        return array_merge($this->mergeDefaults($matches, array
(    'to' => 'foo',)), array('_route' => 'home'));

        return false;
    }
}

                        The Symfony Components – Fabien Potencier
class ProjectUrlGenerator extends SymfonyComponentsRoutingGeneratorUrlGenerator
{
  // ...

  public function generate($name, array $parameters, $absolute = false)
  {
    if (!method_exists($this, $method = 'get'.$name.'RouteInfo'))
    {
      throw new InvalidArgumentException(sprintf('Route "%s" does not exist.', $name));
    }

    list($variables, $defaults, $requirements, $tokens) = $this->$method();

    return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters,
$name, $absolute);
  }

  protected function gethomeRouteInfo()
  {
    return array(array (), array_merge($this->defaults, array ( 'to' => 'foo',)), array
(), array ( 0 =>    array (    0 => 'text',    1 => '/',    2 => '',   3 => NULL, ),));
  }
}

                              The Symfony Components – Fabien Potencier
use SymfonyComponentsRoutingFileResource;

$loader = function ()
{
  $routes = new RouteCollection();
  // ...

  $routes->addResource(new FileResource(__FILE__));

  return $routes;
};


                    The Symfony Components – Fabien Potencier
Routing

    Make it really fast



The Symfony Components – Fabien Potencier
use SymfonyComponentsRoutingMatcherDumper
ApacheMatcherDumper;

$dumper = new ApacheMatcherDumper($routes);

echo $dumper->dump();




                The Symfony Components – Fabien Potencier
RewriteCond %{PATH_INFO} ^/$
RewriteRule .* index.php
[QSA,L,E=_ROUTING__route:home,E=_ROUTING_to:foo
]




                The Symfony Components – Fabien Potencier
$options = array(
   'cache_dir'     => '/tmp/routing',
   'debug'         => true,
   'matcher_class' => 'SymfonyComponents
RoutingMatcherApacheUrlMatcher',
);




                The Symfony Components – Fabien Potencier
Output Escaper




The Symfony Components – Fabien Potencier
Provides XSS protection
 for your PHP templates

      The Symfony Components – Fabien Potencier
Wraps template variables
Works for
   strings
   arrays
   objects
      properties
      methods
      __call(), __get(), …
      Iterators, Coutables, …
      …
Works for deep method calls
                         The Symfony Components – Fabien Potencier
use SymfonyComponentsOutputEscaperEscaper;

$title = 'Foo <br />';

echo Escaper::escape('htmlspecialchars', $title);




                     The Symfony Components – Fabien Potencier
use SymfonyComponentsOutputEscaperEscaper;

$article = array(
   'title' => 'Foo <br />',
   'author' => array(
     'name' => 'Fabien <br/>',
   )
);

$article = Escaper::escape('htmlspecialchars', $article);

echo $article['title']."n";
echo $article['author']['name']."n";


                      The Symfony Components – Fabien Potencier
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 function getAuthor() { return $this->author; }                     public method returning
    public function __get($key) { return $this->$key; }                       another object
    public function __call($method, $arguments)
    {                                                                       magic __get()
      return $this->{'get'.$method}();     magic __call()
    }
}
                             The Symfony Components – Fabien Potencier
class Author
{
  protected $name;

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




                       The Symfony Components – Fabien Potencier
use SymfonyComponentsOutputEscaperEscaper;

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

$article = Escaper::escape('htmlspecialchars', $article);

echo   $article->getTitle()."n";
echo   $article->getAuthor()->getName()."n";
echo   $article->full_title."n";
echo   $article->title."n";
echo   $article->title()."n";


                       The Symfony Components – Fabien Potencier
explicitly ask
                                                              for raw data


echo $article->getHtmlContent('raw');



echo $article->getTitle('js');
                                             change the default
                                             escaping strategy



                The Symfony Components – Fabien Potencier
Request Handler




The Symfony Components – Fabien Potencier
use SymfonyComponentsRequestHandlerRequest;

$request = new Request();
$request->getPathInfo();
$request->getPreferredLanguage(array('en', 'fr'));
$request->isXmlHttpRequest();




                 The Symfony Components – Fabien Potencier
use SymfonyComponentsRequestHandlerRequest;

$request = new   Request(array(
  'request' =>   $_POST,
  'query'   =>   $_GET,
  'path'    =>   array(),
  'server' =>    $_SERVER,
));



                  The Symfony Components – Fabien Potencier
use SymfonyComponentsRequestHandlerResponse;

$response = new Response('Hello World', 200,
  array('Content-Type' => 'text/plain'));
$response->send();

$response->setHeader('Content-Type', 'text/plain');
$response->setCookie('foo', 'bar');
$response->setContent('Hello World');
$response->setStatusCode(200);



                  The Symfony Components – Fabien Potencier
Request Handler

    Framework to build Frameworks



The Symfony Components – Fabien Potencier
use SymfonyComponentsRequestHandlerRequest;
use SymfonyComponentsRequestHandlerResponse;
use SymfonyComponentsRequestHandlerRequestHandler;

$handler = new RequestHandler($dispatcher);

$request = new Request();
$response = $handler->handle($request);
$response->send();



                  The Symfony Components – Fabien Potencier
use SymfonyComponentsEventDispatcherEventDispatcher;
use SymfonyComponentsEventDispatcherEvent;

$dispatcher = new EventDispatcher();
$dispatcher->connect('core.load_controller', function (Event $event)
{
  $event->setReturnValue(array(
    function ($request) { return new Response('Hello!'); },
    array($event['request'])
  ));

  return true;
});




                         The Symfony Components – Fabien Potencier
Request Handler

    A small Framework



The Symfony Components – Fabien Potencier
$framework = new Framework(array(
  '/' => function ($request)
  {
    $content = 'Hello '.
      $request->getParameter('name');

    return new Response($content);
  }
));
$framework->run();

                The Symfony Components – Fabien Potencier
class Framework
{
  protected $map;

    public function __construct($map)
    {
      $this->map = $map;
    }

    public function run()
    {
      $dispatcher = new EventDispatcher();
      $dispatcher->connect('core.load_controller', array($this, 'loadController'));

        $handler = new RequestHandler($dispatcher);
        $response = $handler->handle(new Request());
        $response->send();
    }
}



                                The Symfony Components – Fabien Potencier
public function loadController(Event $event)
{
  $request = $event['request'];

    $routes = new RouteCollection();
    foreach ($this->map as $pattern => $to)
    {
      $route = new Route($pattern, array('to' => $to));
      $routes->addRoute(str_replace('/', '_', $pattern), $route);
    }

    $matcher = new UrlMatcher($routes, array(
      'base_url' => $request->getBaseUrl(),
      'method'    => $request->getMethod(),
      'host'      => $request->getHost(),
      'is_secure' => $request->isSecure(),
    ));

    $parameters = $matcher->match($request->getPathInfo());
    if (false === $parameters)
    {
      return false;
    }

    $request->setPathParameters($parameters);

    $event->setReturnValue(array($parameters['to'], array($request)));

    return true;
}
                                      The Symfony Components – Fabien Potencier
$framework = new Framework(array(
  '/' => function ($request)
  {
    $content = 'Hello '.
      $request->getParameter('name');

    return new Response($content);
  }
));
$framework->run();

                The Symfony Components – Fabien Potencier
Questions?




The Symfony Components – Fabien Potencier
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/


The Symfony Components – Fabien Potencier

Weitere ähnliche Inhalte

Was ist angesagt?

Being Dangerous with Twig
Being Dangerous with TwigBeing Dangerous with Twig
Being Dangerous with TwigRyan Weaver
 
Create a Symfony Application from a Drupal Perspective
Create a Symfony Application from a Drupal PerspectiveCreate a Symfony Application from a Drupal Perspective
Create a Symfony Application from a Drupal PerspectiveAcquia
 
Wait, IPython can do that?! (30 minutes)
Wait, IPython can do that?! (30 minutes)Wait, IPython can do that?! (30 minutes)
Wait, IPython can do that?! (30 minutes)Sebastian Witowski
 
Introduction to web and php mysql
Introduction to web and php mysqlIntroduction to web and php mysql
Introduction to web and php mysqlProgrammer 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.netProgrammer Blog
 
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 PHPCesare 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] 2015Colin O'Dell
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHPWim Godden
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Plataformatec
 
Last train to php 7
Last train to php 7Last train to php 7
Last train to php 7Damien Seguy
 
Introduction to php
Introduction to phpIntroduction to php
Introduction to phpAnjan Banda
 
Incredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and GeneratorsIncredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and Generatorsdantleech
 
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 - 23may2010Plataformatec
 
Php Reusing Code And Writing Functions
Php Reusing Code And Writing FunctionsPhp Reusing Code And Writing Functions
Php Reusing Code And Writing Functionsmussawir20
 

Was ist angesagt? (20)

Being Dangerous with Twig
Being Dangerous with TwigBeing Dangerous with Twig
Being Dangerous with Twig
 
Create a Symfony Application from a Drupal Perspective
Create a Symfony Application from a Drupal PerspectiveCreate a Symfony Application from a Drupal Perspective
Create a Symfony Application from a Drupal Perspective
 
Wait, IPython can do that?! (30 minutes)
Wait, IPython can do that?! (30 minutes)Wait, IPython can do that?! (30 minutes)
Wait, IPython can do that?! (30 minutes)
 
Wait, IPython can do that?
Wait, IPython can do that?Wait, IPython can do that?
Wait, IPython can do that?
 
Introduction to web and php mysql
Introduction to web and php mysqlIntroduction to web and php mysql
Introduction to web and php mysql
 
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
 
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
 
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
 
Introduction to PHP
Introduction to PHPIntroduction to PHP
Introduction to PHP
 
Peek at PHP 7
Peek at PHP 7Peek at PHP 7
Peek at PHP 7
 
The promise of asynchronous PHP
The promise of asynchronous PHPThe promise of asynchronous PHP
The promise of asynchronous PHP
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010
 
Last train to php 7
Last train to php 7Last train to php 7
Last train to php 7
 
Love Twig
Love TwigLove Twig
Love Twig
 
Introduction to php
Introduction to phpIntroduction to php
Introduction to php
 
PHP NOTES FOR BEGGINERS
PHP NOTES FOR BEGGINERSPHP NOTES FOR BEGGINERS
PHP NOTES FOR BEGGINERS
 
Incredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and GeneratorsIncredible Machine with Pipelines and Generators
Incredible Machine with Pipelines and Generators
 
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
 
ZF3 introduction
ZF3 introductionZF3 introduction
ZF3 introduction
 
Php Reusing Code And Writing Functions
Php Reusing Code And Writing FunctionsPhp Reusing Code And Writing Functions
Php Reusing Code And Writing Functions
 

Andere mochten auch

Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Fabien Potencier
 
Enterprise Symfony Architecture (RU)
Enterprise Symfony Architecture (RU)Enterprise Symfony Architecture (RU)
Enterprise Symfony Architecture (RU)Alexander Lisachenko
 
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...Alexander Lisachenko
 
Weaving aspects in PHP with the help of Go! AOP library
Weaving aspects in PHP with the help of Go! AOP libraryWeaving aspects in PHP with the help of Go! AOP library
Weaving aspects in PHP with the help of Go! AOP libraryAlexander Lisachenko
 
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
 
MVP & Startup, with OpenSource Software and Microsoft Azure
MVP & Startup, with OpenSource Software and Microsoft AzureMVP & Startup, with OpenSource Software and Microsoft Azure
MVP & Startup, with OpenSource Software and Microsoft AzureFrancesco Fullone
 
symfony Live 2010 - Using Doctrine Migrations
symfony Live 2010 -  Using Doctrine Migrationssymfony Live 2010 -  Using Doctrine Migrations
symfony Live 2010 - Using Doctrine MigrationsD
 
Debugging and Profiling Symfony Apps
Debugging and Profiling Symfony AppsDebugging and Profiling Symfony Apps
Debugging and Profiling Symfony AppsAlvaro Videla
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 WorldFabien Potencier
 
Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Fabien Potencier
 
Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Fabien Potencier
 
Have you played this Symfony? Why Symfony is great choice for Web development
Have you played this Symfony? Why Symfony is great choice for Web developmentHave you played this Symfony? Why Symfony is great choice for Web development
Have you played this Symfony? Why Symfony is great choice for Web developmentMike Taylor
 
Mastering Twig (DrupalCon Barcelona 2015)
Mastering Twig (DrupalCon Barcelona 2015)Mastering Twig (DrupalCon Barcelona 2015)
Mastering Twig (DrupalCon Barcelona 2015)Javier Eguiluz
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Fabien 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 2014D
 
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterSymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterHaehnchen
 

Andere mochten auch (20)

Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2Unit and Functional Testing with Symfony2
Unit and Functional Testing with Symfony2
 
Enterprise Symfony Architecture (RU)
Enterprise Symfony Architecture (RU)Enterprise Symfony Architecture (RU)
Enterprise Symfony Architecture (RU)
 
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
Handling 10k requests per second with Symfony and Varnish - SymfonyCon Berlin...
 
30 Symfony Best Practices
30 Symfony Best Practices30 Symfony Best Practices
30 Symfony Best Practices
 
Weaving aspects in PHP with the help of Go! AOP library
Weaving aspects in PHP with the help of Go! AOP libraryWeaving aspects in PHP with the help of Go! AOP library
Weaving aspects in PHP with the help of Go! AOP library
 
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)
 
MVP & Startup, with OpenSource Software and Microsoft Azure
MVP & Startup, with OpenSource Software and Microsoft AzureMVP & Startup, with OpenSource Software and Microsoft Azure
MVP & Startup, with OpenSource Software and Microsoft Azure
 
symfony Live 2010 - Using Doctrine Migrations
symfony Live 2010 -  Using Doctrine Migrationssymfony Live 2010 -  Using Doctrine Migrations
symfony Live 2010 - Using Doctrine Migrations
 
Debugging and Profiling Symfony Apps
Debugging and Profiling Symfony AppsDebugging and Profiling Symfony Apps
Debugging and Profiling Symfony Apps
 
News of the Symfony2 World
News of the Symfony2 WorldNews of the Symfony2 World
News of the Symfony2 World
 
Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010Dependency Injection - ConFoo 2010
Dependency Injection - ConFoo 2010
 
Caching on the Edge with Symfony2
Caching on the Edge with Symfony2Caching on the Edge with Symfony2
Caching on the Edge with Symfony2
 
PHP 5.3 in practice
PHP 5.3 in practicePHP 5.3 in practice
PHP 5.3 in practice
 
Have you played this Symfony? Why Symfony is great choice for Web development
Have you played this Symfony? Why Symfony is great choice for Web developmentHave you played this Symfony? Why Symfony is great choice for Web development
Have you played this Symfony? Why Symfony is great choice for Web development
 
PhpBB meets Symfony2
PhpBB meets Symfony2PhpBB meets Symfony2
PhpBB meets Symfony2
 
Look beyond PHP
Look beyond PHPLook beyond PHP
Look beyond PHP
 
Mastering Twig (DrupalCon Barcelona 2015)
Mastering Twig (DrupalCon Barcelona 2015)Mastering Twig (DrupalCon Barcelona 2015)
Mastering Twig (DrupalCon Barcelona 2015)
 
Dependency injection-zendcon-2010
Dependency injection-zendcon-2010Dependency injection-zendcon-2010
Dependency injection-zendcon-2010
 
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
 
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterSymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
 

Ähnlich wie Symfony Components

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 Components in the wild
Symfony Components in the wildSymfony Components in the wild
Symfony Components in the wildPHPLondon
 
Integrating symfony and Zend Framework
Integrating symfony and Zend FrameworkIntegrating symfony and Zend Framework
Integrating symfony and Zend FrameworkStefan Koopmanschap
 
Integrating symfony and Zend Framework (PHPNW09)
Integrating symfony and Zend Framework (PHPNW09)Integrating symfony and Zend Framework (PHPNW09)
Integrating symfony and Zend Framework (PHPNW09)Stefan Koopmanschap
 
Integrating symfony and Zend Framework (PHPBarcelona 2009)
Integrating symfony and Zend Framework (PHPBarcelona 2009)Integrating symfony and Zend Framework (PHPBarcelona 2009)
Integrating symfony and Zend Framework (PHPBarcelona 2009)Stefan Koopmanschap
 
Symfony: A Brief Introduction
Symfony: A Brief IntroductionSymfony: A Brief Introduction
Symfony: A Brief IntroductionCraig Willis
 
An introduction to Symfony 2 for symfony 1 developers
An introduction to Symfony 2 for symfony 1 developersAn introduction to Symfony 2 for symfony 1 developers
An introduction to Symfony 2 for symfony 1 developersGiorgio Cefaro
 
Symfony2 components to the rescue of your PHP projects
Symfony2 components to the rescue of your PHP projectsSymfony2 components to the rescue of your PHP projects
Symfony2 components to the rescue of your PHP projectsXavier Lacot
 
A Glymse of Symfony 2
A Glymse of Symfony 2A Glymse of Symfony 2
A Glymse of Symfony 2shaduli
 
Symfony State Of The Union, March 2010
Symfony State Of The Union, March 2010Symfony State Of The Union, March 2010
Symfony State Of The Union, March 2010Damien Filiatrault
 
Write Plugins for symfony (Symfony Camp 2007)
Write Plugins for symfony (Symfony Camp 2007)Write Plugins for symfony (Symfony Camp 2007)
Write Plugins for symfony (Symfony Camp 2007)Fabien Potencier
 
Artificial Neural Networks with PHP & Symfony con 2014
Artificial Neural Networks with PHP & Symfony con 2014Artificial Neural Networks with PHP & Symfony con 2014
Artificial Neural Networks with PHP & Symfony con 2014Eduardo Gulias Davis
 
Artificial Neural Network in a Tic Tac Toe Symfony Console Application - Symf...
Artificial Neural Network in a Tic Tac Toe Symfony Console Application - Symf...Artificial Neural Network in a Tic Tac Toe Symfony Console Application - Symf...
Artificial Neural Network in a Tic Tac Toe Symfony Console Application - Symf...aferrandini
 
Introduction to symfony2
Introduction to symfony2Introduction to symfony2
Introduction to symfony2Pablo Godel
 
Php symfony and software lifecycle
Php symfony and software lifecyclePhp symfony and software lifecycle
Php symfony and software lifecyclePierre Joye
 

Ähnlich wie Symfony Components (20)

симфони это не страшно
симфони   это не страшносимфони   это не страшно
симфони это не страшно
 
Drupal symfony
Drupal symfonyDrupal symfony
Drupal symfony
 
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 "Symfony 4 in action"
Fabien Potencier "Symfony 4 in action"Fabien Potencier "Symfony 4 in action"
Fabien Potencier "Symfony 4 in action"
 
Symfony Components in the wild
Symfony Components in the wildSymfony Components in the wild
Symfony Components in the wild
 
Running Symfony
Running SymfonyRunning Symfony
Running Symfony
 
Integrating symfony and Zend Framework
Integrating symfony and Zend FrameworkIntegrating symfony and Zend Framework
Integrating symfony and Zend Framework
 
Integrating symfony and Zend Framework (PHPNW09)
Integrating symfony and Zend Framework (PHPNW09)Integrating symfony and Zend Framework (PHPNW09)
Integrating symfony and Zend Framework (PHPNW09)
 
Integrating symfony and Zend Framework (PHPBarcelona 2009)
Integrating symfony and Zend Framework (PHPBarcelona 2009)Integrating symfony and Zend Framework (PHPBarcelona 2009)
Integrating symfony and Zend Framework (PHPBarcelona 2009)
 
Symfony: A Brief Introduction
Symfony: A Brief IntroductionSymfony: A Brief Introduction
Symfony: A Brief Introduction
 
An introduction to Symfony 2 for symfony 1 developers
An introduction to Symfony 2 for symfony 1 developersAn introduction to Symfony 2 for symfony 1 developers
An introduction to Symfony 2 for symfony 1 developers
 
CPAN For Private Code
CPAN For Private CodeCPAN For Private Code
CPAN For Private Code
 
Symfony2 components to the rescue of your PHP projects
Symfony2 components to the rescue of your PHP projectsSymfony2 components to the rescue of your PHP projects
Symfony2 components to the rescue of your PHP projects
 
A Glymse of Symfony 2
A Glymse of Symfony 2A Glymse of Symfony 2
A Glymse of Symfony 2
 
Symfony State Of The Union, March 2010
Symfony State Of The Union, March 2010Symfony State Of The Union, March 2010
Symfony State Of The Union, March 2010
 
Write Plugins for symfony (Symfony Camp 2007)
Write Plugins for symfony (Symfony Camp 2007)Write Plugins for symfony (Symfony Camp 2007)
Write Plugins for symfony (Symfony Camp 2007)
 
Artificial Neural Networks with PHP & Symfony con 2014
Artificial Neural Networks with PHP & Symfony con 2014Artificial Neural Networks with PHP & Symfony con 2014
Artificial Neural Networks with PHP & Symfony con 2014
 
Artificial Neural Network in a Tic Tac Toe Symfony Console Application - Symf...
Artificial Neural Network in a Tic Tac Toe Symfony Console Application - Symf...Artificial Neural Network in a Tic Tac Toe Symfony Console Application - Symf...
Artificial Neural Network in a Tic Tac Toe Symfony Console Application - Symf...
 
Introduction to symfony2
Introduction to symfony2Introduction to symfony2
Introduction to symfony2
 
Php symfony and software lifecycle
Php symfony and software lifecyclePhp symfony and software lifecycle
Php symfony and software lifecycle
 

Mehr von 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.4Fabien 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.3Fabien Potencier
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010Fabien Potencier
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010Fabien Potencier
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201Fabien Potencier
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Fabien 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.3Fabien Potencier
 
Symfony And Zend Framework Together 2009
Symfony And Zend Framework Together 2009Symfony And Zend Framework Together 2009
Symfony And Zend Framework Together 2009Fabien Potencier
 
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 PHPFabien Potencier
 
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)Fabien Potencier
 
The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)Fabien Potencier
 

Mehr von Fabien Potencier (19)

Varnish
VarnishVarnish
Varnish
 
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
 
Caching on the Edge
Caching on the EdgeCaching on the Edge
Caching on the Edge
 
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
 
The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010The state of Symfony2 - SymfonyDay 2010
The state of Symfony2 - SymfonyDay 2010
 
Dependency injection - phpday 2010
Dependency injection - phpday 2010Dependency injection - phpday 2010
Dependency injection - phpday 2010
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Symfony2 revealed
Symfony2 revealedSymfony2 revealed
Symfony2 revealed
 
Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3Dependency Injection with PHP 5.3
Dependency Injection with PHP 5.3
 
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
 
Playing With PHP 5.3
Playing With PHP 5.3Playing With PHP 5.3
Playing With PHP 5.3
 
Symfony And Zend Framework Together 2009
Symfony And Zend Framework Together 2009Symfony And Zend Framework Together 2009
Symfony And Zend Framework Together 2009
 
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
 
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
symfony: Un Framework Open-Source pour les Entreprises (Solutions Linux 2008)
 
The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)The symfony platform: Create your very own framework (PHP Quebec 2008)
The symfony platform: Create your very own framework (PHP Quebec 2008)
 

Kürzlich hochgeladen

The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 

Kürzlich hochgeladen (20)

The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 

Symfony Components

  • 1. The Symfony Components – Fabien Potencier
  • 2. Serial entrepreneur Developer by passion Founder of Sensio Creator and lead developer of Symfony On Twitter @fabpot On github http://www.github.com/fabpot http://fabien.potencier.org/ The Symfony Components – Fabien Potencier
  • 3. Standalone components for PHP 5.3 No dependency between them Used extensively in Symfony 2, the framework The Symfony Components – Fabien Potencier
  • 4. Low-level libraries needed by most websites The Symfony Components – Fabien Potencier
  • 5. Event Dispatcher Stable Output Escaper Stable Extracted from symfony 1 YAML Stable Routing Beta Console Stable Dependency Injection Container Stable Written from scratch for Symfony 2 Request Handler Stable Templating Stable The Symfony Components – Fabien Potencier
  • 6. YAML Event Dispatcher PHP Quebec 2009 Templating Dependency Injection Container Console Routing ConFoo 2010 Output Escaper Request Handler The Symfony Components – Fabien Potencier
  • 7. Download / Installation The Symfony Components – Fabien Potencier
  • 8. git clone git://github.com/symfony/symfony.git Main repository The Symfony Components – Fabien Potencier
  • 9. svn checkout http://svn.symfony-project.org/branches/2.0/ Git Mirror Synchronized every 15 minutes The Symfony Components – Fabien Potencier
  • 10. curl -O http://github.com/symfony/symfony/tarball/master tar zxpf symfony-symfony-XXXXXXX.tar.gz curl -O http://github.com/symfony/symfony/zipball/master unzip symfony-symfony-XXXXXXX.zip Nightly build The Symfony Components – Fabien Potencier
  • 11. app/ .../ Symfony/ Components/ Foundation/ Framework/ The Symfony Components – Fabien Potencier
  • 12. Autoloading Classes The Symfony Components – Fabien Potencier
  • 13. Before PHP 5.3 PEAR naming convention The Symfony Components – Fabien Potencier
  • 14. PEAR_Log > PEAR/Log.php Zend_Log > Zend/Log.php Swift_Mime_Message > Swift/Mime/Message.php Doctrine_Pager_Range > Doctrine/Pager/Range.php Twig_Node_For > Twig/Node/For.php The Symfony Components – Fabien Potencier
  • 15. PEAR_Log > PEAR/Log.php Zend_Log > Zend/Log.php Swift_Mime_Message > Swift/Mime/Message.php Doctrine_Pager_Range > Doctrine/Pager/Range.php Twig_Node_For > Twig/Node/For.php Vendor name The Symfony Components – Fabien Potencier
  • 16. As of PHP 5.3 PHP 5.3 technical interoperability standards The Symfony Components – Fabien Potencier
  • 17. SymfonyFoundationKernel > Symfony/Foundation/Kernel.php DoctrineDBALDriver > Doctrine/DBAL/Driver.php pdependreflectionReflectionSession > pdepend/reflection/ReflectionSession.php The Symfony Components – Fabien Potencier
  • 18. SymfonyFoundationKernel > Symfony/Foundation/Kernel.php DoctrineDBALDriver > Doctrine/DBAL/Driver.php pdependreflectionReflectionSession > pdepend/reflection/ReflectionSession.php Vendor name The Symfony Components – Fabien Potencier
  • 19. 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 The Symfony Components – Fabien Potencier
  • 20. use SymfonyFoundationUniversalClassLoader; The Symfony Components – Fabien Potencier
  • 21. require_once '.../Symfony/Foundation/UniversalClassLoader.php'; use SymfonyFoundationUniversalClassLoader; $loader = new UniversalClassLoader(); $loader->registerNamespace( 'Symfony', __DIR__.'/src/symfony/src' ); $loader->register(); // use any Symfony class The Symfony Components – Fabien Potencier
  • 22. $loader->registerNamespaces(array( 'Symfony' => '/path/to/symfony/src', 'Doctrine' => '/path/to/doctrine/lib', 'pdepend' => '/path/to/reflection/source', )); PHP 5.3 technical interoperability standards The Symfony Components – Fabien Potencier
  • 23. $loader->registerPrefixes(array( 'Swift_' => '/path/to/swiftmailer/lib/classes', 'Zend_' => '/path/to/vendor/zend/library', )); PEAR style The Symfony Components – Fabien Potencier
  • 24. require_once '.../Symfony/Foundation/UniversalClassLoader.php'; use SymfonyFoundationUniversalClassLoader; $loader = new UniversalClassLoader(); $loader->registerNamespaces(array( 'Symfony' => '/path/to/symfony/src', 'Doctrine' => '/path/to/doctrine/lib', )); $loader->registerPrefixes(array( 'Swift_' => '/path/to/swiftmailer/lib/classes', 'Zend_' => '/path/to/vendor/zend/library', )); $loader->register(); // use any class The Symfony Components – Fabien Potencier
  • 25. Console The Symfony Components – Fabien Potencier
  • 26. Console The Symfony Components – Fabien Potencier
  • 27. Automate things code generators deployment The Symfony Components – Fabien Potencier
  • 28. Long running tasks deployment get « things » from the Internet The Symfony Components – Fabien Potencier
  • 29. Batches cleanup a database from time to time migrate a DB to a new schema The Symfony Components – Fabien Potencier
  • 30. These tasks should never be run from a browser The Symfony Components – Fabien Potencier
  • 31. But PHP is a web language, right? The Symfony Components – Fabien Potencier
  • 32. So, why not use the right tool for the job? … like Perl or Python? The Symfony Components – Fabien Potencier
  • 33. Don’t want to use/learn another language Want to share code The Symfony Components – Fabien Potencier
  • 34. PHP natively supports the CLI environment The Symfony Components – Fabien Potencier
  • 35. <?php // ... The Symfony Components – Fabien Potencier
  • 36. #!/usr/bin/env php <?php // ... $ ./foo … The Symfony Components – Fabien Potencier
  • 37. $ ./foobar Fabien $name = $argv[1]; echo 'Hello '.$name; The Symfony Components – Fabien Potencier
  • 38. … but the complexity lies in the details The Symfony Components – Fabien Potencier
  • 39. option / arguments handling exit codes shell output colorization tests error messages … The Symfony Components – Fabien Potencier
  • 40. $ ./life foo "foo bar" --foo foobar -b Array ( [0] => ./life [1] => foo [2] => foo bar [3] => --foo [4] => foobar [5] => -b ) The Symfony Components – Fabien Potencier
  • 41. don’t reinvent the wheel… use a “framework” The Symfony Components – Fabien Potencier
  • 42. Console The Symfony Components – Fabien Potencier
  • 43. Let’s create a CLI tool to get the weather anywhere in the world The Symfony Components – Fabien Potencier
  • 44. The Symfony Components – Fabien Potencier
  • 45. use LifeYahooWeather; $weather = new YahooWeather('API_KEY', $argv[1]); echo $weather->getTitle()."n"; $attrs = $weather->getCurrentConditions(); echo "Current conditions:n"; echo sprintf(" %s, %sCn", $attrs['text'], $attrs['temp']); $attrs = $weather->getForecast(); echo sprintf("nForecast for %sn", $attrs['date']); echo sprintf(" %s, low: %s, high: %sn", $attrs['text'], $attrs['low'], $attrs['high']); The Symfony Components – Fabien Potencier
  • 46. use SymfonyComponentsConsoleApplication; $application = new Application(); $application->run(); The Symfony Components – Fabien Potencier
  • 47. $command = new Command('weather'); $command->setCode( function ($input, $output) { // do something } ); $application->addCommand($command); The Symfony Components – Fabien Potencier
  • 48. use SymfonyComponentsConsoleApplication; $application = new Application(); $application->addCommand(new WeatherCommand()); $application->run(); The Symfony Components – Fabien Potencier
  • 49. use SymfonyComponentsConsoleCommandCommand; use SymfonyComponentsConsoleInputInputInterface; use SymfonyComponentsConsoleOutputOutputInterface; class WeatherCommand extends Command { protected function configure() { $this->setName('weather'); } protected function execute(InputInterface $input, OutputInterface $output) { // do something } } The Symfony Components – Fabien Potencier
  • 50. Console The Output The Symfony Components – Fabien Potencier
  • 51. $output->writeln($weather->getTitle()); The Symfony Components – Fabien Potencier
  • 52. $output->writeln( sprintf('<info>%s</info>', $weather->getTitle()) ); $output->writeln("<comment>Conditions</comment>"); The Symfony Components – Fabien Potencier
  • 53. The Symfony Components – Fabien Potencier
  • 54. The Symfony Components – Fabien Potencier
  • 55. Console Getting help The Symfony Components – Fabien Potencier
  • 56. The Symfony Components – Fabien Potencier
  • 57. $application = new Application('Life Tool', '0.1'); The Symfony Components – Fabien Potencier
  • 58. class WeatherCommand extends Command { protected function configure() { $this->setName('weather') ->setDescription('Displays weather forecast') ->setHelp(<<<EOF The <info>weather</info> command displays weather forecast for a given city: <info>./life weather Paris</info> You can also change the default degree unit with the <comment>--unit</comment> option: <info>./life weather Paris --unit=c</info> <info>./life weather Paris -u c</info> EOF ); } The Symfony Components – Fabien Potencier
  • 59. The Symfony Components – Fabien Potencier
  • 60. The Symfony Components – Fabien Potencier
  • 61. $ ./life weather $ ./life weath $ ./life w The Symfony Components – Fabien Potencier
  • 62. Console The Input The Symfony Components – Fabien Potencier
  • 63. class WeatherCommand extends Command { protected function configure() { $definition = array( new InputArgument('place', InputArgument::OPTIONAL, 'The place name', 'Paris'), new InputOption('unit', 'u', InputOption::PARAMETER_REQUIRED, 'The degree unit', 'c'), ); $this->setDefinition($definition); The Symfony Components – Fabien Potencier
  • 64. The Symfony Components – Fabien Potencier
  • 65. protected function execute(InputInterface $input, OutputInterface $output) { $city = $input->getArgument('place'); $unit = $input->getOption('unit'); $output->writeln("<comment>Conditions</comment>"); } The Symfony Components – Fabien Potencier
  • 66. Console Error codes / Exit status The Symfony Components – Fabien Potencier
  • 67. The Symfony Components – Fabien Potencier
  • 68. The Symfony Components – Fabien Potencier
  • 69. protected function execute(InputInterface $input, OutputInterface $output) { $city = $input->getArgument('place'); $unit = $input->getOption('unit'); $output->writeln("<comment>Conditions</comment>"); return 120; } The Symfony Components – Fabien Potencier
  • 70. Console Interact with the user The Symfony Components – Fabien Potencier
  • 71. protected function interact($input, $output) { $city = $this->dialog->ask( $output, '<comment>Which city?</comment> (Paris)', 'Paris’ ); $input->setArgument('place', $city); } The Symfony Components – Fabien Potencier
  • 72. ./life weather --no-interaction The Symfony Components – Fabien Potencier
  • 73. dialog ask() askConfirmation() askAndValidate() formatter formatSection() formatBlock() ... your own The Symfony Components – Fabien Potencier
  • 74. class WeatherHelper extends Helper { public function __construct() { Output::setStyle('weather_hot', array('bg' => 'red', 'fg' => 'yellow')); Output::setStyle('weather_cold', array('bg' => 'blue', 'fg' => 'white')); } public function formatTemperature($temperature, $unit) { $style = $temperature < 0 ? 'weather_cold' : 'weather_hot'; return sprintf("<%s> %s%s </%s>", $style, $temperature, strtoupper($unit), $style); } public function getName() { return 'weather'; } } The Symfony Components – Fabien Potencier
  • 75. $output->writeln(sprintf( " %s, low: %s, high: %s", $attrs['text'], $this->weather->formatTemperature( $attrs['low'], $input->getOption('unit')), $this->weather->formatTemperature( $attrs['high'], $input->getOption('unit')) )); The Symfony Components – Fabien Potencier
  • 76. The Symfony Components – Fabien Potencier
  • 77. Console Testing The Symfony Components – Fabien Potencier
  • 78. $input = new ArrayInput( array('place' => 'Paris', '--unit' => 'C') ); $application->run($input); $input = new StringInput('Paris --unit=C'); $application->run($input); The Symfony Components – Fabien Potencier
  • 79. $stream = fopen('php://memory', 'a', false); $output = new StreamOutput($stream); $application->run($input, $output); rewind($output->getStream()); echo stream_get_contents($output->getStream()); The Symfony Components – Fabien Potencier
  • 80. $application = new Application(); // for testing $application->setCatchExceptions(false); $application->setAutoExit(false); The Symfony Components – Fabien Potencier
  • 81. echo $application->asXml(); The Symfony Components – Fabien Potencier
  • 82. $command = new WeatherCommand(); echo $command->asXml(); The Symfony Components – Fabien Potencier
  • 83. Create a PHAR archive out of your CLI tool for distribution The Symfony Components – Fabien Potencier
  • 84. $pharFile = 'life.phar’; if (file_exists($pharFile)) unlink($pharFile); $phar = new Phar($pharFile, 0, $this->application->getName()); $phar->setSignatureAlgorithm(Phar::SHA1); $phar->startBuffering(); // CLI Component files foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__.'/../symfony/src/Symfony/Components/ Console'), RecursiveIteratorIterator::LEAVES_ONLY) as $file) { $phar['Symfony/Components/Console'.str_replace(__DIR__.'/../symfony/src/Symfony/Components/Console', '', $file)] = file_get_contents($file); } // Life stuff foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(__DIR__.'/../Life'), RecursiveIteratorIterator::LEAVES_ONLY) as $file) { $phar['Life'.str_replace(__DIR__.'/../Life', '', $file)] = file_get_contents($file); } // Autoloader $phar['Symfony/Foundation/UniversalClassLoader.php'] = file_get_contents(__DIR__.'/../symfony/src/Symfony/Foundation/ UniversalClassLoader.php'); // Stubs $phar['_cli_stub.php'] = $this->getCliStub(); $phar['_web_stub.php'] = $this->getWebStub(); $phar->setDefaultStub('_cli_stub.php', '_web_stub.php'); $phar->stopBuffering(); $phar->compressFiles(Phar::GZ); unset($phar); The Symfony Components – Fabien Potencier
  • 85. git clone http://github.com/fabpot/confoo2010 The Symfony Components – Fabien Potencier
  • 86. Routing Pretty and Smart URLs The Symfony Components – Fabien Potencier
  • 88. Routing is a two-way process Matching incoming requests (URLs) Generating URLs The Symfony Components – Fabien Potencier
  • 89. The architecture is difficult to get right The Symfony Components – Fabien Potencier
  • 90. Symfony one is built with performance in mind The Symfony Components – Fabien Potencier
  • 91. Routing Describing your routes The Symfony Components – Fabien Potencier
  • 92. use SymfonyComponentsRoutingRouteCollection; use SymfonyComponentsRoutingRoute; $routes = new RouteCollection(); $route = new Route( '/', array('to' => function () { echo "Home!"; }) ); $routes->addRoute('home', $route); The Symfony Components – Fabien Potencier
  • 93. $route = new Route( '/:year/:month/:day/:slug', array('to' => function ($params) { var_export ($params); }), array('year' => 'd{4}') ); $routes->addRoute('blog_post', $route); The Symfony Components – Fabien Potencier
  • 94. Routing Matching URLs The Symfony Components – Fabien Potencier
  • 95. use SymfonyComponentsRoutingMatcherUrlMatcher; $matcher = new UrlMatcher($routes); if (false === $params = $matcher->match('/')) { throw new Exception('No route matches.'); } $params['to'](); The Symfony Components – Fabien Potencier
  • 96. $params = $matcher->match('/2010/03/10/confoo'); if (false === $params) { throw new Exception('No route matches.'); } $params['to']($params); The Symfony Components – Fabien Potencier
  • 97. array ( 'to' => Closure::__set_state(array( )), 'year' => '2010', 'month' => '03', 'day' => '10', 'slug' => 'confoo', '_route' => 'blog_post', ) The Symfony Components – Fabien Potencier
  • 98. $params = $matcher->match('/yyyy/03/10/confoo'); if (false === $params) { throw new Exception('No route matches.'); } $params['to']($params); Uncaught exception 'Exception' with message 'No route matches.' The Symfony Components – Fabien Potencier
  • 99. Routing Generating URLs The Symfony Components – Fabien Potencier
  • 100. use SymfonyComponentsRoutingGeneratorUrlGenerator; $generator = new UrlGenerator($routes); echo $generator->generate('home', array()); The Symfony Components – Fabien Potencier
  • 101. $params = array( 'year' => 2010, 'month' => 10, 'day' => 10, 'slug' => 'another-one' ); echo $generator->generate('blog_post', $params); The Symfony Components – Fabien Potencier
  • 102. $params = array( 'year' => 'yyyy', 'month' => 10, 'day' => 10, ); echo $generator->generate('blog_post', $params); Uncaught exception 'InvalidArgumentException' with message 'The "blog_post" route has some missing mandatory parameters (:slug).' The Symfony Components – Fabien Potencier
  • 103. use SymfonyComponentsRoutingGeneratorUrlGenerator; $generator = new UrlGenerator($routes); echo $generator->generate('home', array('foo' => 'bar')); /?foo=bar The Symfony Components – Fabien Potencier
  • 104. $generator = new UrlGenerator($routes, array( 'base_url' => '/myapp', 'host' => 'www.example.com', 'is_secure' => false, )); echo $generator->generate('home', array(), true); http://www.example.com/myapp/ The Symfony Components – Fabien Potencier
  • 105. The context makes the routing decoupled from the rest of the world base_url host is_secure method The Symfony Components – Fabien Potencier
  • 106. Routing Describing your routes with XML or YAML The Symfony Components – Fabien Potencier
  • 107. home: pattern: / defaults: { controller: home, action: index } blog_post: pattern: /:year/:month/:day/:slug defaults: controller: blog action: show requirements: year: d{4} The Symfony Components – Fabien Potencier
  • 108. use SymfonyComponentsRoutingLoaderYamlFileLoader; $loader = new YamlFileLoader(); $routes = $loader->load('routes.yml'); The Symfony Components – Fabien Potencier
  • 109. <?xml version="1.0" encoding="UTF-8" ?> <routes xmlns="http://www.symfony-project.org/schema/routing" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.symfony-project.org/schema/routing http://www.symfony-project.org/schema/routing/routing-1.0.xsd"> <route id="blog_post" pattern="/:year/:month/:day/:slug"> <default key="controller">blog</default> <default key="action">show</default> <requirement key="year">d{4}</requirement> </route> <route id="home" pattern="/"> <default key="controller">home</default> <default key="action">index</default> </route> </routes> The Symfony Components – Fabien Potencier
  • 110. use SymfonyComponentsRoutingLoaderXmlFileLoader; $loader = new XmlFileLoader(); $routes = $loader->load('routes.xml'); The Symfony Components – Fabien Potencier
  • 111. <?xml version="1.0" encoding="UTF-8" ?> <routes> <route id="home" pattern="/"> <default key="controller">home</default> <default key="action">index</default> </route> <import resource="blog.yml" prefix="/blog" /> <import resource="forum.xml" prefix="/forum" /> </routes> The Symfony Components – Fabien Potencier
  • 112. home: pattern: / defaults: { controller: home, action: index } import: - { resource: blog.yml, prefix: /blog } - { resource: forum.xml, prefix: /forum } The Symfony Components – Fabien Potencier
  • 113. $yamlLoader = new YamlFileLoader(); $xmlLoader = new XmlFileLoader(); $routes = new RouteCollection(); $route = new Route( '/', array('to' => function () { echo "Home!"; }) ); $routes->addRoute('home', $route); $routes->addCollection( $yamlLoader->load('blog.yml'), '/blog'); $routes->addCollection( $xmlLoader->load('forum.xml'), '/forum'); The Symfony Components – Fabien Potencier
  • 114. /blog/2010/03/10/confoo prefix pattern The Symfony Components – Fabien Potencier
  • 115. Routing Make it simple & fast The Symfony Components – Fabien Potencier
  • 116. use SymfonyComponentsRoutingRouter; $router = new Router($loader, $options, $context); The Symfony Components – Fabien Potencier
  • 117. $loader = function () { $routes = new RouteCollection(); // ... return $routes; }; $context = array( 'base_url' => '/myapp', 'host' => 'www.example.com', 'is_secure' => false, ); $options = array( 'cache_dir' => '/tmp/routing', 'debug' => true, ); The Symfony Components – Fabien Potencier
  • 118. $router = new Router($loader, $options, $context); if (false === $params = $router->match('/')) { throw new Exception('No route matches.'); } echo $router->generate('home', array()); The Symfony Components – Fabien Potencier
  • 119. class ProjectUrlMatcher extends SymfonyComponentsRouting MatcherUrlMatcher { // ... public function match($url) { $url = $this->normalizeUrl($url); if (preg_match('#^/$#x', $url, $matches)) return array_merge($this->mergeDefaults($matches, array ( 'to' => 'foo',)), array('_route' => 'home')); return false; } } The Symfony Components – Fabien Potencier
  • 120. class ProjectUrlGenerator extends SymfonyComponentsRoutingGeneratorUrlGenerator { // ... public function generate($name, array $parameters, $absolute = false) { if (!method_exists($this, $method = 'get'.$name.'RouteInfo')) { throw new InvalidArgumentException(sprintf('Route "%s" does not exist.', $name)); } list($variables, $defaults, $requirements, $tokens) = $this->$method(); return $this->doGenerate($variables, $defaults, $requirements, $tokens, $parameters, $name, $absolute); } protected function gethomeRouteInfo() { return array(array (), array_merge($this->defaults, array ( 'to' => 'foo',)), array (), array ( 0 => array ( 0 => 'text', 1 => '/', 2 => '', 3 => NULL, ),)); } } The Symfony Components – Fabien Potencier
  • 121. use SymfonyComponentsRoutingFileResource; $loader = function () { $routes = new RouteCollection(); // ... $routes->addResource(new FileResource(__FILE__)); return $routes; }; The Symfony Components – Fabien Potencier
  • 122. Routing Make it really fast The Symfony Components – Fabien Potencier
  • 123. use SymfonyComponentsRoutingMatcherDumper ApacheMatcherDumper; $dumper = new ApacheMatcherDumper($routes); echo $dumper->dump(); The Symfony Components – Fabien Potencier
  • 124. RewriteCond %{PATH_INFO} ^/$ RewriteRule .* index.php [QSA,L,E=_ROUTING__route:home,E=_ROUTING_to:foo ] The Symfony Components – Fabien Potencier
  • 125. $options = array( 'cache_dir' => '/tmp/routing', 'debug' => true, 'matcher_class' => 'SymfonyComponents RoutingMatcherApacheUrlMatcher', ); The Symfony Components – Fabien Potencier
  • 126. Output Escaper The Symfony Components – Fabien Potencier
  • 127. Provides XSS protection for your PHP templates The Symfony Components – Fabien Potencier
  • 128. Wraps template variables Works for strings arrays objects properties methods __call(), __get(), … Iterators, Coutables, … … Works for deep method calls The Symfony Components – Fabien Potencier
  • 129. use SymfonyComponentsOutputEscaperEscaper; $title = 'Foo <br />'; echo Escaper::escape('htmlspecialchars', $title); The Symfony Components – Fabien Potencier
  • 130. use SymfonyComponentsOutputEscaperEscaper; $article = array( 'title' => 'Foo <br />', 'author' => array( 'name' => 'Fabien <br/>', ) ); $article = Escaper::escape('htmlspecialchars', $article); echo $article['title']."n"; echo $article['author']['name']."n"; The Symfony Components – Fabien Potencier
  • 131. 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 function getAuthor() { return $this->author; } public method returning public function __get($key) { return $this->$key; } another object public function __call($method, $arguments) { magic __get() return $this->{'get'.$method}(); magic __call() } } The Symfony Components – Fabien Potencier
  • 132. class Author { protected $name; public function __construct($name) { $this->name = $name; } public function getName() { return $this->name; } } The Symfony Components – Fabien Potencier
  • 133. use SymfonyComponentsOutputEscaperEscaper; $article = new Article( 'foo <br />', new Author('Fabien <br />') ); $article = Escaper::escape('htmlspecialchars', $article); echo $article->getTitle()."n"; echo $article->getAuthor()->getName()."n"; echo $article->full_title."n"; echo $article->title."n"; echo $article->title()."n"; The Symfony Components – Fabien Potencier
  • 134. explicitly ask for raw data echo $article->getHtmlContent('raw'); echo $article->getTitle('js'); change the default escaping strategy The Symfony Components – Fabien Potencier
  • 135. Request Handler The Symfony Components – Fabien Potencier
  • 136. use SymfonyComponentsRequestHandlerRequest; $request = new Request(); $request->getPathInfo(); $request->getPreferredLanguage(array('en', 'fr')); $request->isXmlHttpRequest(); The Symfony Components – Fabien Potencier
  • 137. use SymfonyComponentsRequestHandlerRequest; $request = new Request(array( 'request' => $_POST, 'query' => $_GET, 'path' => array(), 'server' => $_SERVER, )); The Symfony Components – Fabien Potencier
  • 138. use SymfonyComponentsRequestHandlerResponse; $response = new Response('Hello World', 200, array('Content-Type' => 'text/plain')); $response->send(); $response->setHeader('Content-Type', 'text/plain'); $response->setCookie('foo', 'bar'); $response->setContent('Hello World'); $response->setStatusCode(200); The Symfony Components – Fabien Potencier
  • 139. Request Handler Framework to build Frameworks The Symfony Components – Fabien Potencier
  • 140. use SymfonyComponentsRequestHandlerRequest; use SymfonyComponentsRequestHandlerResponse; use SymfonyComponentsRequestHandlerRequestHandler; $handler = new RequestHandler($dispatcher); $request = new Request(); $response = $handler->handle($request); $response->send(); The Symfony Components – Fabien Potencier
  • 141. use SymfonyComponentsEventDispatcherEventDispatcher; use SymfonyComponentsEventDispatcherEvent; $dispatcher = new EventDispatcher(); $dispatcher->connect('core.load_controller', function (Event $event) { $event->setReturnValue(array( function ($request) { return new Response('Hello!'); }, array($event['request']) )); return true; }); The Symfony Components – Fabien Potencier
  • 142. Request Handler A small Framework The Symfony Components – Fabien Potencier
  • 143. $framework = new Framework(array( '/' => function ($request) { $content = 'Hello '. $request->getParameter('name'); return new Response($content); } )); $framework->run(); The Symfony Components – Fabien Potencier
  • 144. class Framework { protected $map; public function __construct($map) { $this->map = $map; } public function run() { $dispatcher = new EventDispatcher(); $dispatcher->connect('core.load_controller', array($this, 'loadController')); $handler = new RequestHandler($dispatcher); $response = $handler->handle(new Request()); $response->send(); } } The Symfony Components – Fabien Potencier
  • 145. public function loadController(Event $event) { $request = $event['request']; $routes = new RouteCollection(); foreach ($this->map as $pattern => $to) { $route = new Route($pattern, array('to' => $to)); $routes->addRoute(str_replace('/', '_', $pattern), $route); } $matcher = new UrlMatcher($routes, array( 'base_url' => $request->getBaseUrl(), 'method' => $request->getMethod(), 'host' => $request->getHost(), 'is_secure' => $request->isSecure(), )); $parameters = $matcher->match($request->getPathInfo()); if (false === $parameters) { return false; } $request->setPathParameters($parameters); $event->setReturnValue(array($parameters['to'], array($request))); return true; } The Symfony Components – Fabien Potencier
  • 146. $framework = new Framework(array( '/' => function ($request) { $content = 'Hello '. $request->getParameter('name'); return new Response($content); } )); $framework->run(); The Symfony Components – Fabien Potencier
  • 147. Questions? The Symfony Components – Fabien Potencier
  • 148. 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/ The Symfony Components – Fabien Potencier