+ All Categories
Home > Technology > The Wonderful World of Symfony Components

The Wonderful World of Symfony Components

Date post: 18-Oct-2014
Category:
View: 13,390 times
Download: 2 times
Share this document with a friend
Description:
Wow, Symfony Components! In this talk, we'll look at the history of PHP, and the struggles as a community to create shared libraries between our large community. Find out the significance of PSR-0 and Composer in *your* life and how you can leverage libraries from all of PHP in your projects. We'll also look at the most fundamental Symfony2 components - HttpFoundation, HttpKernel, EventDispatcher, & Routing - including those that have been adopted by Drupal 8. We'll also check out a bunch of the other interesting Symfony2 components that can be used as tools in any PHP project. The goal of this talk is to show you just how easy finding and using high quality libraries has become in PHP. By the end, you'll be excited and ready to high-five all of your PHP friends.
160
The Wonderful World of the Symfony Components by your friend: Ryan Weaver @weaverryan Friday, September 28, 12
Transcript
Page 1: The Wonderful World of Symfony Components

The Wonderful World of the Symfony Components

by your friend:

Ryan Weaver@weaverryan

Friday, September 28, 12

Page 2: The Wonderful World of Symfony Components

Who is this dude?

• That “Docs” guy

• KnpLabs US - Symfony consulting, training, Kumbaya

• Writer for KnpUniversity.comscreencasts

• Husband of the much more talented @leannapelham

knplabs.comgithub.com/weaverryan@weaverryan

Friday, September 28, 12

Page 3: The Wonderful World of Symfony Components

Intro

Life before components(The Desert of the Real)

Friday, September 28, 12

Page 4: The Wonderful World of Symfony Components

Symfony consists of 23 individual components

Friday, September 28, 12

Page 5: The Wonderful World of Symfony Components

Components are available via Composer

Friday, September 28, 12

Page 6: The Wonderful World of Symfony Components

Snooze...

Friday, September 28, 12

Page 7: The Wonderful World of Symfony Components

Who Cares?

Friday, September 28, 12

Page 8: The Wonderful World of Symfony Components

We Suck at Sharingand that sucks for you

@weaverryan

1

Friday, September 28, 12

Page 9: The Wonderful World of Symfony Components

Including External Libraries is Depressing

Friday, September 28, 12

Page 10: The Wonderful World of Symfony Components

