Date post: | 06-May-2015 |
Category: |
Technology |
Upload: | jakub-zalas |
View: | 2,291 times |
Download: | 2 times |
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