SlideShare a Scribd company logo
1 of 45
Symfony Components & Friends
Michael Peacock, PHPNE August 2012
About Me
 @michaelpeacock
Head Developer @ Ground Six
  Leading the development team and managing the
  development process
  We are a tech investment company: you bring ideas, we
  partner and build the product
Author
Occasional Speaker
Symfony Components
Routing            YAML
Event dispatcher   Finder
Form               Dependency Injection
Process            HttpFoundation
Security           HttpKernel
Console            Locale
Friends


Pimple: dependency injection container
Twig: templating engine
Silex
Why?

Solve common web application problems
Incredibly well documented
Standalone: use them how you want
[Components] Ideal for:
  Refactoring
Installing
 Create a composer.json file in the root of your project
                    {
                          "require": {
                          	
                          "company/project": "version",
                          }
                    }


 Download Composer

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



 Run Composer

                        php composer.phar install
{



Routing
                                  "require": {
                                      "symfony/routing": "dev-master"
                                  }
                              }




Looks at the users request and converts it into a
Controller::method paid
Request Context: POST|GET|PUT|DELETE
Looks within a list of pre-defined routes
Returns a class name and a method
Defining Routes


YAML
PHP Code (A collection of Routes)
Annotations
comment_story_add:
  pattern: /news/{category}/{date}/{article}
  defaults: { class: 'CommentsController::addComment' }
  requirements:
    date: "[0-9]{2}-[0-9]{2}-[0-9]{4}"
    _method: POST