The Big Bummer :(

@weaverryan

• How do I autoload their files?

• Does their library depend on anything else?

• How do I even store their files in my project?

Friday, September 28, 12

Page 11: The Wonderful World of Symfony Components

Include a Zend Framework 1 component in symfony1

Friday, September 28, 12

Page 12: The Wonderful World of Symfony Components

Friday, September 28, 12

Page 13: The Wonderful World of Symfony Components

manually download the library and commit it

into your project

Friday, September 28, 12

Page 14: The Wonderful World of Symfony Components

if you don’t want the WHOLE library, carefully delete everything except the dependent components

Friday, September 28, 12

Page 15: The Wonderful World of Symfony Components

autoloading is completely custom ... blah gross!

Friday, September 28, 12

Page 16: The Wonderful World of Symfony Components

Components are the key to mastering your framework

@weaverryan

2

Friday, September 28, 12

Page 17: The Wonderful World of Symfony Components

If PHP is big, we’ll thriveIf PHP is small, we’ll die

@weaverryan

3

Friday, September 28, 12

Page 18: The Wonderful World of Symfony Components

Communities

@weaverryan

PHP is Huge! Right?

http://www.flickr.com/photos/kitty-kat/

Friday, September 28, 12

Page 19: The Wonderful World of Symfony Components

@weaverryan

PHP > Ruby

Friday, September 28, 12

Page 20: The Wonderful World of Symfony Components

Fragmentation

@weaverryan

But fragmentation makes us tiny, isolated, and misguided trend-setters

http://www.flickr.com/photos/slpunk99/7329609744

Friday, September 28, 12

Page 21: The Wonderful World of Symfony Components

PHP frameworks < Rails

@weaverryanFriday, September 28, 12

Page 22: The Wonderful World of Symfony Components

I don’t want a damned CakePHP Plugin!

@weaverryan

CakePHP

CodeIgniter

Friday, September 28, 12

Page 23: The Wonderful World of Symfony Components

Fragmentation

@weaverryan

• More information we have to know

• Difficult to hire

• Disjointed forums, StackOverflow

• Interoperability? What’s that?

Friday, September 28, 12

Page 24: The Wonderful World of Symfony Components

Components are shareable across all of PHP

Friday, September 28, 12

Page 25: The Wonderful World of Symfony Components

Act 1

Making Sharing Sexy

Friday, September 28, 12

Page 26: The Wonderful World of Symfony Components

PHP Framework Interoperability Group

http://www.php-fig.org/

Friday, September 28, 12

Page 27: The Wonderful World of Symfony Components

The United Nations of PHP

Friday, September 28, 12

Page 28: The Wonderful World of Symfony Components

(A)

The Problem of Autoloading

Friday, September 28, 12

Page 29: The Wonderful World of Symfony Components

My Autoloader doesn’t like your PHPs

@weaverryan

• The symfony1 autoloader doesn’t know where ZF1 classes live. The Zf1 autoloader doesn’t know where symfony1 classes live

• Each library has its own autoloader that you must discover, configure and use

Friday, September 28, 12

Page 30: The Wonderful World of Symfony Components

like a town where every store has its own currency

Friday, September 28, 12

Page 31: The Wonderful World of Symfony Components

From The Mountain:PSR-0 Class Naming Conventions

@weaverryan

“Thou shalt name your classes by

following a predictable pattern”

Friday, September 28, 12

Page 32: The Wonderful World of Symfony Components

class:sfRequest

path:lib/vendor/symfony/???idk

Friday, September 28, 12

Page 33: The Wonderful World of Symfony Components

class:Symfony\Component\HttpFoundation\Request

path:vendor/symfony/src/Symfony/Component/HttpFoundation/Request.php

Friday, September 28, 12

Page 34: The Wonderful World of Symfony Components

use Symfony\Component\ClassLoader\UniversalClassLoader;

$loader = new UniversalClassLoader();$loader->registerNamespaces(array( 'Zend' => __DIR__.'/path/to/zf'));

$loader->register();

Friday, September 28, 12

Page 35: The Wonderful World of Symfony Components

(B)

Managing Vendors in your project

Friday, September 28, 12

Page 36: The Wonderful World of Symfony Components

Composer

Friday, September 28, 12

Page 37: The Wonderful World of Symfony Components

{ "require": { "zendframework/ldap": "2.0.x-dev" }}

1) Composer.json

Friday, September 28, 12

Page 38: The Wonderful World of Symfony Components

$ curl -s https://getcomposer.org/installer | php

$ php composer.phar install

2) Composer.phar

Friday, September 28, 12

Page 39: The Wonderful World of Symfony Components

require 'vendor/autoload.php';

use Zend\Ldap\Ldap;

$options = array(...);$ldap = new Ldap($options);

3) Use It

Friday, September 28, 12

Page 40: The Wonderful World of Symfony Components

Friday, September 28, 12

Page 41: The Wonderful World of Symfony Components

Act 2

Your friendly, neighborhood Symfony Components

Friday, September 28, 12

Page 42: The Wonderful World of Symfony Components

The Symfony Components• HttpFoundation• HttpKernel• Event Dispatcher• Routing• CSSSelector• DomCrawler• BrowserKit• Config• Yaml• DependencyInjection• Security

@weaverryan

• OptionsResolver• Console• Filesystem• Finder• Locale• Process• Serializer• Templating• Form• Translation• Validator

Friday, September 28, 12

Page 43: The Wonderful World of Symfony Components

The Symfony Components• HttpFoundation• HttpKernel• Event Dispatcher• Routing• CSSSelector• DomCrawler• BrowserKit• Config• Yaml• DependencyInjection• Security

@weaverryan

• OptionsResolver• Console• Filesystem• Finder• Locale• Process• Serializer• Templating• Form• Translation• Validator

The “Framework” Components

Friday, September 28, 12

Page 44: The Wonderful World of Symfony Components

Level 1

HttpFoundationsymfony/http-foundation

Friday, September 28, 12

Page 45: The Wonderful World of Symfony Components

@weaverryan

{ "require": { "symfony/http-foundation": "2.1.x-dev" }}

php composer.phar install

<?php// your app

