+ All Categories
Home > Technology > Symfony components in the wild, PHPNW12

Symfony components in the wild, PHPNW12

Date post: 06-May-2015
Category:
Upload: jakub-zalas
View: 2,291 times
Download: 2 times
Share this document with a friend
Description:
Symfony is a set of reusable and decoupled PHP components designed to solve common web development problems. While as a framework it might not be the best for some of your projects, you can always build on top of its solid foundation of well written, tested and flexible components. Original presentation: https://docs.google.com/presentation/pub?id=136blt1DWJ95yuEdpmjz9dIqgg38VwEXBQlY7bu0Op8w&start=false&loop=false&delayms=3000
51
Symfony components in the wild Jakub Zalas
Transcript
Page 1: Symfony components in the wild, PHPNW12

Symfony components in

the wild Jakub Zalas

Page 2: Symfony components in the wild, PHPNW12

o  Remembers symfony 1.0 (2007)

o  Open Source contributor

o  BDD advocate

o  Works at Sensio Labs UK

o  ZCE & Sensio Labs Certi"ed Symfony Developer

Who am I?

o  Twitter: @jakub_zalas

o  Blog: http://zalas.eu

o  Github: @jakzal

Page 3: Symfony components in the wild, PHPNW12

What is Symfony?

First, Symfony2 is a reusable set

of standalone, decoupled, and cohesive

PHP components

that solve common web development problems.

Then, based on these components, Symfony2 is also a full-stack web framework.

http://fabien.potencier.org/article/49/what-is-symfony2 http://www.sxc.hu/photo/1197009

Page 4: Symfony components in the wild, PHPNW12

Why does it matter?

* 76% of statistics found on the Internet is made up

http://www.sxc.hu/photo/1223174

Page 5: Symfony components in the wild, PHPNW12

Reinventing the wheel

http://flic.kr/p/Mu9m2

Page 6: Symfony components in the wild, PHPNW12

Maintenance hell

http://www.sxc.hu/photo/1005333

Page 7: Symfony components in the wild, PHPNW12

Symfony components

Finder Process

Console HttpFoundation

ClassLoader

Routing HttpKernel

EventDispatcher

DependencyInjection

Security

CssSelector

DomCrawler BrowserKit

Yaml

Con"g

Locale

Serializer

Templating

Translation

OptionsResolver

Form

Filesystem

Validator

http://www.sxc.hu/photo/338038

Page 8: Symfony components in the wild, PHPNW12
Page 9: Symfony components in the wild, PHPNW12

HttpFoundation

http://www.sxc.hu/photo/1212545

Page 10: Symfony components in the wild, PHPNW12

use Symfony\Component\HttpFoundation\Request;

use Symfony\Component\HttpFoundation\Response;

$request = Request::createFromGlobals();

$name = $request->query->get('name', 'PHPNW');

$message = "Hello $name!";

$response = new Response($message, 200);

$response->headers->set('X-REQUEST-NAME', $name);

$response->headers->setCookie(new Cookie('phpnw', $name));

$response->send();

Page 11: Symfony components in the wild, PHPNW12

use Symfony\Component\HttpFoundation\Request;

use Symfony\Component\HttpFoundation\Response;

$request = Request::createFromGlobals();

$name = $request->query->get('name', 'PHPNW');

$message = "Hello $name!";

$response = new Response($message, 200);

$response->headers->set('X-REQUEST-NAME', $name);

$response->headers->setCookie(new Cookie('phpnw', $name));

$response->send();

$request->request

$request->query

$request->server

$request->files

$request->cookies

$request->headers

$request->attributes

Page 12: Symfony components in the wild, PHPNW12

$request = Request::createFromGlobals();

$session = $request->getSession();

if ($session->has('referrer')) {

$referrer = $session->get('referrer');

return new RedirectResponse($referrer);

}

if ($session->hasFlash('notice')) {

return new Response($session->getFlash('notice'));

} else {

$session->setFlash('notice', 'Hello again!');

return new Response('Foo')

}