// look in our routes folder
$locator = new SymfonyComponentConfigFileLocator(array(__DIR__ . '/../../'));
$loader = new SymfonyComponentRoutingLoaderYamlFileLoader($locator);
// the URL the user requested / is visiting
$request = (isset($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : '';
// combine it with the request method to create a request context
$requestContext = new SymfonyComponentRoutingRequestContext($request,
$_SERVER['REQUEST_METHOD']);
// Create a router
$router = new SymfonyComponentRoutingRouter($locator, 'routes.yml',
array('cache_dir' => null), $requestContext);


try {
   $requestURL = (isset($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : '';
   $requestURL = (strlen($requestURL) > 1) ? rtrim($requestURL, '/') :
   $requestURL;
   $route = $this->router->match($requestURL);
   // explode the resulting route
   $usersRoute = explode('::', $route['class']);
   $controller = new $usersRoute[0]();
   $variables = $route;
   unset($variables['name']);
   unset($variables['class']);
   $action = $controller->$usersRoute[1]($container, $variables);
} catch (SymfonyComponentRoutingExceptionResourceNotFoundException $e) {
   header('HTTP/1.0 404 Not Found');
   die('Page not found.');
}
Event                      {
                               "require": {
                                   "symfony/event-dispatcher": "dev-master"


Dispatcher                 }
                               }




At key points in your application you create an event
Pass this event to the dispatcher
Observers listen for specific events
  Observers can be ordered - some events are observed by
  multiple observers
Example: Displaying a “flash notification”
  Set some sessions containing the notification
  Redirect the user
Event: Notify
 <?php
 namespace ProjectFrameworkEvents;

 class Notify extends RequestRedirection implements NotifiableMessageInterface
 {
     protected $notification;
     protected $class = 'notice';

     public function __construct($url = null, $notification = null, $class = 'notice')
     {
         parent::__construct($url);
         $this->class = $class;
         $this->notification = $notification;
     }

     public function getNotification()
     {
         return $this->notification;
     }

     public function getClass()
     {
         return $this->class;
     }

 }
<?php
namespace ProjectFrameworkEvents;

use SymfonyComponentEventDispatcherEvent;

class RequestRedirection extends Event
{
    protected $url;

    public function __construct($url = null)
    {
        $this->url = $url;
    }

    public function getURL()
    {
        return $this->url;
    }
}




           <?php
           namespace ProjectFrameworkEvents;

           interface NotifiableMessageInterface
           {
               public function getNotification();
               public function getClass();
           }
Listener: Set Notification
Session
<?php
namespace ProjectFrameworkListeners;

use ProjectFrameworkEvents;
use SymfonyComponentEventDispatcherEvent;

class SetPersistantNotification
{
    public function setNotification( EventsNotifiableMessageInterface $event )
    {
        $_SESSION['system_notification'] = $event->getNotification();
        $_SESSION['system_notification_class'] = $event->getClass();
    }

}
Listener: Redirect
  <?php
  namespace ProjectFrameworkListeners;
  use ProjectFrameworkEvents;
  use SymfonyComponentEventDispatcherEvent;
  class Redirect
  {
      public function redirectUser( EventsRequestRedirection $event )
      {
          header("Location: " . $event->getURL() );
          exit();
      }

  }
Dispatcher
        Create an event dispatcher

        Create instance of listener

        Add the listener

           Event name

           Callable: e.g. Object > Method array combo, Closure (event is passed)

           Priority: for multiple listeners listening for the same event

$dispatcher = new EventDispatcher();

// Notification (Success, Warning, Error)
$setPersistantNotification = new ListenersSetPersistantNotification();
$dispatcher->addListener('notify', array($setPersistantNotification, 'setNotification'), 10);

// Redirect
$redirectUser = new ListenersRedirect();
$dispatcher->addListener('notifiy', array($redirectUser, 'redirectUser'), 0);
Raise and Dispatch Event

 $url = $baseUrl . 'account';
 $message = 'Your password was changed successfuly.';
 $event = new EventsRedirectableNotification($url, $message, 'success');
 $dispatcher->dispatch('notify', $event);
{



Forms
                                       "require": {
                                           "symfony/form": "dev-master"
                                       }
                                   }



A little fiddly to get running in a stand-alone mode
  READ: I didn’t have time to figure it out for this talk :-(
Supports:
  Creating forms programmatically
  Processing form submissions
  Uploading Files
  Validating submissions with the Validator
Creating a form: with Silex
$data = array();
$data['a_hidden_field'] = 'the value';
$form = $app['form.factory']->createBuilder('form', $data)
	 ->add('image', 'file')
	 ->add('name')
	 ->add('a_hidden_field', 'hidden')
	 ->getform();
return $app['twig']->render('form.twig', array('form' => $form->createView()));




            <form action="/" method="post" {{ form_enctype(form) }}>
                {{ form_widget(form) }}

                <input type="submit" name="submit" />
            </form>
Process form submission


    if(   'POST' == $request->getMethod()) {
    	 	    $form->bindRequest($request);
    	 	    if($form->isValid()) {
    	 	    	 $data = $form->getData();
    	 	    }
    	 }
File upload


    $uploadedFile = $form['image']->getData();
    	 	 	 	
    $path = $uploadedFile->getPath();
    $originalName = $uploadedFile->getOriginalName();
    $mimeType = $uploadedFile->getMimeType();
    	 	 	 	
    $uploadedFile->move( '/var/www/uploads/upload.png');
{



Validator
                                     "require": {
                                         "symfony/validator": "dev-master"
                                     }
                                 }




 Takes a series of constraints
 Checks an input against these constraints
 Returns a collection of violations
Validation Constraints
 Constraints define the rule that an input must satisfy
 Examples:
   Min/Max Length
   Email
   Regex
   Date
   Min / Max / Null / NotNull / Empty / Not Empty
Documentation Example
  <?php
  use SymfonyComponentValidatorValidation;
  use SymfonyComponentValidatorConstraints as Assert;

  $validator = Validation::createValidator();

  $constraint = new AssertCollection(array(
      'name' => new AssertCollection(array(
          'first_name' => new AssertMinLength(101),
          'last_name' => new AssertMinLength(1),
      )),
      'email'    => new AssertEmail(),
      'simple'   => new AssertMinLength(102),
      'gender'   => new AssertChoice(array(3, 4)),
      'file'     => new AssertFile(),
      'password' => new AssertMinLength(60),
  ));

  $violations = $validator->validateValue($input, $constraint);
{



Security
                                  "require": {
                                      "symfony/security": "dev-master"
                                  }
                              }




 Provides a framework for:
   Authentication
   Authorisation
     Firewall: who can access which areas e.g. “edit”
     Access Control: what data the user can
     manipulate e.g. edit home page
HTTP                   {
                           "require": {
                               "symfony/http-foundation": "dev-master"


Foundation
                           }
                       }




Abstracts core HTTP functions
  Request: Super Globals ($_POST, $_GET, etc)
  Response: Status Codes, Cache, Cookies, Sessions
HTTPFoundation: Request
Object-Oriented wrapper for SuperGloabls
          use SymfonyComponentHttpFoundationRequest;
          $request = Request::createFromGlobals();


                      Property          Purpose

                       request        store $_POST

                        query         store $_GET

                       cookies      store $_COOKIE

                      attributes   Application specific

                        files             $_FILE

                       server          $_SERVER

                      headers      subset of $_SERVER
ParameterBag
Request properties are all ParameterBag or sub-classes
Provides special methods to manage contents, including:
  all
  keys
  add
  get
  set
  has
  remove

 $value = $request->query->get(‘my_get_parameter’);
Response
use SymfonyComponentHttpFoundationResponse;

$response = new Response();
$response->setContent('Hello PHPNE');
$response->setStatusCode(200);
$response->headers->set('Content-Type', 'text/plain');

// alternatively...
$response = new Response('Hello PHPNE', 200, array('content-type', 'text/plain'));

$response->prepare();

// send the response to the user
$response->send();
Pimple
                    {
                        "require": {
                            "pimple/pimple": "dev-master"
                        }
                    }




   Dependency Injection Container
     Use it to store and pass objects, and other things
     your code depends on
   What is dependency injection?
                public function __construct()
                {
Not injected      $this->database = new mysqli();
                }

                public function __construct($database)
                {
    Injected      $this->database = $database;
                }
Pimple: Lazy Loading
        We can use anonymous functions to prevent
        (dependent) objects being instantiated until they are
        needed
$container['database'] = $container->share(function($container) {
    try {
         $db = new
         PDO("mysql:host={$container['database_host']};port={$container['database_port']};dbname={$container['d
         atabase_name']}", $container['database_user'], $container['database_pass'], array(PDO::ATTR_PERSISTENT
         => true, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'",PDO::MYSQL_ATTR_USE_BUFFERED_QUERY =>
         true));

          $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

          return $db;
      }
      catch (PDOException $e) {
          echo $e->getMessage();
          exit();
      }
});
Parameters


          $container['my_parameter'] = 'Some Value';




 Objects



$container['my_object'] = function($container){
	 //will return this each and every time $container['my_object'] is accessed
	 return new MyObject();
};
Sharing Objects
    $container['my_object'] = $container->share(function($container){
    	 // will return a new instance first time accessed
    	 // same object returned every other time
    	 return new MyObject();
    });



Protecting Parameters

$container['my_object'] = $container->protect(function($container){
	 // lets you return the result of an anonymous function as a parameter	
	 return some_function();
});




A warning: You can’t modify a parameter
Twig
                     {
                         "require": {
                             "twig/twig": "dev-master"
                         }
                     }




Lightweight template engine
Really easy to extend and use

    // create a twig filesystem loader so it can access templates
    $loader = new Twig_Loader_Filesystem('templates');
    // create a new twig environment and pass it the loader
    $twig = Twig_Environment($loader);
    // load the template
    $twig->loadTemplate('index.twig');
    // render it
    $twig->render(array('title' => 'variable'));
Twig Template Syntax

      {{ some_variable }}

      {# some comment #}

      {% set list_of_items = variable.getItems() %}

      {%   for item in list_of_items %}
      	    <li>{{loop.index}}: {{item.name}}</li>
      {%   else %}
      	    <li>Empty :-(</li>
      {%   endfor %}
Silex
                 {
                     "require": {
                         "silex/silex": "dev-master"
                     }
                 }




 A “micro-framework” based off some of these
 components and pimple
 Designed for single-page PHP apps
Silex: A note on closures

 Anonymous function: created without a name
 Can accept parameters
 Can use variables from compile time scope if defined


         $objectToInject = new stdClass();
         $test = function($parameter) use ($objectToInject){
         	 // here we can use $parameter and $objectToInject
         };
Setup

        require_once '../vendor/autoload.php';

        use SymfonyComponentHttpFoundationRequest;
        use SymfonyComponentHttpFoundationResponse;

        use SymfonyComponentProcessProcess;

        $app = new SilexApplication();
        // Enable debugging.
        $app['debug'] = true;
Silex: Before running

$app->before(function () use ($app)
{
    $app->register(new SilexProviderTranslationServiceProvider(), array(
        'locale_fallback' => 'en',
        ));
    $app->register(new SilexProviderFormServiceProvider());
    $app->register(new SilexProviderTwigServiceProvider(), array(
                 'twig.path' => __DIR__.'/views',
     ));
     $app['conn'] = new mysqli('localhost', 'root', '', 'app');
});
Silex: Routes
     $app->get('image.{format}', function( $format ) use ($app)
     {
         $form = $app['form.factory']->createBuilder('form', array())
                     ->add('image', 'file')
                     ->getform();
         return $app['twig']->render("upload.{$format}.twig",
     array('title' => 'Upload image', 'form' => $form->createView()));
     })->assert('format', 'json|html' );




$app->post('/image.{format}', function( $format, Request $request) use ($app)
{
    return $app['twig']->render("image.{$format}.twig", array));
})->assert( 'format', 'json|html');
Silex: Run



        $app->run();
Silex & Components

Silex has a number of “providers” which allow certain
components to be plugged in
Silex knows nothing about the component
The component knows nothing about Silex
The provider bridges the gap
Silex Providers:
 Doctrine: ORM
                     URL Generator
 Monolog: Sessions
                     Validator
 SwiftMailer
                     HTTP Cache
 Session
                     Form
 Twig
                     Any that you create
 Translation
Conclusion

Lots of components
Solve lots of problems
Easy to use
Why reinvent the wheel? Use a Symfony Component or
one of their friends
Cheers!

Thanks for listening!


mkpeacock@gmail.com
@michaelpeacock

More Related Content

What's hot

What happens in laravel 4 bootstraping
What happens in laravel 4 bootstrapingWhat happens in laravel 4 bootstraping
What happens in laravel 4 bootstrapingJace Ju
 
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017Ryan Weaver
 
Running a Scalable And Reliable Symfony2 Application in Cloud (Symfony Sweden...
Running a Scalable And Reliable Symfony2 Application in Cloud (Symfony Sweden...Running a Scalable And Reliable Symfony2 Application in Cloud (Symfony Sweden...
Running a Scalable And Reliable Symfony2 Application in Cloud (Symfony Sweden...Ville Mattila
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworksdiego_k
 
Inside Bokete: Web Application with Mojolicious and others
Inside Bokete:  Web Application with Mojolicious and othersInside Bokete:  Web Application with Mojolicious and others
Inside Bokete: Web Application with Mojolicious and othersYusuke Wada
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkJeremy Kendall
 
Introducing Assetic: Asset Management for PHP 5.3
Introducing Assetic: Asset Management for PHP 5.3Introducing Assetic: Asset Management for PHP 5.3
Introducing Assetic: Asset Management for PHP 5.3Kris Wallsmith
 
Redis for your boss 2.0
Redis for your boss 2.0Redis for your boss 2.0
Redis for your boss 2.0Elena Kolevska
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Elena Kolevska
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkJeremy Kendall
 
Codeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept ImplementationCodeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept ImplementationAbdul Malik Ikhsan
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh PollockExtending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh PollockCaldera Labs
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Ryan Weaver
 
Filling the flask
Filling the flaskFilling the flask
Filling the flaskJason Myers
 

What's hot (20)

What happens in laravel 4 bootstraping
What happens in laravel 4 bootstrapingWhat happens in laravel 4 bootstraping
What happens in laravel 4 bootstraping
 
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
The Coolest Symfony Components you’ve never heard of - DrupalCon 2017
 
Running a Scalable And Reliable Symfony2 Application in Cloud (Symfony Sweden...
Running a Scalable And Reliable Symfony2 Application in Cloud (Symfony Sweden...Running a Scalable And Reliable Symfony2 Application in Cloud (Symfony Sweden...
Running a Scalable And Reliable Symfony2 Application in Cloud (Symfony Sweden...
 
Perl web frameworks
Perl web frameworksPerl web frameworks
Perl web frameworks
 
Developing apps using Perl
Developing apps using PerlDeveloping apps using Perl
Developing apps using Perl
 
Inside Bokete: Web Application with Mojolicious and others
Inside Bokete:  Web Application with Mojolicious and othersInside Bokete:  Web Application with Mojolicious and others
Inside Bokete: Web Application with Mojolicious and others
 
Keeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro frameworkKeeping it small: Getting to know the Slim micro framework
Keeping it small: Getting to know the Slim micro framework
 
Introducing Assetic: Asset Management for PHP 5.3
Introducing Assetic: Asset Management for PHP 5.3Introducing Assetic: Asset Management for PHP 5.3
Introducing Assetic: Asset Management for PHP 5.3
 
Mojo as a_client
Mojo as a_clientMojo as a_client
Mojo as a_client
 
Redis for your boss 2.0
Redis for your boss 2.0Redis for your boss 2.0
Redis for your boss 2.0
 
Redis for your boss
Redis for your bossRedis for your boss
Redis for your boss
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
 
Codeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept ImplementationCodeigniter : Two Step View - Concept Implementation
Codeigniter : Two Step View - Concept Implementation
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
Extending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh PollockExtending the WordPress REST API - Josh Pollock
Extending the WordPress REST API - Josh Pollock
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)
 
Filling the flask
Filling the flaskFilling the flask
Filling the flask
 
RESTful web services
RESTful web servicesRESTful web services
RESTful web services
 
Symfony2 revealed
Symfony2 revealedSymfony2 revealed
Symfony2 revealed
 

Similar to Phpne august-2012-symfony-components-friends

Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Jakub Zalas
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207patter
 
Filesystem abstractions and msg queue sergeev - symfony camp 2018
Filesystem abstractions and msg queue   sergeev - symfony camp 2018Filesystem abstractions and msg queue   sergeev - symfony camp 2018
Filesystem abstractions and msg queue sergeev - symfony camp 2018Юлия Коваленко
 
Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]Raul Fraile
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Hugo Hamon
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteLeonardo Proietti
 
Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Fabien Potencier
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐいHisateru Tanaka
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowKacper Gunia
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenchesLukas Smith
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5Darren Craig
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Kacper Gunia
 
Api Design
Api DesignApi Design
Api Designsartak
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012D
 
Flask patterns
Flask patternsFlask patterns
Flask patternsit-people
 

Similar to Phpne august-2012-symfony-components-friends (20)

Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12Symfony components in the wild, PHPNW12
Symfony components in the wild, PHPNW12
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
 
Filesystem abstractions and msg queue sergeev - symfony camp 2018
Filesystem abstractions and msg queue   sergeev - symfony camp 2018Filesystem abstractions and msg queue   sergeev - symfony camp 2018
Filesystem abstractions and msg queue sergeev - symfony camp 2018
 
Symfony internals [english]
Symfony internals [english]Symfony internals [english]
Symfony internals [english]
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2Build powerfull and smart web applications with Symfony2
Build powerfull and smart web applications with Symfony2
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
Silex Cheat Sheet
Silex Cheat SheetSilex Cheat Sheet
Silex Cheat Sheet
 
Forget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers CracowForget about Index.php and build you applications around HTTP - PHPers Cracow
Forget about Index.php and build you applications around HTTP - PHPers Cracow
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
What's New In Laravel 5
What's New In Laravel 5What's New In Laravel 5
What's New In Laravel 5
 
Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!Forget about index.php and build you applications around HTTP!
Forget about index.php and build you applications around HTTP!
 
Api Design
Api DesignApi Design
Api Design
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012What mom never told you about bundle configurations - Symfony Live Paris 2012
What mom never told you about bundle configurations - Symfony Live Paris 2012
 
Flask patterns
Flask patternsFlask patterns
Flask patterns
 

More from Michael Peacock

Immutable Infrastructure with Packer Ansible and Terraform
Immutable Infrastructure with Packer Ansible and TerraformImmutable Infrastructure with Packer Ansible and Terraform
Immutable Infrastructure with Packer Ansible and TerraformMichael Peacock
 
Test driven APIs with Laravel
Test driven APIs with LaravelTest driven APIs with Laravel
Test driven APIs with LaravelMichael Peacock
 
Symfony Workflow Component - Introductory Lightning Talk
Symfony Workflow Component - Introductory Lightning TalkSymfony Workflow Component - Introductory Lightning Talk
Symfony Workflow Component - Introductory Lightning TalkMichael Peacock
 
Alexa, lets make a skill
Alexa, lets make a skillAlexa, lets make a skill
Alexa, lets make a skillMichael Peacock
 
API Development with Laravel
API Development with LaravelAPI Development with Laravel
API Development with LaravelMichael Peacock
 
Refactoring to symfony components
Refactoring to symfony componentsRefactoring to symfony components
Refactoring to symfony componentsMichael Peacock
 
Introduction to OOP with PHP
Introduction to OOP with PHPIntroduction to OOP with PHP
Introduction to OOP with PHPMichael Peacock
 
Evolution of a big data project
Evolution of a big data projectEvolution of a big data project
Evolution of a big data projectMichael Peacock
 
Real time voice call integration - Confoo 2012
Real time voice call integration - Confoo 2012Real time voice call integration - Confoo 2012
Real time voice call integration - Confoo 2012Michael Peacock
 
Data at Scale - Michael Peacock, Cloud Connect 2012
Data at Scale - Michael Peacock, Cloud Connect 2012Data at Scale - Michael Peacock, Cloud Connect 2012
Data at Scale - Michael Peacock, Cloud Connect 2012Michael Peacock
 
PHP Continuous Data Processing
PHP Continuous Data ProcessingPHP Continuous Data Processing
PHP Continuous Data ProcessingMichael Peacock
 
PHP North East Registry Pattern
PHP North East Registry PatternPHP North East Registry Pattern
PHP North East Registry PatternMichael Peacock
 
PHP North East - Registry Design Pattern
PHP North East - Registry Design PatternPHP North East - Registry Design Pattern
PHP North East - Registry Design PatternMichael Peacock
 
Supermondays: Jenkins CI lightning talk
Supermondays: Jenkins CI lightning talkSupermondays: Jenkins CI lightning talk
Supermondays: Jenkins CI lightning talkMichael Peacock
 
Corporate Structures - September 2010
Corporate Structures - September 2010Corporate Structures - September 2010
Corporate Structures - September 2010Michael Peacock
 
PHP North-East - Automated Deployment
PHP North-East - Automated DeploymentPHP North-East - Automated Deployment
PHP North-East - Automated DeploymentMichael Peacock
 
Abstracting functionality with centralised content
Abstracting functionality with centralised contentAbstracting functionality with centralised content
Abstracting functionality with centralised contentMichael Peacock
 

More from Michael Peacock (20)

Immutable Infrastructure with Packer Ansible and Terraform
Immutable Infrastructure with Packer Ansible and TerraformImmutable Infrastructure with Packer Ansible and Terraform
Immutable Infrastructure with Packer Ansible and Terraform
 
Test driven APIs with Laravel
Test driven APIs with LaravelTest driven APIs with Laravel
Test driven APIs with Laravel
 
Symfony Workflow Component - Introductory Lightning Talk
Symfony Workflow Component - Introductory Lightning TalkSymfony Workflow Component - Introductory Lightning Talk
Symfony Workflow Component - Introductory Lightning Talk
 
Alexa, lets make a skill
Alexa, lets make a skillAlexa, lets make a skill
Alexa, lets make a skill
 
API Development with Laravel
API Development with LaravelAPI Development with Laravel
API Development with Laravel
 
Refactoring to symfony components
Refactoring to symfony componentsRefactoring to symfony components
Refactoring to symfony components
 
Introduction to OOP with PHP
Introduction to OOP with PHPIntroduction to OOP with PHP
Introduction to OOP with PHP
 
Vagrant
VagrantVagrant
Vagrant
 
Evolution of a big data project
Evolution of a big data projectEvolution of a big data project
Evolution of a big data project
 
Real time voice call integration - Confoo 2012
Real time voice call integration - Confoo 2012Real time voice call integration - Confoo 2012
Real time voice call integration - Confoo 2012
 
Data at Scale - Michael Peacock, Cloud Connect 2012
Data at Scale - Michael Peacock, Cloud Connect 2012Data at Scale - Michael Peacock, Cloud Connect 2012
Data at Scale - Michael Peacock, Cloud Connect 2012
 
Supermondays twilio
Supermondays twilioSupermondays twilio
Supermondays twilio
 
PHP & Twilio
PHP & TwilioPHP & Twilio
PHP & Twilio
 
PHP Continuous Data Processing
PHP Continuous Data ProcessingPHP Continuous Data Processing
PHP Continuous Data Processing
 
PHP North East Registry Pattern
PHP North East Registry PatternPHP North East Registry Pattern
PHP North East Registry Pattern
 
PHP North East - Registry Design Pattern
PHP North East - Registry Design PatternPHP North East - Registry Design Pattern
PHP North East - Registry Design Pattern
 
Supermondays: Jenkins CI lightning talk
Supermondays: Jenkins CI lightning talkSupermondays: Jenkins CI lightning talk
Supermondays: Jenkins CI lightning talk
 
Corporate Structures - September 2010
Corporate Structures - September 2010Corporate Structures - September 2010
Corporate Structures - September 2010
 
PHP North-East - Automated Deployment
PHP North-East - Automated DeploymentPHP North-East - Automated Deployment
PHP North-East - Automated Deployment
 
Abstracting functionality with centralised content
Abstracting functionality with centralised contentAbstracting functionality with centralised content
Abstracting functionality with centralised content
 

Recently uploaded

Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESmohitsingh558521
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxBkGupta21
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteDianaGray10
 

Recently uploaded (20)

Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICESSALESFORCE EDUCATION CLOUD | FEXLE SERVICES
SALESFORCE EDUCATION CLOUD | FEXLE SERVICES
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
unit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptxunit 4 immunoblotting technique complete.pptx
unit 4 immunoblotting technique complete.pptx
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Take control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test SuiteTake control of your SAP testing with UiPath Test Suite
Take control of your SAP testing with UiPath Test Suite
 

Phpne august-2012-symfony-components-friends

  • 1. Symfony Components & Friends Michael Peacock, PHPNE August 2012
  • 2. About Me @michaelpeacock Head Developer @ Ground Six Leading the development team and managing the development process We are a tech investment company: you bring ideas, we partner and build the product Author Occasional Speaker
  • 3. Symfony Components Routing YAML Event dispatcher Finder Form Dependency Injection Process HttpFoundation Security HttpKernel Console Locale
  • 4. Friends Pimple: dependency injection container Twig: templating engine Silex
  • 5. Why? Solve common web application problems Incredibly well documented Standalone: use them how you want [Components] Ideal for: Refactoring
  • 6. Installing Create a composer.json file in the root of your project { "require": { "company/project": "version", } } Download Composer curl -s https://getcomposer.org/installer | php Run Composer php composer.phar install
  • 7. { Routing "require": { "symfony/routing": "dev-master" } } Looks at the users request and converts it into a Controller::method paid Request Context: POST|GET|PUT|DELETE Looks within a list of pre-defined routes Returns a class name and a method
  • 8. Defining Routes YAML PHP Code (A collection of Routes) Annotations
  • 9. comment_story_add: pattern: /news/{category}/{date}/{article} defaults: { class: 'CommentsController::addComment' } requirements: date: "[0-9]{2}-[0-9]{2}-[0-9]{4}" _method: POST
  • 10. // look in our routes folder $locator = new SymfonyComponentConfigFileLocator(array(__DIR__ . '/../../')); $loader = new SymfonyComponentRoutingLoaderYamlFileLoader($locator); // the URL the user requested / is visiting $request = (isset($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : ''; // combine it with the request method to create a request context $requestContext = new SymfonyComponentRoutingRequestContext($request, $_SERVER['REQUEST_METHOD']); // Create a router $router = new SymfonyComponentRoutingRouter($locator, 'routes.yml', array('cache_dir' => null), $requestContext); try { $requestURL = (isset($_SERVER['REQUEST_URI'])) ? $_SERVER['REQUEST_URI'] : ''; $requestURL = (strlen($requestURL) > 1) ? rtrim($requestURL, '/') : $requestURL; $route = $this->router->match($requestURL); // explode the resulting route $usersRoute = explode('::', $route['class']); $controller = new $usersRoute[0](); $variables = $route; unset($variables['name']); unset($variables['class']); $action = $controller->$usersRoute[1]($container, $variables); } catch (SymfonyComponentRoutingExceptionResourceNotFoundException $e) { header('HTTP/1.0 404 Not Found'); die('Page not found.'); }
  • 11. Event { "require": { "symfony/event-dispatcher": "dev-master" Dispatcher } } At key points in your application you create an event Pass this event to the dispatcher Observers listen for specific events Observers can be ordered - some events are observed by multiple observers Example: Displaying a “flash notification” Set some sessions containing the notification Redirect the user
  • 12. Event: Notify <?php namespace ProjectFrameworkEvents; class Notify extends RequestRedirection implements NotifiableMessageInterface { protected $notification; protected $class = 'notice'; public function __construct($url = null, $notification = null, $class = 'notice') { parent::__construct($url); $this->class = $class; $this->notification = $notification; } public function getNotification() { return $this->notification; } public function getClass() { return $this->class; } }
  • 13. <?php namespace ProjectFrameworkEvents; use SymfonyComponentEventDispatcherEvent; class RequestRedirection extends Event { protected $url; public function __construct($url = null) { $this->url = $url; } public function getURL() { return $this->url; } } <?php namespace ProjectFrameworkEvents; interface NotifiableMessageInterface { public function getNotification(); public function getClass(); }
  • 14. Listener: Set Notification Session <?php namespace ProjectFrameworkListeners; use ProjectFrameworkEvents; use SymfonyComponentEventDispatcherEvent; class SetPersistantNotification { public function setNotification( EventsNotifiableMessageInterface $event ) { $_SESSION['system_notification'] = $event->getNotification(); $_SESSION['system_notification_class'] = $event->getClass(); } }
  • 15. Listener: Redirect <?php namespace ProjectFrameworkListeners; use ProjectFrameworkEvents; use SymfonyComponentEventDispatcherEvent; class Redirect { public function redirectUser( EventsRequestRedirection $event ) { header("Location: " . $event->getURL() ); exit(); } }
  • 16. Dispatcher Create an event dispatcher Create instance of listener Add the listener Event name Callable: e.g. Object > Method array combo, Closure (event is passed) Priority: for multiple listeners listening for the same event $dispatcher = new EventDispatcher(); // Notification (Success, Warning, Error) $setPersistantNotification = new ListenersSetPersistantNotification(); $dispatcher->addListener('notify', array($setPersistantNotification, 'setNotification'), 10); // Redirect $redirectUser = new ListenersRedirect(); $dispatcher->addListener('notifiy', array($redirectUser, 'redirectUser'), 0);
  • 17. Raise and Dispatch Event $url = $baseUrl . 'account'; $message = 'Your password was changed successfuly.'; $event = new EventsRedirectableNotification($url, $message, 'success'); $dispatcher->dispatch('notify', $event);
  • 18. { Forms "require": { "symfony/form": "dev-master" } } A little fiddly to get running in a stand-alone mode READ: I didn’t have time to figure it out for this talk :-( Supports: Creating forms programmatically Processing form submissions Uploading Files Validating submissions with the Validator
  • 19. Creating a form: with Silex $data = array(); $data['a_hidden_field'] = 'the value'; $form = $app['form.factory']->createBuilder('form', $data) ->add('image', 'file') ->add('name') ->add('a_hidden_field', 'hidden') ->getform(); return $app['twig']->render('form.twig', array('form' => $form->createView())); <form action="/" method="post" {{ form_enctype(form) }}> {{ form_widget(form) }} <input type="submit" name="submit" /> </form>
  • 20. Process form submission if( 'POST' == $request->getMethod()) { $form->bindRequest($request); if($form->isValid()) { $data = $form->getData(); } }
  • 21. File upload $uploadedFile = $form['image']->getData(); $path = $uploadedFile->getPath(); $originalName = $uploadedFile->getOriginalName(); $mimeType = $uploadedFile->getMimeType(); $uploadedFile->move( '/var/www/uploads/upload.png');
  • 22. { Validator "require": { "symfony/validator": "dev-master" } } Takes a series of constraints Checks an input against these constraints Returns a collection of violations
  • 23. Validation Constraints Constraints define the rule that an input must satisfy Examples: Min/Max Length Email Regex Date Min / Max / Null / NotNull / Empty / Not Empty
  • 24. Documentation Example <?php use SymfonyComponentValidatorValidation; use SymfonyComponentValidatorConstraints as Assert; $validator = Validation::createValidator(); $constraint = new AssertCollection(array( 'name' => new AssertCollection(array( 'first_name' => new AssertMinLength(101), 'last_name' => new AssertMinLength(1), )), 'email' => new AssertEmail(), 'simple' => new AssertMinLength(102), 'gender' => new AssertChoice(array(3, 4)), 'file' => new AssertFile(), 'password' => new AssertMinLength(60), )); $violations = $validator->validateValue($input, $constraint);
  • 25. { Security "require": { "symfony/security": "dev-master" } } Provides a framework for: Authentication Authorisation Firewall: who can access which areas e.g. “edit” Access Control: what data the user can manipulate e.g. edit home page
  • 26. HTTP { "require": { "symfony/http-foundation": "dev-master" Foundation } } Abstracts core HTTP functions Request: Super Globals ($_POST, $_GET, etc) Response: Status Codes, Cache, Cookies, Sessions
  • 27. HTTPFoundation: Request Object-Oriented wrapper for SuperGloabls use SymfonyComponentHttpFoundationRequest; $request = Request::createFromGlobals(); Property Purpose request store $_POST query store $_GET cookies store $_COOKIE attributes Application specific files $_FILE server $_SERVER headers subset of $_SERVER
  • 28. ParameterBag Request properties are all ParameterBag or sub-classes Provides special methods to manage contents, including: all keys add get set has remove $value = $request->query->get(‘my_get_parameter’);
  • 29. Response use SymfonyComponentHttpFoundationResponse; $response = new Response(); $response->setContent('Hello PHPNE'); $response->setStatusCode(200); $response->headers->set('Content-Type', 'text/plain'); // alternatively... $response = new Response('Hello PHPNE', 200, array('content-type', 'text/plain')); $response->prepare(); // send the response to the user $response->send();
  • 30. Pimple { "require": { "pimple/pimple": "dev-master" } } Dependency Injection Container Use it to store and pass objects, and other things your code depends on What is dependency injection? public function __construct() { Not injected $this->database = new mysqli(); } public function __construct($database) { Injected $this->database = $database; }
  • 31. Pimple: Lazy Loading We can use anonymous functions to prevent (dependent) objects being instantiated until they are needed $container['database'] = $container->share(function($container) { try { $db = new PDO("mysql:host={$container['database_host']};port={$container['database_port']};dbname={$container['d atabase_name']}", $container['database_user'], $container['database_pass'], array(PDO::ATTR_PERSISTENT => true, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'",PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true)); $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); return $db; } catch (PDOException $e) { echo $e->getMessage(); exit(); } });
  • 32. Parameters $container['my_parameter'] = 'Some Value'; Objects $container['my_object'] = function($container){ //will return this each and every time $container['my_object'] is accessed return new MyObject(); };
  • 33. Sharing Objects $container['my_object'] = $container->share(function($container){ // will return a new instance first time accessed // same object returned every other time return new MyObject(); }); Protecting Parameters $container['my_object'] = $container->protect(function($container){ // lets you return the result of an anonymous function as a parameter return some_function(); }); A warning: You can’t modify a parameter
  • 34. Twig { "require": { "twig/twig": "dev-master" } } Lightweight template engine Really easy to extend and use // create a twig filesystem loader so it can access templates $loader = new Twig_Loader_Filesystem('templates'); // create a new twig environment and pass it the loader $twig = Twig_Environment($loader); // load the template $twig->loadTemplate('index.twig'); // render it $twig->render(array('title' => 'variable'));
  • 35. Twig Template Syntax {{ some_variable }} {# some comment #} {% set list_of_items = variable.getItems() %} {% for item in list_of_items %} <li>{{loop.index}}: {{item.name}}</li> {% else %} <li>Empty :-(</li> {% endfor %}
  • 36. Silex { "require": { "silex/silex": "dev-master" } } A “micro-framework” based off some of these components and pimple Designed for single-page PHP apps
  • 37. Silex: A note on closures Anonymous function: created without a name Can accept parameters Can use variables from compile time scope if defined $objectToInject = new stdClass(); $test = function($parameter) use ($objectToInject){ // here we can use $parameter and $objectToInject };
  • 38. Setup require_once '../vendor/autoload.php'; use SymfonyComponentHttpFoundationRequest; use SymfonyComponentHttpFoundationResponse; use SymfonyComponentProcessProcess; $app = new SilexApplication(); // Enable debugging. $app['debug'] = true;
  • 39. Silex: Before running $app->before(function () use ($app) { $app->register(new SilexProviderTranslationServiceProvider(), array( 'locale_fallback' => 'en', )); $app->register(new SilexProviderFormServiceProvider()); $app->register(new SilexProviderTwigServiceProvider(), array( 'twig.path' => __DIR__.'/views', )); $app['conn'] = new mysqli('localhost', 'root', '', 'app'); });
  • 40. Silex: Routes $app->get('image.{format}', function( $format ) use ($app) { $form = $app['form.factory']->createBuilder('form', array()) ->add('image', 'file') ->getform(); return $app['twig']->render("upload.{$format}.twig", array('title' => 'Upload image', 'form' => $form->createView())); })->assert('format', 'json|html' ); $app->post('/image.{format}', function( $format, Request $request) use ($app) { return $app['twig']->render("image.{$format}.twig", array)); })->assert( 'format', 'json|html');
  • 41. Silex: Run $app->run();
  • 42. Silex & Components Silex has a number of “providers” which allow certain components to be plugged in Silex knows nothing about the component The component knows nothing about Silex The provider bridges the gap
  • 43. Silex Providers: Doctrine: ORM URL Generator Monolog: Sessions Validator SwiftMailer HTTP Cache Session Form Twig Any that you create Translation
  • 44. Conclusion Lots of components Solve lots of problems Easy to use Why reinvent the wheel? Use a Symfony Component or one of their friends

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. Problem with not using an event for this is that code is littered with SESSION setting and Header Redirects. What if we change how this needs to work? Lots of find and replaces\n
  12. \n
  13. \n
  14. \n
  15. \n
  16. \n
  17. \n
  18. \n
  19. \n
  20. \n
  21. \n
  22. \n
  23. \n
  24. \n
  25. \n
  26. \n
  27. \n
  28. \n
  29. \n
  30. \n
  31. \n
  32. \n
  33. \n
  34. \n
  35. Dot syntax is very special. It can be used to access object properties, object methods, array elements, and even object getter methods. Templates can also be extended to chain multiple templates together.\n
  36. \n
  37. \n
  38. \n
  39. \n
  40. Request parameter is optional, the Type Hint is used to work out if its used or not\n
  41. \n
  42. \n
  43. \n
  44. \n
  45. \n