require 'vendor/autoload.php';

1

2

3

Fun to Install!

Friday, September 28, 12

Page 46: The Wonderful World of Symfony Components

@weaverryan

Request/foo

Response<h1>Hi!</h1>

?

?

?

? ?

?

MysteryPHP Code

Friday, September 28, 12

Page 47: The Wonderful World of Symfony Components

The Request

Friday, September 28, 12

Page 48: The Wonderful World of Symfony Components

GET /foo?p=v1 HTTP/1.1Host: knplabs.comAccept: text/htmlUser-Agent: Mozilla/5.0

// /foo?p=v1$uri = $_SERVER['REQUEST_URI'];$p = isset($_GET['p']) ? $_GET['p'] : '';$host = $_SERVER['HTTP_HOST'];$accept = $_SERVER['HTTP_ACCEPT'];$ua = $_SERVER['HTTP_USER_AGENT'];

Friday, September 28, 12

Page 49: The Wonderful World of Symfony Components

use Symfony\Component\HttpFoundation\Request;$request = Request::createFromGlobals();

$uri = $request->getPathInfo(); /foo$p = $request->query->get('p');$host = $request->getHost();$accept = $request->headers->get('Accept');

GET /foo?p=v1 HTTP/1.1Host: knplabs.comAccept: text/htmlUser-Agent: Mozilla/5.0

Friday, September 28, 12

Page 50: The Wonderful World of Symfony Components

The Response

Friday, September 28, 12

Page 51: The Wonderful World of Symfony Components

HTTP/1.1 200 OKDate: Tue, 04 Jun 2011 21:05:05 GMTContent-Type: text/htmlSet-Cookie:foo=fooval; path=/; httponly

<h1>Foo!</h1>

header('Content-Type', 'text/html');setcookie('foo', 'fooval');echo '<h1>Foo!</h1>';

Friday, September 28, 12

Page 52: The Wonderful World of Symfony Components

HTTP/1.1 200 OKDate: Tue, 04 Jun 2011 21:05:05 GMTContent-Type: text/htmlSet-Cookie:foo=fooval; path=/; httponly

<h1>Foo!</h1>

use Symfony\Component\HttpFoundation\Response;use Symfony\Component\HttpFoundation\Cookie;

$response = new Response('<h1>Foo!</h1>');$cookie = new Cookie('foo', 'fooval');$response->headers->setCookie($cookie);

$response->send();Friday, September 28, 12

Page 53: The Wonderful World of Symfony Components

A Mini Framework

Friday, September 28, 12

Page 54: The Wonderful World of Symfony Components

// not dependable!$uri = $_SERVER['REQUEST_URI'];

ob_start();if ($uri == '/') { echo 'Homepage! \o/';} else { echo 'sad missing page :/';}

header('X-TOKEN: Foo');

ob_end_flush();Friday, September 28, 12

Page 55: The Wonderful World of Symfony Components

$req = Request::createFromGlobals();

if ($req->getPathInfo() == '/') { $res = new Response('Homepage! \o/');} else { $res = new Response('sad missing page :/');}

$res->headers->set('X-SECRET', 'Foo');

$res->send();

Symfony3

Friday, September 28, 12

Page 56: The Wonderful World of Symfony Components

Get some learning about HttpFoundation

@weaverryan

• Docs: http://bit.ly/sf2-http-foundation• Code: http://bit.ly/sf2-http-foundation-code• API: http://bit.ly/sf2-http-foundation-api

Friday, September 28, 12

Page 57: The Wonderful World of Symfony Components

Level 2

HttpKernelsymfony/http-kernel

Friday, September 28, 12

Page 58: The Wonderful World of Symfony Components

@weaverryan

FrameworkRequest

Determine the controller

?

? ?

Execute it

Flush the ResponseResponse

Friday, September 28, 12

Page 59: The Wonderful World of Symfony Components

Framework:

A pattern for converting a request into a response

Friday, September 28, 12

Page 60: The Wonderful World of Symfony Components

@weaverryan

FrameworkRequest

Determine the controller

?

? ?

Execute it

Flush the ResponseResponse

Friday, September 28, 12

Page 61: The Wonderful World of Symfony Components

@weaverryan

HttpKernelRequest

Determine the controller

?

? ?

Execute it

