Symfony2 Architecture

Drupal Camp, Wrocław, 18 October 2014

Michał Pipa

About me

What is Symfony?

Symfony2 is a reusable set of standalone, decoupled, and cohesive PHP components that solve common web development problems.
Symfony2 is also a full-stack web framework.

What about MVC?

Symfony2 is an HTTP framework; it is a Request/Response framework.

Bridge

Bundle

Component

Components

  • Console
  • CssSelector
  • Expression Language
  • Finder
  • Process
  • YAML

Bridge

3rd party libraries integration

  • Monolog
  • Doctrine
  • Propel
  • Twig
  • Swiftmailer

Bundle

Plugin, just fancy name

Bundle

  • Doctrine
  • Propel
  • Twig
  • Swiftmailer

Dependency Injection Container

Dependency Injection


<?php

class Newsletter
{
    private $mailer;

    public function __construct()
    {
        $this->mailer = new MyMailer();
    }
}
                    

<?php

$newsletter = new Newsletter();
                    

Dependency Injection


<?php

interface Mailer
{
    public function send();
}
                    

Dependency Injection


<?php

class Newsletter
{
    private $mailer;

    public function __construct(Mailer $mailer)
    {
        $this->mailer = $mailer;
    }
}
                    

<?php

$mailer = new MyMailer();
$newsletter = new Newsletter($mailer);
                    

Dependency Injection


<?php

class Newsletter
{
    private $mailer;

    public function __construct(Mailer $mailer)
    {
        $this->mailer = $mailer;
    }
}
                    

<?php

$mailer = new FakeMailer();
$newsletter = new Newsletter($mailer);
                    

Dependency Injection Container


# app/config/config.yml
services:
    mailer:
        class:      MyMailer

    newsletter:
        class:      Newsletter
        arguments:  ["%mailer%"]
                    

Dependency Injection Container


<?php

use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();

// ...

$newsletter = $container->get('newsletter');
                    

Event Dispatcher

Provides tools that allow your application components to communicate with each other by dispatching events and listening to them.

Event Dispatcher


<?php

use Symfony\Component\EventDispatcher\EventDispatcher;

$dispatcher = new EventDispatcher();
                    

Event Dispatcher


<?php

$event = new Event();

$dispatcher->dispatch('order.create', $event);
                    

Event Dispatcher


<?php

class OrderListener
{
    public function onCreate(Event $event)
    {
        // do something
    }
}
                    

Event Dispatcher


<?php

$listener = new OrderListener();

$dispatcher->addListener('order.create', array($listener, 'onCreate'));
                    

Event Dispatcher


# app/config/config.yml

services:
  kernel.listener.order_listener:
    class: OrderListener
    tags:
      - { name: kernel.event_listener, event: order.create, method: onCreate }
                    

HttpFoundation

The HttpFoundation component defines an object-oriented layer for the HTTP specification.

HttpFoundation

  • Request
  • Response
  • Session

HttpKernel

The HttpKernel component provides a structured process for converting a Request into a Response by making use of the EventDispatcher.

HttpKernel

  • Thin wrapper on top of the Request and Response classes to standardize the way requests are handled
  • Provides extension points and tools for web frameworks
  • HttpKernel class
  • HttpKernelInterface

HttpKernelInterface


<?php

namespace Symfony\Component\HttpKernel;

use Symfony\Component\HttpFoundation\Request;

interface HttpKernelInterface
{
    /**
     * @return Response A Response instance
     */
    public function handle(
        Request $request,
        $type = self::MASTER_REQUEST,
        $catch = true
    );
}
                    

HttpKernel events

  • kernel.request
  • kernel.controller
  • kernel.view
  • kernel.response
  • kernel.terminate

The kernel.request Event

Typical Purposes: To add more information to the Request, initialize parts of the system, or return a Response if possible (e.g. a security layer that denies access).

The kernel.request Event

The kernel.request Event

Source

The kernel.request Event

The kernel.request Event

Source

The kernel.request in the Symfony Framework

  • RouterListener

Resolve the Controller

Resolve the Controller

Source

ControllerResolverInterface


<?php

namespace Symfony\Component\HttpKernel\Controller;

use Symfony\Component\HttpFoundation\Request;

interface ControllerResolverInterface
{
    public function getController(Request $request);

    public function getArguments(Request $request, $controller);
}
                    

The kernel.controller Event

Typical Purposes: Initialize things or change the controller just before the controller is executed.

The kernel.controller Event

The kernel.controller Event

Source

The kernel.controller in the Symfony Framework

  • @ParamConverter

Getting the Controller Arguments

Getting the Controller Arguments

Source

Calling the Controller

Calling the Controller

Source

Calling the Controller

Calling the Controller

Source

The kernel.view Event

Typical Purposes: Transform a non-Response return value from a controller into a Response

The kernel.view Event

The kernel.view Event

Source

The kernel.view in the Symfony Framework

  • @Template
  • FOSRestBundle

The kernel.response Event

Typical Purposes: Modify the Response object just before it is sent

The kernel.response in the Symfony Framework

  • WebDebugToolbarListener
  • ContextListener serializes the current user's information into the session so that it can be reloaded on the next request

The kernel.terminate Event

Typical Purposes: To perform some "heavy" action after the response has been streamed to the user

The kernel.terminate Event


<?php

// send the headers and echo the content
$response->send();

// triggers the kernel.terminate event
$kernel->terminate($request, $response);
                    

kernel.terminate in the Symfony Framework

  • EmailSenderListener

The kernel.exception Event

Typical Purposes: Handle some type of exception and create an appropriate Response to return for the exception

The kernel.exception Event

The kernel.exception Event

Source

Thank you

Questions?