Your SlideShare is downloading. ×
0
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Symfony Components
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Symfony Components

15,686

Published on

Published in: Technology
2 Comments
32 Likes
Statistics
Notes
No Downloads
Views
Total Views
15,686
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
408
Comments
2
Likes
32
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 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
  • 87. http://example.com/article.php?id=44 http://example.com/article/confoo-2010 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

×