Flush the ResponseResponse

Friday, September 28, 12

Page 62: The Wonderful World of Symfony Components

$kernel = new HttpKernel(...);$request = Request::createFromGlobals();$response = $kernel->handle($request);$response->send();

There be magic inside!

Friday, September 28, 12

Page 63: The Wonderful World of Symfony Components

These lines execute your Symfony application

(hint, see - web/app.php)

Friday, September 28, 12

Page 64: The Wonderful World of Symfony Components

... and Drupal 8 too ...

Friday, September 28, 12

Page 65: The Wonderful World of Symfony Components

Yea, this is abstract

Stay Tuned...

Friday, September 28, 12

Page 66: The Wonderful World of Symfony Components

Level 3

EventDispatchersymfony/event-dispatcher

Friday, September 28, 12

Page 67: The Wonderful World of Symfony Components

@weaverryan

Event Dispatcher

A classic “observer pattern”

Listener

Listener

Tell me when Lizgets to work

Tell me when Lizgets to work

Friday, September 28, 12

Page 68: The Wonderful World of Symfony Components

@weaverryan

Event Dispatcher

• Event Dispatcher: a classic “observer pattern”

Listener

Listener

Yo! I’m at work!

Friday, September 28, 12

Page 69: The Wonderful World of Symfony Components

@weaverryan

Event Dispatcher

• Event Dispatcher: a classic “observer pattern”

Listener

Listener

Liz is atwork!

Liz is atwork!

Friday, September 28, 12

Page 70: The Wonderful World of Symfony Components

Event Dispatcher

• Event Dispatcher: a classic “observer pattern”

Listener

Listener

She’s the best around!

I’m totally going to go talk

with her!!

Friday, September 28, 12

Page 71: The Wonderful World of Symfony Components

Level 4

Routingsymfony/routing

Friday, September 28, 12

Page 72: The Wonderful World of Symfony Components

@weaverryan

RouterUrl

Match againsta route

Return infoabout the routeRoute

Route

Friday, September 28, 12

Page 73: The Wonderful World of Symfony Components

$loader = new ClosureLoader();$router = new Router($loader, function() { $collection = new RouteCollection();

$route = new Route('/blog/{slug}'); $collection->add('blog', $route);

return $collection;});$results = $router->match('/blog/sflive');

array( 'slug' => 'sflive', '_route' => 'blog',)

Friday, September 28, 12

Page 74: The Wonderful World of Symfony Components

$loader = new ClosureLoader();$router = new Router($loader, function() { $collection = new RouteCollection();

$route = new Route('/blog/{slug}', array( '_controller' => 'SomeBundle:Blog:show' )); $collection->add('blog', $route);

return $collection;});$results = $router->match('/blog/sflive');

array( '_controller' => 'SomeBundle:Blog:show', 'slug' => 'sflive', '_route' => 'blog')

Friday, September 28, 12

Page 75: The Wonderful World of Symfony Components

Input: Request Information

Output: An array of info

Friday, September 28, 12

Page 76: The Wonderful World of Symfony Components

Level 5

A “Framework”

Friday, September 28, 12

Page 77: The Wonderful World of Symfony Components

$kernel = new HttpKernel(...);$request = Request::createFromGlobals();$response = $kernel->handle($request);$response->send();

Friday, September 28, 12

Page 78: The Wonderful World of Symfony Components

@weaverryan

HttpKernel::handle()

HttpFoundation

+

EventDispatcher

+

Routing (optional)

=

Framework

Friday, September 28, 12

Page 79: The Wonderful World of Symfony Components

@weaverryan

HttpKernel::handle()

Request

+

Determine Controller

+

Controller Returns a Response

=

Response

Friday, September 28, 12

Page 80: The Wonderful World of Symfony Components

Homework:Hack your Framework

... or do Karaoke later... your call

Friday, September 28, 12

Page 81: The Wonderful World of Symfony Components

@weaverryan

