symfony components in the wild, phpnw12
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=3000TRANSCRIPT
Symfony components in
the wild Jakub Zalas
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
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
Why does it matter?
* 76% of statistics found on the Internet is made up
http://www.sxc.hu/photo/1223174
Reinventing the wheel
http://flic.kr/p/Mu9m2
Maintenance hell
http://www.sxc.hu/photo/1005333
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
HttpFoundation
http://www.sxc.hu/photo/1212545
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();
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
$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')
}
$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
• 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 }
Routing
http://www.sxc.hu/photo/1070609
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'
)));
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'
// )
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'
// )
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'
)));
$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'
// )
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');
}
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
);
EventDispatcher
http://www.sxc.hu/photo/715294
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");
}
);
printf("Hello!\n");
$dispatcher->dispatch('received_hello', new Event());
Hello!
Hello from listener 1!
Hello from listener 2!
$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
);
printf("Hello!\n");
$dispatcher->dispatch('received_hello', new Event());
Hello!
Hello from listener 2!
Hello from listener 1!
$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");
}
);
printf("Hello!\n");
$dispatcher->dispatch('received_hello', new Event());
Hello!
Hello from listener 1!
$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();
// 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
);
}
// Silex/src/Silex/Application.php:603
$this['dispatcher']->dispatch(SilexEvents::AFTER, $event);
HttpKernel
http://www.sxc.hu/photo/835732
$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
$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);
}
);
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'
)));
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);
}
}
$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
$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?
Console
http://www.sxc.hu/photo/910912
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 [...]
}
}
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'
);
}
$application = new Application('Demo', '1.0.0');
$application->add(new HelloCommand('hello'));
$application->run();
protected function execute(InputInterface $input,
OutputInterface $output)
{
$name = $input->getArgument('name');
$output->writeln(sprintf('Hello %s!', $name));
}
}
public function configure()
{
// [...]
$this->addOption(
'more',
'm',
InputOption::VALUE_NONE,
'Tell me more'
);
}
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!');
}
}
}
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
Why Symfony?
• Good code covered by tests
• Flexible
• Secure
• Stable API (@api annotation)
• Long term support
• Outstanding community
• Wide adoption
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