use Symfony\Component\HttpFoundation\Response;
$response = new Response();
$response->setCharset('UTF-8');
$response->setEtag('abcdef');
$response->headers->set('Content-Type', 'application/json');
if ($response->isNotModified($request)) {
$response->send();
}
$response->setContent('{ "name": "John Doe"}');
$response->setStatusCode(200);
$response->setPublic();
$response->setSharedMaxAge(3600);
$response->prepare($request);
$response->send();
Slide 21
Slide 21 text
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\RedirectResponse;
$cookie = new Cookie('user', 'hhamon', '+30 days');
$resp = new RedirectResponse('http://www.acme.com');
$resp->headers->setCookie($cookie);
$resp->send();
Cookies and Redirects
Slide 22
Slide 22 text
$storage = new NativeSessionStorage();
$session = new Session($storage);
$session->start();
// Saving data into the session
$session->set('cart', array(1, 2, 3));
$cart = $session->get('cart');
$session->save();
Session Management
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$routes = new RouteCollection();
$routes->add('post', new Route(
'/blog/{id}/{slug}',
array('controller' => 'BlogController::post'),
array('id' => '\d+')
));
PHP Con guration
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
$context = new RequestContext($_SERVER['REQUEST_URI']);
$matcher = new UrlMatcher($routes, $context);
$parameters = $matcher->match('/blog/42/symfony-2');
Request Matching
Slide 29
Slide 29 text
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\Generator\UrlGenerator;
// ...
$context = new RequestContext($_SERVER['REQUEST_URI']);
$generator = new UrlGenerator($routes, $context);
echo $generator->generate('post', array(
'id' => '42',
'slug' => 'symfony-components',
'page' => '2',
));
// Generates /blog/42/symfony-components?page=2
URLs Generator
Slide 30
Slide 30 text
$locator = new FileLocator(array(__DIR__.'/config'));
$router = new Router(
new YamlFileLoader($locator),
'routing.yml',
array('cache_dir' => __DIR__.'/cache'),
new RequestContext($_SERVER['REQUEST_URI']),
);
$params = $router->match('/blog/42/symfony');
$url = $router->generate('blog');
The All-in-One Router
namespace Symfony\Component\HttpKernel;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
interface HttpKernelInterface
{
const MASTER_REQUEST = 1;
const SUB_REQUEST = 2;
public function handle(
Request $request,
$type = self::MASTER_REQUEST, $catch = true);
}
The HttpKernel Interface
Slide 33
Slide 33 text
namespace Acme;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Routing\RouterInterface;
class Kernel implements HttpKernelInterface
{
private $router;
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true)
{
// ...
}
}
Designing a Kernel for a Legacy Application
namespace Acme\Controller;
use Symfony\Component\HttpFoundation\Response;
abstract class Controller
{
public function render($name, array $context = array())
{
$template = sprintf(__DIR__.'/../../../views/%s.php', $name);
if (!is_readable($template)) {
throw new \InvalidArgumentException('No "'. $template.'" template.');
}
extract($context);
ob_start();
include $template;
$content = ob_get_clean();
return new Response($content, 200);
}
}
The Base Controller Class
Slide 36
Slide 36 text
namespace Acme\Controller;
use Symfony\Component\HttpFoundation\Request;
class BlogController extends Controller
{
public function indexAction(Request $request)
{
// Get a list of recent posts
$posts = ...;
return $this->render('blog/index', array('posts' => $posts));
}
}
The BlogController Class
Slide 37
Slide 37 text
$request = Request::createFromGlobals();
$request->overrideGlobals();
$router = new Router(...);
$kernel = new Acme\Kernel($router);
$response = $kernel->handle($request);
$response->send();
index.php
class Article
{
public function save(Database $con)
{
$parser = new Markdown();
$html = $parser->toHTML($this->getContent());
$this->setHtmlContent($html);
$this->save($con);
$this->updateLuceneIndex();
}
}
Slide 41
Slide 41 text
use Symfony\Component\EventDispatcher\EventDispatcher;
// Declaring listeners
$l1 = array(new ArticleListener(), 'onPreSave');
$l2 = array(new LuceneListener(), 'onPostSave');
// Registering listeners
$dispatcher = new EventDispatcher();
$dispatcher->addListener('article.pre_save', $l1);
$dispatcher->addListener('article.post_save', $l2);
Registering Listeners in the Dispatcher
Slide 42
Slide 42 text
Setting the Dispatcher
use Symfony\Component\EventDispatcher\EventDispatcher;
class Article
{
private $dispatcher;
public function setDispatcher(EventDispatcher $dp)
{
$this->dispatcher = $dp;
}
}
Slide 43
Slide 43 text
Dispatching Events
class Article
{
// ...
public function save(Database $con)
{
$e = new ArticleEvent($this);
$this->dispatcher->dispatch('article.pre_save', $e);
$this->save($con);
$this->dispatcher->dispatch('article.post_save', $e);
}
}
Slide 44
Slide 44 text
The Listener
class ArticleListener
{
public function onPreSave(ArticleEvent $event)
{
$article = $event->article;
$markdown = $article->getContent();
$parser = new Markdown();
$html = $parser->toHTML($markdown);
$article->setHtmlContent($html);
}
}
Slide 45
Slide 45 text
Triggering the Registered Listeners
$markdown = 'Some **markdown**';
$article = new Article();
$article->setDispatcher($dispatcher);
$article->setMarkdownContent($markdown);
$article->save();
#!/usr/bin/env php
$loader = require __DIR__.'/vendor/autoload.php';
$loader->add('Hangman', __DIR__.'/src');
use Symfony\Component\Console\Application;
use Hangman\Command\HangmanPlayCommand;
$application = new Application();
$application->add(new HangmanPlayCommand());
$application->run();
The Console Script
Slide 60
Slide 60 text
namespace HangmanPlay\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class HangmanPlayCommand extends Command
{
protected function configure()
{
// ...
}
protected function execute(InputInterface $input, OutputInterface
$output)
{
// ...
}
}
Slide 61
Slide 61 text
namespace HangmanPlay\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
class HangmanPlayCommand extends Command
{
protected function configure()
{
// ...
}
protected function execute(InputInterface $input, OutputInterface
$output)
{
// ...
}
}
Slide 62
Slide 62 text
protected function configure()
{
$this
->setName('hangman:play')
->setDescription('Play the famous Hangman game')
->addArgument('name', InputArgument::REQUIRED, 'Your name')
->addOption('length', 'l', InputOption::VALUE_REQUIRED, 'The
word length', 8)
->setHelp(<<%command.name% command.
You can run the command like this:
$ php %command.full_name% hhamon --length=6
EOF);
}
Slide 63
Slide 63 text
protected function execute(InputInterface $input,
OutputInterface $output)
{
$words = new WordList();
$words->load(__DIR__.'/../../../data/words.txt');
$length = $input->getOption('length');
$name = $input->getArgument('name');
$game = new Game($words->getRandomWord($length));
// ...
}
Slide 64
Slide 64 text
protected function execute(InputInterface $input, OutputInterface
$output)
{
// ...
$dialog = $this->getHelperSet()->get('dialog');
$output->writeln('Welcome '.$name.' to the Hangman Game!');
while (!$game->isOver()) {
$letter = $dialog->ask($output, 'Type a letter: ');
$game->tryLetter($letter);
$output->writeLn(implode(' ', $game->getSolution()));
}
if ($game->isWon()) {
$output->writeln('Congratulations!');
} else {
$output->writeln('Game Over!');
}
}
$locator = new FileLocator(__DIR__);
$container = new ContainerBuilder();
$loader = new XmlFileLoader(
$container,
$locator
);
$loader->load('services.xml');
// Get the DBAL service
$db = $container->get('dbal');
$result = $db->execute('SELECT ...');
use Symfony\Component\Validator\Validator;
use Symfony\Component\Validator\Mapping\ClassMetadataFactory;
use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
use Symfony\Component\Validator\ConstraintValidatorFactory;
use Symfony\Component\Validator\Constraints\Email;
$validator = new Validator(
new ClassMetadataFactory(new StaticMethodLoader()),
new ConstraintValidatorFactory()
);
$validator->validateValue('[email protected]', new Email());
Slide 75
Slide 75 text
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints;
class Post
{
public $title;
public $body;
static public function loadValidatorMetadata(ClassMetadata $metadata)
{
$metadata->addPropertyConstraint('title', new Constraints\NotNull());
$metadata->addPropertyConstraint('title', new Constraints\NotBlank());
$metadata->addPropertyConstraint('body', new Constraints\Length(array(
'max' => 10
)));
}
}
Serialization is the process of
converting an object state
into a format that can be
stored and resurrected later
Wikipedia
Slide 82
Slide 82 text
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
// Register the normalizers
$normalizers[] = new GetSetMethodNormalizer();
// Register the encoders
$encoders[] = new JsonEncoder();
$encoders[] = new XmlEncoder();
// Create and initialize the serializer
$serializer = new Serializer($normalizers, $encoders);
use Symfony\Component\Locale\Locale;
// Get the country names for a locale or get all country codes
$countries = Locale::getDisplayCountries('pl');
$countryCodes = Locale::getCountries();
// Get the language names for a locale or get all language codes
$languages = Locale::getDisplayLanguages('fr');
$languageCodes = Locale::getLanguages();
// Get the locale names for a given code or get all locale codes
$locales = Locale::getDisplayLocales('en');
$localeCodes = Locale::getLocales();
// Get ICU versions
$icuVersion = Locale::getIcuVersion();
$icuDataVersion = Locale::getIcuDataVersion();