HttpKernel::handleRaw()private function handleRaw(Request $request, $type = self::MASTER_REQUEST){    // request    $event = new GetResponseEvent($this, $request, $type);    $this->dispatcher->dispatch(KernelEvents::REQUEST, $event);

    if ($event->hasResponse()) {        return $this->filterResponse($event->getResponse(), $request, $type);    }

    // load controller    if (false === $controller = $this->resolver->getController($request)) {        throw new NotFoundHttpException('Unable to find the controller);    }

    $event = new FilterControllerEvent($this, $controller, $request, $type);    $this->dispatcher->dispatch(KernelEvents::CONTROLLER, $event);    $controller = $event->getController();

    // ... returns a response}

The kewlest code I know about... seriously

Friday, September 28, 12

Page 82: The Wonderful World of Symfony Components

@weaverryan

• Symfony\Component\HttpKernel\HttpKernel::handle()http://bit.ly/sf2-http-kernel-code

• Symfony Framework Important Classes

Symfony\Component\HttpKernel\EventListener\RouterListener- Executes the routing

Symfomy\Bundle\FrameworkBundle\Controller\ControllerResolver- Parses _controller and instantiates the controller object

step/var_dump()die; the core

Friday, September 28, 12

Page 83: The Wonderful World of Symfony Components

Timeline of events in the Symfony Framework

kernel.request

kernel.controller

kernel.response

Friday, September 28, 12

Page 84: The Wonderful World of Symfony Components

Profile events in the Symfony Framework

Friday, September 28, 12

Page 85: The Wonderful World of Symfony Components

The Symfony Components• HttpFoundation• HttpKernel• Event Dispatcher• Routing• CSSSelector• DomCrawler• BrowserKit• Config• Yaml• DependencyInjection• Security

@weaverryan

• OptionsResolver• Console• Filesystem• Finder• Locale• Process• Serializer• Templating• Form• Translation• Validator

AwesomeTools

Friday, September 28, 12

Page 86: The Wonderful World of Symfony Components

Process

symfony/process

Now with more Windows Love!

Friday, September 28, 12

Page 87: The Wonderful World of Symfony Components

@weaverryan

{ "require": { "symfony/process": "2.1.x-dev" }}

Find Symfony’s Process on Packagist.org

php composer.phar install

1

2

3

<?php// your app

require 'vendor/autoload.php';

Friday, September 28, 12

Page 88: The Wonderful World of Symfony Components

<?php// dinner.php

for ($i = 1; $i <= 3; $i++) { sleep(1); echo sprintf("Cooking... %s\n", $i);}

echo "DING! \n";

External Script to Cook Dinner

Friday, September 28, 12

Page 89: The Wonderful World of Symfony Components

Run the script synchronously

Friday, September 28, 12

Page 90: The Wonderful World of Symfony Components

// app.phprequire 'vendor/autoload.php';

use Symfony\Component\Process\Process;

$process = new Process('php dinner.php');// if dinner takes longer than 5 seconds// to cook, freak out!$process->setTimeout(5);

$process->run(function($type, $buffer) { echo $buffer;});

// executed after the command finishesif (!$process->isSuccessful()) { throw new \Exception('Process misbehaved')}

Friday, September 28, 12

Page 91: The Wonderful World of Symfony Components

Friday, September 28, 12

Page 92: The Wonderful World of Symfony Components

Run the script asynchronously

Friday, September 28, 12

Page 93: The Wonderful World of Symfony Components

$process = new Process('php dinner.php');$process->start();

// do more work hereecho "WORKING!!! \n";

while ($process->isRunning()) { // wait for the process to finish};echo $process->getOutput();

Friday, September 28, 12

Page 94: The Wonderful World of Symfony Components

Interacting via Stdin

Friday, September 28, 12

Page 95: The Wonderful World of Symfony Components

$process = new Process('php dinner.php');$process->setStdin('turkey');

“turkey” is read from Stdin

Friday, September 28, 12

Page 96: The Wonderful World of Symfony Components

$process = new Process('php dinner.php');$process->run(function($type, $buffer) { if ($type == 'err') { // perhaps do some logging? echo $buffer; }});

Handling things that blow up!

if (!$process->isSuccessful()) { echo sprintf( "Process failed! Exit code %s, '%s'\n", $process->getExitCode(), $process->getExitCodeText() );}

Friday, September 28, 12

Page 97: The Wonderful World of Symfony Components

Find out more about Process

@weaverryan

• Docs: http://bit.ly/sf2-process• Code: http://bit.ly/sf2-process-code• API: http://bit.ly/sf2-process-api

Friday, September 28, 12

Page 98: The Wonderful World of Symfony Components

SPORK!@kriswallsmith

$manager = new Spork\ProcessManager();$manager->fork(function() { // do something in another process! return 'Hello from '.getmypid();})->then(function(Spork\Fork $fork) { // do something in the parent process afterwards echo "{$fork->getPid()} says '{$fork->getResult()}'";});

Fork yourself some more PHP

https://github.com/kriswallsmith/spork

Friday, September 28, 12

Page 99: The Wonderful World of Symfony Components

Finder

symfony/finder

Friday, September 28, 12

Page 100: The Wonderful World of Symfony Components

From the Fablog

http://fabien.potencier.org/article/44/php-iterators-and-streams-are-awesome

use Symfony\Components\Finder\Finder; $s3 = new \Zend_Service_Amazon_S3($key, $secret);$s3->registerStreamWrapper("s3"); $finder = new Finder();$finder->name('photos*') ->size('< 100K') ->date('since 1 hour ago');foreach ($finder->in('s3://bucket-name') as $file) { // do something  print $file->getFilename()."\n";} 

Friday, September 28, 12

Page 101: The Wonderful World of Symfony Components

Find(er) out more about Finder

@weaverryan

• Docs: http://bit.ly/sf2-finder• Code: http://bit.ly/sf2-finder-code• API: http://bit.ly/sf2-finder-api

Friday, September 28, 12

Page 102: The Wonderful World of Symfony Components

Filesystem

symfony/filesystem

New in 2.1!

Friday, September 28, 12

Page 103: The Wonderful World of Symfony Components

@weaverryan

{ "require": { "symfony/filesystem": "2.1.x-dev" }}

Find Symfony’s Filesystem on Packagist.org

php composer.phar update symfony/filesystem

1

2

3

<?php// your app

require 'vendor/autoload.php';

Friday, September 28, 12

Page 104: The Wonderful World of Symfony Components

// ...

use Symfony\Component\Filesystem\Filesystem;

$filesystem = new Filesystem();$filesystem->copy( 'cowboy.jpg', 's3://my-bucket/cowboy.jpg');$filesystem->copy( 's3://my-bucket/rodeo.mov', 'rodeo.mov');$filesystem->mirror( 'thumbnails', 's3://my-bucket/thumbnails');

Friday, September 28, 12

Page 105: The Wonderful World of Symfony Components

// ...

use Symfony\Component\Filesystem\Filesystem;use Symfony\Component\Finder\Finder;

$finder = new Finder();$finder->name('*.jpg') ->date('since 1 hour ago'); ->in('thumbs');$filesystem = new Filesystem();$filesystem->chmod($finder, 0777);

Friday, September 28, 12

Page 106: The Wonderful World of Symfony Components

// ...

use Symfony\Component\Filesystem\Filesystem;

$filesystem = new Filesystem();$filesystem->touch('foo.txt');$filesystem->chmod('foo.txt', 0777);$filesystem->symlink('/some/dir', '/symlink/target')

Friday, September 28, 12

Page 107: The Wonderful World of Symfony Components

Find out more about Filesystem

@weaverryan

• Docs: http://bit.ly/sf2-filesystem• Code: http://bit.ly/sf2-filesystem-code• API: http://bit.ly/sf2-filesystem-api

Friday, September 28, 12

Page 108: The Wonderful World of Symfony Components

Console

symfony/console

Friday, September 28, 12

Page 109: The Wonderful World of Symfony Components

Friday, September 28, 12

Page 110: The Wonderful World of Symfony Components

<?php// command.php

$loader = require 'vendor/autoload.php';$loader->add('App', __DIR__);

use Symfony\Component\Console\Application;use App\Command\EchoCommand;

$app = new Application();$app->add(new EchoCommand());$app->run();

Friday, September 28, 12

Page 111: The Wonderful World of Symfony Components

namespace App\Command;

use Symfony\Component\Console\Command\Command;use Symfony\Component\Console\Input\InputInterface;use Symfony\Component\Console\Output\OutputInterface;

class EchoCommand extends Command{ protected function configure() { $this->setName('echo')->addArgument('msg'); }

public function execute( InputInterface $input, OutputInterface $output) { $output->writeln('Yo '.$input->getArgument('msg')); }}

Friday, September 28, 12

Page 112: The Wonderful World of Symfony Components

Output with pretty colors

Friday, September 28, 12

Page 113: The Wonderful World of Symfony Components

Find out more about Command

@weaverryan

• Docs http://bit.ly/sf2-console• Code http://bit.ly/sf2-console-code

• API http://api.symfony.com/master/namespaces.html-> and search for “Console”

Friday, September 28, 12

Page 114: The Wonderful World of Symfony Components

If you download Composer in the next 5 minutes, we’ll

throw in a special gift!

Friday, September 28, 12

Page 115: The Wonderful World of Symfony Components

CssSelector + DomCrawler

symfony/css-selectorsymfony/dom-crawler

Friday, September 28, 12

Page 116: The Wonderful World of Symfony Components

require 'vendor/autoload.php';use Symfony\Component\DomCrawler\Crawler;

$html = <<<'HTML'<!DOCTYPE html><html> <body> <p class="message">Hello World!</p> <p>Hello Crawler!</p> </body></html>HTML;

$crawler = new Crawler($html);

$crawler->filter('p')->eq(0)->attr('class');$crawler->filter('p')->eq(1)->text();

Friday, September 28, 12

Page 117: The Wonderful World of Symfony Components

Goutte!

Friday, September 28, 12

Page 118: The Wonderful World of Symfony Components

Config

symfony/config

Friday, September 28, 12

Page 119: The Wonderful World of Symfony Components

Config

@weaverryan

• Load configuration from many formats (YAML, PHP files, XML)

• Config Validation

• Caching for parsed config

Friday, September 28, 12

Page 120: The Wonderful World of Symfony Components

Validator

symfony/validator

Friday, September 28, 12

Page 121: The Wonderful World of Symfony Components

Shh... a little setup

Friday, September 28, 12

Page 122: The Wonderful World of Symfony Components

require 'vendor/autoload.php';

use Symfony\Component\Validator\Validator;use Symfony\Component\Validator\Mapping\ClassMetadataFactory;use Symfony\Component\Validator\ConstraintValidatorFactory;

// a little setup$metadata = new ClassMetadataFactory();$constraintFactory = new ConstraintValidatorFactory();$validator = new Validator($metadata, $constraintFactory);

Friday, September 28, 12

Page 123: The Wonderful World of Symfony Components

use Symfony\Component\Validator\Constraints\Email;

$value = 'ryan[AT]knplabs.com';$email = new Email();$email->message = 'Invalid! You entered {{ value }}';$errors = $validator->validateValue($value, $email);

if (count($errors) > 0) { echo strtr( $errors[0]->getMessageTemplate(), $errors[0]->getMessageParameters() );}

Friday, September 28, 12

Page 124: The Wonderful World of Symfony Components

34 Core Validators and counting• String length• Regular expressions• Ip addresses• Dates• Collections• File size, mime-type, etc

... and the brand new Luhn validatorfor credit card numbers thanks to@merk ----------------------------------->

@weaverryan

See the “Reference”section of the docs

Friday, September 28, 12

Page 125: The Wonderful World of Symfony Components

But wait there’s more!

Friday, September 28, 12

Page 126: The Wonderful World of Symfony Components

More Components

• DependencyInjection• Security• OptionsResolver• Locale• Serializer• Templating• Form• Translation

@weaverryanFriday, September 28, 12

Page 127: The Wonderful World of Symfony Components

Many components are easy

Friday, September 28, 12

Page 128: The Wonderful World of Symfony Components

Some are still wtf-hard

Friday, September 28, 12

Page 129: The Wonderful World of Symfony Components

(cough) Security (cough)

Friday, September 28, 12

Page 130: The Wonderful World of Symfony Components

DocumentationDocumentationDocumentation

Friday, September 28, 12

Page 131: The Wonderful World of Symfony Components

The Security Component

https://github.com/symfony/symfony-docs/pull/1604

WIP by @matthiasnoback

Friday, September 28, 12

Page 132: The Wonderful World of Symfony Components

Act 3

Kicking ass in the new PHP eco-system

Friday, September 28, 12

Page 133: The Wonderful World of Symfony Components

The PHP Ecosphere

• Symfony• Zend Framework• EZ Components• Drupal• ...• Individuals

@weaverryan

Symfony is only one part of the picture

What other stuff exists?

Friday, September 28, 12

Page 134: The Wonderful World of Symfony Components

How do we find good libraries?

Friday, September 28, 12

Page 135: The Wonderful World of Symfony Components

Friday, September 28, 12

Page 136: The Wonderful World of Symfony Components

Friday, September 28, 12

Page 137: The Wonderful World of Symfony Components

Some Favorites

Friday, September 28, 12

Page 138: The Wonderful World of Symfony Components

Minkbehat/mink

http://mink.behat.org/

By @everzet, written onFabien’s childhood computer

Friday, September 28, 12

Page 139: The Wonderful World of Symfony Components

Command a browser, find elements, click them, and fill out forms

$driver = new \Behat\Mink\Driver\SahiDriver('firefox');$session->visit('http://my_project.dev/some_page.php');

$page = $session->getPage();

$anchor = $page->find('css', '.something');$anchor->click();

// get the content of the new pageecho $page->getContent();

Friday, September 28, 12

Page 140: The Wonderful World of Symfony Components

Monologmonolog/monolog

https://github.com/Seldaek/monolog

Your Friend Jordi

Friday, September 28, 12

Page 141: The Wonderful World of Symfony Components

A Logger, where bells and whistles come standard

use Monolog\Logger;use Monolog\Handler\StreamHandler;use Monolog\Handler\FirePHPHandler;

// Create the logger$logger = new Logger('my_logger');$logger->pushHandler(new StreamHandler( __DIR__.'/my_app.log'));$logger->pushHandler(new FirePHPHandler());

$logger->addInfo('My logger is now ready');

Friday, September 28, 12

Page 142: The Wonderful World of Symfony Components

Zend Framework 2

They have some stuff

Friday, September 28, 12

Page 143: The Wonderful World of Symfony Components

Yay Find More!

Friday, September 28, 12

Page 144: The Wonderful World of Symfony Components

Epilogue

4 Reasons to getsilly-excited about

the Future

Friday, September 28, 12

Page 145: The Wonderful World of Symfony Components

1) Look for Participation & Consolidation

Friday, September 28, 12

Page 146: The Wonderful World of Symfony Components

Shared Building-blocks

• Drupal• phpBB• Midgard• Zikula• ez Publish 5• ...

@weaverryanFriday, September 28, 12

Page 147: The Wonderful World of Symfony Components

Less Library Duplication?

• Zend/Form• Zend/Serializer• Zend/Http• Zend/EventManager• Zend/Log• Zend/Navigation• ...

@weaverryan

• Symfony/Form• Symfony/Serializer• Symfony/HttpFoundation• Symfony/EventDispatcher• Monlog• KnpMenu• ...

Friday, September 28, 12

Page 148: The Wonderful World of Symfony Components

2) More high quality, community-grown libraries

Friday, September 28, 12

Page 149: The Wonderful World of Symfony Components

Solving 1 specific problem is a low barrier to entry

Friday, September 28, 12

Page 150: The Wonderful World of Symfony Components

Find them, fork them.

Friday, September 28, 12

Page 151: The Wonderful World of Symfony Components

Write their docs :)

Friday, September 28, 12

Page 152: The Wonderful World of Symfony Components

Programmers that write docs get hugs

Friday, September 28, 12

Page 153: The Wonderful World of Symfony Components

3) Easier upgrades

Friday, September 28, 12

Page 154: The Wonderful World of Symfony Components

4) Grow your Community

Friday, September 28, 12

Page 155: The Wonderful World of Symfony Components

Solutions exist outside of your framework

Friday, September 28, 12

Page 156: The Wonderful World of Symfony Components

Fabien will not come to your house and tell you about them

Friday, September 28, 12

Page 157: The Wonderful World of Symfony Components

Cast your vote by using the best libraries and improving

them

Friday, September 28, 12

Page 158: The Wonderful World of Symfony Components

and realize the power of the entire PHP community

Friday, September 28, 12

Page 159: The Wonderful World of Symfony Components

Thanks...

Ryan Weaver@weaverryan

Friday, September 28, 12

Page 160: The Wonderful World of Symfony Components

... and we love you!

Ryan Weaver@weaverryan

Ryan Weaver@weaverryan

https://joind.in/7218

Friday, September 28, 12


Recommended