Page 13: Symfony components in the wild, PHPNW12

$request = Request::createFromGlobals();

$date = getPageUpdatedAtById($request->query->get('id'));

$response = new Response();

$response->setPublic();

$response->setLastModified($date);

if ($response->isNotModified($request)) {

return $response;

}

// else do heavy processing to render the page

Page 14: Symfony components in the wild, PHPNW12

•  is there HTTPS in the server vars? is it 'on' or '1'? •  or is there SSL_HTTPS header? is it 'on' or '1'? •  or is there X_FORWARDED_PROTO header set to 'https'

How to check if a request is made over ssl?

if ($request->isSecure()) { // we're fine }

Page 15: Symfony components in the wild, PHPNW12

Routing

http://www.sxc.hu/photo/1070609

Page 16: Symfony components in the wild, PHPNW12

use Symfony\Component\Routing\RouteCollection;

use Symfony\Component\Routing\Route;

$routes = new RouteCollection();

$routes->add('hello', new Route('/hello/{name}', array(

'controller' => 'HelloController'

)));

$routes->add('homepage', new Route('/', array(

'controller' => 'HomepageController'

)));

Page 17: Symfony components in the wild, PHPNW12

use Symfony\Component\Routing\Matcher\UrlMatcher;

use Symfony\Component\Routing\RequestContext;

$matcher = new UrlMatcher($routes, new RequestContext());

$parameters = $matcher->match('/');

var_dump($parameters);

// array(

// 'controller' => 'HomepageController',

// '_route' => 'homepage'

// )

Page 18: Symfony components in the wild, PHPNW12

use Symfony\Component\Routing\Matcher\UrlMatcher;

use Symfony\Component\Routing\RequestContext;

$matcher = new UrlMatcher($routes, new RequestContext());

$parameters = $matcher->match('/hello/PHPNW');

var_dump($parameters);

// array(

// 'controller' => 'HelloController',

// 'name' => 'PHPNW',

// '_route' => 'hello'

// )

Page 19: Symfony components in the wild, PHPNW12

use Symfony\Component\Routing\Matcher\UrlMatcher;

use Symfony\Component\Routing\RequestContext;

$matcher = new UrlMatcher($routes, new RequestContext());

$parameters = $matcher->match('/hello/PHPNW');

var_dump($parameters);

// array(

// 'controller' => 'HelloController',

// 'name' => 'PHPNW',

// '_route' => 'hello'

// )

$routes->add('hello', new Route('/hello/{name}', array(

'controller' => 'HelloController'

)));

Page 20: Symfony components in the wild, PHPNW12

$routes = new RouteCollection();

$routes->add('hello', new Route(

'/hello/{name}',

array('controller' => 'HelloController'),

array('name' => '^[a-zA-Z]+$')

));

$matcher = new UrlMatcher($routes, new RequestContext());

$parameters = $matcher->match('/hello/PHPNW');

var_dump($parameters);

// array(

// 'controller' => 'HelloController',

// 'name' => 'PHPNW',

// '_route' => 'hello'

// )

Page 21: Symfony components in the wild, PHPNW12

use Symfony\Component\Routing\Exception;

$routes = new RouteCollection();

$routes->add('hello', new Route(

'/hello/{name}',

array('controller' => 'HelloController'),

array('name' => '^[a-zA-Z]+$')

));

$matcher = new UrlMatcher($routes, new RequestContext());

try {

$matcher->match('/hello/PHPNW12');

} catch (Exception\ResourceNotFoundException $exception) {

die('Resource not found');

}

Page 22: Symfony components in the wild, PHPNW12

use Symfony\Component\Routing\Generator\UrlGenerator;

$generator = new UrlGenerator(

$routes, new RequestContext()

);

// "/hello/PHPNW"

$url = $generator->generate(

'hello', array('name' => 'PHPNW')

);

// "http://localhost/hello/PHPNW"

$url = $generator->generate(

'hello', array('name' => 'PHPNW'), true

);

Page 23: Symfony components in the wild, PHPNW12

EventDispatcher

http://www.sxc.hu/photo/715294

Page 24: Symfony components in the wild, PHPNW12

use Symfony\Component\EventDispatcher\EventDispatcher;

use Symfony\Component\EventDispatcher\Event;

$dispatcher = new EventDispatcher();

$dispatcher->addListener(

'received_hello',

function (Event $event) {

printf("Hello from listener 1!\n");

}

);

$dispatcher->addListener(

'received_hello',

function (Event $event) {

printf("Hello from listener 2!\n");

}

);

Page 25: Symfony components in the wild, PHPNW12

printf("Hello!\n");

$dispatcher->dispatch('received_hello', new Event());

Hello!

Hello from listener 1!

Hello from listener 2!

Page 26: Symfony components in the wild, PHPNW12

$dispatcher = new EventDispatcher();

$dispatcher->addListener(

'received_hello',

function (Event $event) {

printf("Hello from listener 1!\n");

},

0

);

$dispatcher->addListener(

'received_hello',

function (Event $event) {

printf("Hello from listener 2!\n");

},

10

);

Page 27: Symfony components in the wild, PHPNW12

printf("Hello!\n");

$dispatcher->dispatch('received_hello', new Event());

Hello!

Hello from listener 2!

Hello from listener 1!

Page 28: Symfony components in the wild, PHPNW12

$dispatcher = new EventDispatcher();

$dispatcher->addListener(

'received_hello',

function (Event $event) {

printf("Hello from listener 1!\n");

$event->stopPropagation();

}

);

$dispatcher->addListener(

'received_hello',

function (Event $event) {

printf("Hello from listener 2!\n");

}

);

Page 29: Symfony components in the wild, PHPNW12

printf("Hello!\n");

$dispatcher->dispatch('received_hello', new Event());

Hello!

Hello from listener 1!

Page 30: Symfony components in the wild, PHPNW12

$app = new \Silex\Application();

$app->after(

function (Request $request, Response $response) {

// http://phpnw.dev/?hello=1

if ($request->query->get('hello') === '1') {

$content = str_replace(

'</body>',

'Hello!!</body>',

$response->getContent()

);

$response->setContent($content);

}

}

);

$app->run();

Page 31: Symfony components in the wild, PHPNW12

// Silex/src/Silex/Application.php:304

public function after($callback, $priority = 0)

{

$this['dispatcher']->addListener(

SilexEvents::AFTER,

function (FilterResponseEvent $event)

use ($callback) {

call_user_func(

$callback,

$event->getRequest(),

$event->getResponse()

);

},

$priority

);

}

Page 32: Symfony components in the wild, PHPNW12

// Silex/src/Silex/Application.php:603

$this['dispatcher']->dispatch(SilexEvents::AFTER, $event);

Page 33: Symfony components in the wild, PHPNW12

HttpKernel

http://www.sxc.hu/photo/835732

Page 34: Symfony components in the wild, PHPNW12

$resolver = new ControllerResolver();

$httpKernel = new HttpKernel($dispatcher, $resolver);

$request = Request::create('/hello/PHPNW')

$response = $httpKernel->handle($request);

echo $response;

HTTP/1.0 200 OK

Cache-Control: no-cache

Date: Sat, 06 Oct 2012 14:32:14 GMT

Hello PHPNW

Page 35: Symfony components in the wild, PHPNW12

$matcher = new UrlMatcher($routes, new RequestContext());

$dispatcher = new EventDispatcher();

$dispatcher->addListener(

KernelEvents::REQUEST,

function (GetResponseEvent $event) use ($matcher) {

$request = $event->getRequest();

$pathInfo = $request->getPathInfo();

// array contains '_controler', 'name', '_route'

$parameters = $matcher->match($pathInfo);

$request->attributes->add($parameters);

}

);

Page 36: Symfony components in the wild, PHPNW12

use Symfony\Component\Routing\RouteCollection;

use Symfony\Component\Routing\Route;

$routes = new RouteCollection();

$routes->add('hello', new Route('/hello/{name}', array(

'_controller' => 'PhpnwController::hello'

)));

$routes->add('homepage', new Route('/', array(

'_controller' => 'PhpnwController::homepage'

)));

Page 37: Symfony components in the wild, PHPNW12

use Symfony\Component\HttpFoundation\Request;

use Symfony\Component\HttpFoundation\Response;

class PhpnwController

{

public function hello(Request $request, $name)

{

return new Response('Hello '.$name.PHP_EOL);

}

public function homepage(Request $request)

{

return new Response('Home sweet home'.PHP_EOL);

}

}

Page 38: Symfony components in the wild, PHPNW12

$response = $httpKernel->handle(Request::create('/bye'));

PHP Fatal error: Uncaught exception 'Symfony\Component\Routing\Exception\ResourceNotFoundException' in /home/vagrant/Projects/WildComponents/vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php:81

Page 39: Symfony components in the wild, PHPNW12

$dispatcher->addListener(

KernelEvents::EXCEPTION,

function (GetResponseForExceptionEvent $event) {

$message = $event->getException()->getMessage();

$response = new Response($message, 404);

$event->setResponse($response);

}

); HTTP/1.0 404 Not Found

Cache-Control: no-cache

Date: Sat, 06 Oct 2012 09:01:02 GMT

Unable to find the controller for path "/bye". Maybe you forgot to add the matching route in your routing configuration?

Page 40: Symfony components in the wild, PHPNW12

Console

http://www.sxc.hu/photo/910912

Page 41: Symfony components in the wild, PHPNW12

use Symfony\Component\Console\Command\Command;

use Symfony\Component\Console\Input\InputInterface;

use Symfony\Component\Console\Output\OutputInterface;

class HelloCommand extends Command

{

public function configure()

{

// configure the command [...]

}

protected function execute(InputInterface $input, OutputInterface $output)

{

// put your code here [...]

}

}

Page 42: Symfony components in the wild, PHPNW12

public function configure()

{

$this->setDescription('Outputs welcome message[...]');

$this->setHelp('Outputs welcome message.');

$this->addArgument(

'name',

InputArgument::OPTIONAL,

'The name to output to the screen',

'World'

);

}

Page 43: Symfony components in the wild, PHPNW12

$application = new Application('Demo', '1.0.0');

$application->add(new HelloCommand('hello'));

$application->run();

Page 44: Symfony components in the wild, PHPNW12
Page 45: Symfony components in the wild, PHPNW12

protected function execute(InputInterface $input,

OutputInterface $output)

{

$name = $input->getArgument('name');

$output->writeln(sprintf('Hello %s!', $name));

}

}

Page 46: Symfony components in the wild, PHPNW12

public function configure()

{

// [...]

$this->addOption(

'more',

'm',

InputOption::VALUE_NONE,

'Tell me more'

);

}

Page 47: Symfony components in the wild, PHPNW12

protected function execute(InputInterface $input,

OutputInterface $output)

{

$name = $input->getArgument('name');

$output->writeln(sprintf('Hello %s!', $name));

if ($input->getOption('more')) {

$output->writeln('It is really nice to meet you!');

}

}

}

Page 48: Symfony components in the wild, PHPNW12
Page 49: Symfony components in the wild, PHPNW12

How to start?

http://www.sxc.hu/photo/1092493

// composer.json

{

"require": {

"symfony/http-foundation": "2.1.2"

}

}

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

php composer.phar install

Page 50: Symfony components in the wild, PHPNW12

Why Symfony?

•  Good code covered by tests

•  Flexible

•  Secure

•  Stable API (@api annotation)

•  Long term support

•  Outstanding community

•  Wide adoption

Page 51: Symfony components in the wild, PHPNW12

Rate my talk: https://joind.in/6945

Thank you!

Interested in training? We're introducing Symfony Components trainings soon:

http://www.sensiolabs.co.uk/training/symfony2.html


Recommended