SlideShare a Scribd company logo
1 of 40
Download to read offline
Symfony2 - From the Trenches




                    by Lukas Kahwe Smith,
                            Kris Wallsmith,
                        Thibault Duplessis,
                            Jeremy Mikola,
                           Jordi Boggiano,
                        Jonathan H. Wage,
                        Bulat Shakirzyanov
Agenda


Getting Setup               Caching
Code Flow                   Performance Tips
Dependency Injection        Asset Management
Configuration Choices       Testing
Controller Choices          Deployment
Application Choices         Third Party Bundles
Doctrine                    Resources
Getting the works)
PHP 5.3+ with ext/intl (compat lib is in
                                         setup
    Read check.php for details (dev/prod php.ini's from Liip)
    Using OSX?
         php53-intl from liangzhenjing or build-entropy-php from chregu
         Blog post on installing PHP 5.3 with intl from Justin Hileman
Initial setup
    symfony-sandbox
    symfony-bootstrap
    Symfony2Project

Read the Coding Style Guide (Code Sniffer Rules)


Managing external dependencies

    Submodule: not everything is in git (svn, mercurial, etc.)
    Vendor install/update scripts: risk of getting out of sync
    MR (not cross platform)
Code Flow
1. Frontend Controller (web/app[_dev].php)
      Loads autoloader
      Creates/boots kernel
      Creates request (from globals) and passes to kernel
2. Kernel
      Loads app config (app/config/config_[prod|dev|test])
      Resolves URL path to a controller (go to 3.)
      Outputs response returned by the controller
3. Controller
      Loads model and view
      Potentially creates a sub-request (go to 2.)
      Creates response and returns it
Execution Flow
Dependency Injection

All objects are instantiated in one of two ways:
    Using the "new" operator
    Using an object factory
All objects get collaborators in one of two ways
    Passed to object constructor
    Set using a setter
Application Using Dependency Injection
<?xml version="1.0" encoding="utf-8" ?>
<container xmlns="http://www.symfony-project.org/schema/dic/services"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <parameters>
    <parameter key="sitemap.class">BundleAvalancheSitemapBundleSitemap</parameter>
  </parameters>

  <services>
    <service id="sitemap" class="%sitemap.class%" />
  </services>

</container>




                             Describe Your Services
<?php
class cachedDevDebugProjectContainer extends Container
{
   /**
    * Gets the 'sitemap' service.
    *
    * @return BundleAvalancheSitemapBundleSitemap
    */
   protected function getSitemapService()
   {
      return $this->services['sitemap'] = new BundleAvalancheSitemapBundleSitemap();
   }

    /**
     * Gets the default parameters.
     *
     * @return array An array of the default parameters
     */
    protected function getDefaultParameters()
    {
       return array(
          'sitemap.class' => 'BundleAvalancheSitemapBundleSitemap'
       );
    }
}




          Service Definitions Are Dumped to Raw PHP
Dependency Injection Container

Benefits:
   No performance loss
   Lazy instantiation
   Readable service configurations

Gotchas:
   Can become hard to work with if the DI extension tries to do
   too much
   Be aware of circular dependencies
   Might lead to code that cannot be used outside of DIC
Circular Dependency Example
<?php
class SomeClass
{
  private $container;

    public function __construct(ContainerInterface $container)    <service id="some_service" class="SomeClass">
    {                                                              <argument type="service" id="service_container" />
      $this->container = $container;                              </service>
    }                                                             <!-- or -->
     // or                                                        <service id="some_service" class="SomeClass">
    public function setContainer(ContainerInterface $container)    <call method="setContainer">
    {                                                               <argument type="service" id="service_container" />
      $this->container = $container;                               </call>
    }                                                             </service>

    public function getDocumentManager()
    {
      return $this->container->get('document_manager');
    }
}




                                           Container Injection
<?php
class SomeClass
{
  private $documentManager;

    public function __construct(DocumentManager $documentManager)
    {
      $this->documentManager = $documentManager;
    }

    public function getDocumentManager()
    {
      return $this->documentManager;
    }
}




<service id="some_service" class="SomeClass">
 <argument type="service" id="document_manager" />
</service>




                 Constructor Injection
<?php
class SomeClass
{
   private $documentManager;

    public function setDocumentManager(DocumentManager $documentManager)
    {
      $this->documentManager = $documentManager;
    }

    public function getDocumentManager()
    {
      return $this->documentManager;
    }
}




<service id="some_service" class="SomeClass">
  <call method="setDocumentManager">
     <argument type="service" id="document_manager" />
  </call>
</service>




                      Setter Injection
<?php
interface SomeInterface
{
   function setDocumentManager(DocumentManager $documentManager);
}

class SomeClass implements SomeInterface
{
   private $documentManager;

    public function setDocumentManager(DocumentManager $documentManager)
    {
      $this->documentManager = $documentManager;
    }

    public function getDocumentManager()
    {
      return $this->documentManager;
    }
}




<interface id="some_service" class="SomeInterface">
  <call method="setDocumentManager">
     <argument type="service" id="document_manager" />
  </call>
</interface>

<service id="some_service" class="SomeClass" />




                      Interface Injection
Configuration Choices

Symfony supports XML, YAML and PHP for configuration
YAML and PHP uses underscore to separate words
XML uses dashes to separate words
XML attributes usually map to array values for YAML/PHP
YAML merge key syntax to reuse pieces within a file
XSD-aware editors provide auto-completion and validation
XML is recommended for Bundle/DI configuration
YAML is recommended for application configuration
Doctrine does not like it when you mix formats!
Controller Choices

Defining Controllers as services is optional
     Non-service controllers must use container injection
     Create a Bundle Extension to load Bundle services
It's recommended to not extend from the base Controller
     The base controller is mainly a tool for beginners
     It provides convenience methods that invoke services
      generateUrl(), redirect(), render()
Application Choices

Security system makes it possible to have just one
application for both frontend and admin backend
Location of application is totally flexible, just update the
frontend controllers accordingly
Large projects should use multiple applications
    Better separation when multiple teams work
    Facilitate step-by-step updating and refactoring
    For example: main, mobile, API, admin
Doctrine Examples

Retrieve references to entity/document without DB queries
Using raw SQL queries with Doctrine2 ORM
Simple search engine with Doctrine MongoDB ODM
Retrieving References w/o DB Queries


$tags = array('baseball', 'basketball');
foreach ($tags as $tag) {
  $product->addTag($em->getReference('Tag', $tag));
}
Raw SQL Queries

$rsm = new ResultSetMapping;
$rsm->addEntityResult('User', 'u');
$rsm->addFieldResult('u', 'id', 'id');
$rsm->addFieldResult('u', 'name', 'name');

$query = $this->_em->createNativeQuery('SELECT id, name
FROM users WHERE name = ?', $rsm);
$query->setParameter(1, 'romanb');

$users = $query->getResult();
http://www.doctrine-project.org/docs/orm/2.0/en/reference/native-sql.html
Simple Search Engine

interface HasKeywords
{
   function setKeywords();
   function getKeywords();
}
Simple Search Engine
/** @mongodb:EmbeddedDocument */
class Keyword
{
   // ...

    /** @mongodb:String @mongodb:Index */
    private $keyword;

    /** @mongodb:Integer */
    private $score;

    // ...
}
Simple Search Engine
/** @mongodb:Document */
class Product implements HasKeywords
{
   /** @mongodb:Id */
   private $id;

    /** @mongodb:String */
    private $title;

    /** @mongodb:EmbedMany(targetDocument="Keyword") */
    private $keywords = array();

    // ...
}
Simple Search Engine
class KeywordListener
{
  public function preUpdate(PreUpdateEventArgs $eventArgs)
  {
    $entity = $eventArgs->getEntity();
    if ($entity instanceof HasKeywords) {
        $entity->setKeywords($this->buildKeywords($entity));
    }
  }

    private function buildKeywords(HasKeywords $entity)
    {
      $keywords = array();
      // build keywords from title, description, etc.
      return $keywords;
    }
}
Simple Search Engine

// find products by keyword
$products = $dm->createQueryBuilder()
    ->field('keywords.keyword')->all($keywords)
    ->getQuery()
    ->execute();
Different Content Areas of a Page
Caching with Edge Side Includes

Symfony2 provides support for Edge Side Includes (ESI)
   Proxy assembles page from snippets of HTML
   Snippets can have different cache rules
   Develop without ESI, test with Symfony2 internal ESI
   proxy, deploy using ultra fast Varnish Proxy
Break up page into different controller actions based on
cache invalidation rules
   Do not worry about overhead from multiple render calls
   Never mix content that has different cache timeouts
 Varnish Reverse Proxy
   Super fast, PHP cannot touch the performance
   Cache full pages for anonymous users
   Not just for HTML, also useful for JSON/XML API
Page Rendered Behind a Reverse Proxy
Performance Tips

Dump routes to apache rewrite rules
Cache warming
Do not add optional services to controllers
Do minimal work in the controller, let templates pull
additional data as needed
Use a bytecode cache with MapFileClassLoader
Asset Management

Go see Kris's talk later today!
Testing
Symfony2 rocks for unit and functional testing because
   Dependency Injection
   No base classes, no static dependencies, no ActiveRecord
   Client fakes "real" requests for functional testing
Functional Testing
   Pros: Tests configuration, Tests API not implementation
Unit Testing
   Pros: Pinpoints issues, Very directed Testing
Recommendation:
   Functional testing is recommended for controller actions
       Symfony2 provides WebTestCase and BrowserKit
   Unit testing for complex algorithms, third party API's too hard
   to mock
Use LiipFunctionalTesting to load fixtures, validate HTML5
Deployment

Debian style aka Liip Debian Packager
  Write a manifest in YAML
  Build Debian packages with MAKE
  Install with apt-get install
  Server specific settings are asked during install, change
  later with dpkg-reconfigure
  Maintain a global overview of all application
  dependencies in case of (security) updates
Third Party Bundles

           @weaverryan
           Ryan Weaver


Here's a new year's resolution: to *always*
work on an existing Symfony2 bundle and
never recreate my own. #focus #teamwork

27 Dec   http://twitter.com/weaverryan/status/19565706752299009
Third Party Bundles
Many vendors have already published bundles:

   FriendsOfSymfony (http://github.com/friendsofsymfony)
       UserBundle (forked from knplabs' DoctrineUserBundle)
       FacebookBundle (forked from kriswallsmith)
   Liip (http://github.com/liip)
       FunctionalTestBundle
       MultiplexBundle
       ViewBundle
   Sonata (http://github.com/sonata-project)
       BaseApplicationBundle

Additionally, a few sites currently index community bundles:

   http://symfony2bundles.org/
   http://symfohub.com/
Third Party Bundles

Bundles should follow the best practices
No version-tagging or official package manager (yet)
Use bundles by adding git submodules to your project
Maintain your own fork and "own" what you use
Not all bundles are equally maintained
   Symfony2 API changes => broken bundles
   If you track fabpot/symfony, learn to migrate bundles
Avoid rewriting a bundle's services/parameters directly
   The bundle's DI extension should allow for such
   configuration; if not, submit a pull request
   If absolutely necessary, a CompilerPass is cleaner
Contributing to Third Party Bundles

  Similar to Symfony2's own patch guidlines
  Fork and add remote repository
  Merge regularly to keep up-to-date
     Avoid committing directly to your master
     Merges from upstream should be fast-forwards
  Once upstream changes are stable, bump your
  project's submodule pointer
Contributing to Third Party Bundles

 Create branches for patches and new features
    Can't wait to use this in your project? Temporarily
    change your project submodule to point to your
    branch until your pull request is accepted.
 Help ensure that your pull request merges cleanly
    Create feature branch based on upstream's master
    Rebase on upstream's master when finished
Contributing to Third Party Bundles

 Was your pull request accepted? Congratulations!
 Don't merge your feature branch into master!
    Doing so would cause your master to divert
 Merge upstream's master into your master
 Delete your feature branch
 Update your project's submodule to point to master
Resources

If you want to jump in and contribute:
http://docs.symfony-reloaded.org/master/contributing/community/other.
html
If you are still fuzzy on Dependency Injection:
http://fabien.potencier.org/article/11/what-is-dependency-injection
If you keep up with Fabien's Symfony2 repository:
http://docs.symfony-reloaded.org/master/

More Related Content

What's hot

Node.js in action
Node.js in actionNode.js in action
Node.js in actionSimon Su
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkG Woo
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)Night Sailer
 
Java Development with MongoDB
Java Development with MongoDBJava Development with MongoDB
Java Development with MongoDBScott Hernandez
 
MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know Norberto Leite
 
Java Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDBJava Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDBMongoDB
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Fabien Potencier
 
MongoDB: Easy Java Persistence with Morphia
MongoDB: Easy Java Persistence with MorphiaMongoDB: Easy Java Persistence with Morphia
MongoDB: Easy Java Persistence with MorphiaScott Hernandez
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency InjectionRifat Nabi
 
Dependency Injection in Laravel
Dependency Injection in LaravelDependency Injection in Laravel
Dependency Injection in LaravelHAO-WEN ZHANG
 
Testing Web Applications with GEB
Testing Web Applications with GEBTesting Web Applications with GEB
Testing Web Applications with GEBHoward Lewis Ship
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleHugo Hamon
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
Simplifying Persistence for Java and MongoDB with Morphia
Simplifying Persistence for Java and MongoDB with MorphiaSimplifying Persistence for Java and MongoDB with Morphia
Simplifying Persistence for Java and MongoDB with MorphiaMongoDB
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
Drupal Field API. Practical usage
Drupal Field API. Practical usageDrupal Field API. Practical usage
Drupal Field API. Practical usagePavel Makhrinsky
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 

What's hot (20)

Node.js in action
Node.js in actionNode.js in action
Node.js in action
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
 
From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)From mysql to MongoDB(MongoDB2011北京交流会)
From mysql to MongoDB(MongoDB2011北京交流会)
 
Java Development with MongoDB
Java Development with MongoDBJava Development with MongoDB
Java Development with MongoDB
 
MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know
 
Java Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDBJava Persistence Frameworks for MongoDB
Java Persistence Frameworks for MongoDB
 
Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3Dependency Injection with PHP and PHP 5.3
Dependency Injection with PHP and PHP 5.3
 
MongoDB: Easy Java Persistence with Morphia
MongoDB: Easy Java Persistence with MorphiaMongoDB: Easy Java Persistence with Morphia
MongoDB: Easy Java Persistence with Morphia
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Dependency Injection in Laravel
Dependency Injection in LaravelDependency Injection in Laravel
Dependency Injection in Laravel
 
Testing Web Applications with GEB
Testing Web Applications with GEBTesting Web Applications with GEB
Testing Web Applications with GEB
 
Design Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et PimpleDesign Patterns avec PHP 5.3, Symfony et Pimple
Design Patterns avec PHP 5.3, Symfony et Pimple
 
J query1
J query1J query1
J query1
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
jQuery secrets
jQuery secretsjQuery secrets
jQuery secrets
 
J query
J queryJ query
J query
 
Simplifying Persistence for Java and MongoDB with Morphia
Simplifying Persistence for Java and MongoDB with MorphiaSimplifying Persistence for Java and MongoDB with Morphia
Simplifying Persistence for Java and MongoDB with Morphia
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Drupal Field API. Practical usage
Drupal Field API. Practical usageDrupal Field API. Practical usage
Drupal Field API. Practical usage
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 

Viewers also liked

Symfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friendSymfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friendKirill Chebunin
 
Lets play with Symfony2
Lets play with Symfony2Lets play with Symfony2
Lets play with Symfony2Noel GUILBERT
 
Dependency Injection Smells
Dependency Injection SmellsDependency Injection Smells
Dependency Injection SmellsMatthias Noback
 
Dependency injection with Symfony 2
Dependency injection with Symfony 2Dependency injection with Symfony 2
Dependency injection with Symfony 2cammanderson
 
In The Future We All Use Symfony2
In The Future We All Use Symfony2In The Future We All Use Symfony2
In The Future We All Use Symfony2Brent Shaffer
 
The use of Symfony2 @ Overblog
The use of Symfony2 @ OverblogThe use of Symfony2 @ Overblog
The use of Symfony2 @ OverblogXavier Hausherr
 
Symfony2 Introduction Presentation
Symfony2 Introduction PresentationSymfony2 Introduction Presentation
Symfony2 Introduction PresentationNerd Tzanetopoulos
 
Presentation du framework symfony
Presentation du framework symfonyPresentation du framework symfony
Presentation du framework symfonyJeremy Gachet
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Fabien Potencier
 
Symfony 2 : chapitre 3 - Les modèles en Doctrine 2
Symfony 2 : chapitre 3 - Les modèles en Doctrine 2Symfony 2 : chapitre 3 - Les modèles en Doctrine 2
Symfony 2 : chapitre 3 - Les modèles en Doctrine 2Abdelkader Rhouati
 
Symfony 2 : chapitre 4 - Les services et les formulaires
Symfony 2 : chapitre 4 - Les services et les formulairesSymfony 2 : chapitre 4 - Les services et les formulaires
Symfony 2 : chapitre 4 - Les services et les formulairesAbdelkader Rhouati
 
Symfony 2 : chapitre 1 - Présentation Générale
Symfony 2 : chapitre 1 - Présentation GénéraleSymfony 2 : chapitre 1 - Présentation Générale
Symfony 2 : chapitre 1 - Présentation GénéraleAbdelkader Rhouati
 

Viewers also liked (12)

Symfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friendSymfony2 Service Container: Inject me, my friend
Symfony2 Service Container: Inject me, my friend
 
Lets play with Symfony2
Lets play with Symfony2Lets play with Symfony2
Lets play with Symfony2
 
Dependency Injection Smells
Dependency Injection SmellsDependency Injection Smells
Dependency Injection Smells
 
Dependency injection with Symfony 2
Dependency injection with Symfony 2Dependency injection with Symfony 2
Dependency injection with Symfony 2
 
In The Future We All Use Symfony2
In The Future We All Use Symfony2In The Future We All Use Symfony2
In The Future We All Use Symfony2
 
The use of Symfony2 @ Overblog
The use of Symfony2 @ OverblogThe use of Symfony2 @ Overblog
The use of Symfony2 @ Overblog
 
Symfony2 Introduction Presentation
Symfony2 Introduction PresentationSymfony2 Introduction Presentation
Symfony2 Introduction Presentation
 
Presentation du framework symfony
Presentation du framework symfonyPresentation du framework symfony
Presentation du framework symfony
 
Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4Dependency injection in PHP 5.3/5.4
Dependency injection in PHP 5.3/5.4
 
Symfony 2 : chapitre 3 - Les modèles en Doctrine 2
Symfony 2 : chapitre 3 - Les modèles en Doctrine 2Symfony 2 : chapitre 3 - Les modèles en Doctrine 2
Symfony 2 : chapitre 3 - Les modèles en Doctrine 2
 
Symfony 2 : chapitre 4 - Les services et les formulaires
Symfony 2 : chapitre 4 - Les services et les formulairesSymfony 2 : chapitre 4 - Les services et les formulaires
Symfony 2 : chapitre 4 - Les services et les formulaires
 
Symfony 2 : chapitre 1 - Présentation Générale
Symfony 2 : chapitre 1 - Présentation GénéraleSymfony 2 : chapitre 1 - Présentation Générale
Symfony 2 : chapitre 1 - Présentation Générale
 

Similar to Symfony2 from the Trenches

Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenchesLukas Smith
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf Conference
 
ZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperGary Hockin
 
Zend Framework 2 - Basic Components
Zend Framework 2  - Basic ComponentsZend Framework 2  - Basic Components
Zend Framework 2 - Basic ComponentsMateusz Tymek
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsMichael Peacock
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8Alexei Gorobets
 
Web internship Yii Framework
Web internship  Yii FrameworkWeb internship  Yii Framework
Web internship Yii FrameworkNoveo
 
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
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS ArchitectureEyal Vardi
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS InternalEyal Vardi
 
From framework coupled code to #microservices through #DDD /by @codelytv
From framework coupled code to #microservices through #DDD /by @codelytvFrom framework coupled code to #microservices through #DDD /by @codelytv
From framework coupled code to #microservices through #DDD /by @codelytvCodelyTV
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016Kacper Gunia
 
CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)brian d foy
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJSWei Ru
 
Introduction to Polymer and Firebase - Simon Gauvin
Introduction to Polymer and Firebase - Simon GauvinIntroduction to Polymer and Firebase - Simon Gauvin
Introduction to Polymer and Firebase - Simon GauvinSimon Gauvin
 

Similar to Symfony2 from the Trenches (20)

Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
 
ZF2 for the ZF1 Developer
ZF2 for the ZF1 DeveloperZF2 for the ZF1 Developer
ZF2 for the ZF1 Developer
 
Zend Framework 2 - Basic Components
Zend Framework 2  - Basic ComponentsZend Framework 2  - Basic Components
Zend Framework 2 - Basic Components
 
Yii Introduction
Yii IntroductionYii Introduction
Yii Introduction
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Basics of AngularJS
Basics of AngularJSBasics of AngularJS
Basics of AngularJS
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friends
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
 
Web internship Yii Framework
Web internship  Yii FrameworkWeb internship  Yii Framework
Web internship Yii Framework
 
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
 
Introduction to angular js
Introduction to angular jsIntroduction to angular js
Introduction to angular js
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS Internal
 
From framework coupled code to #microservices through #DDD /by @codelytv
From framework coupled code to #microservices through #DDD /by @codelytvFrom framework coupled code to #microservices through #DDD /by @codelytv
From framework coupled code to #microservices through #DDD /by @codelytv
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016
 
CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJS
 
Introduction to Polymer and Firebase - Simon Gauvin
Introduction to Polymer and Firebase - Simon GauvinIntroduction to Polymer and Firebase - Simon Gauvin
Introduction to Polymer and Firebase - Simon Gauvin
 

More from Jonathan Wage

Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
OpenSky Infrastructure
OpenSky InfrastructureOpenSky Infrastructure
OpenSky InfrastructureJonathan Wage
 
Doctrine In The Real World sflive2011 Paris
Doctrine In The Real World sflive2011 ParisDoctrine In The Real World sflive2011 Paris
Doctrine In The Real World sflive2011 ParisJonathan Wage
 
Doctrine in the Real World
Doctrine in the Real WorldDoctrine in the Real World
Doctrine in the Real WorldJonathan Wage
 
ZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine ProjectZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine ProjectJonathan Wage
 
Symfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 IntegrationSymfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 IntegrationJonathan Wage
 
Doctrine 2 - Enterprise Persistence Layer For PHP
Doctrine 2 - Enterprise Persistence Layer For PHPDoctrine 2 - Enterprise Persistence Layer For PHP
Doctrine 2 - Enterprise Persistence Layer For PHPJonathan Wage
 
Introduction To Doctrine 2
Introduction To Doctrine 2Introduction To Doctrine 2
Introduction To Doctrine 2Jonathan Wage
 
Doctrine 2 - Not The Same Old Php Orm
Doctrine 2 - Not The Same Old Php OrmDoctrine 2 - Not The Same Old Php Orm
Doctrine 2 - Not The Same Old Php OrmJonathan Wage
 
Doctrine 2: Enterprise Persistence Layer for PHP
Doctrine 2: Enterprise Persistence Layer for PHPDoctrine 2: Enterprise Persistence Layer for PHP
Doctrine 2: Enterprise Persistence Layer for PHPJonathan Wage
 
Sympal A Cmf Based On Symfony
Sympal   A Cmf Based On SymfonySympal   A Cmf Based On Symfony
Sympal A Cmf Based On SymfonyJonathan Wage
 
Symfony 1.3 + Doctrine 1.2
Symfony 1.3 + Doctrine 1.2Symfony 1.3 + Doctrine 1.2
Symfony 1.3 + Doctrine 1.2Jonathan Wage
 
Sympal - The flexible Symfony CMS
Sympal - The flexible Symfony CMSSympal - The flexible Symfony CMS
Sympal - The flexible Symfony CMSJonathan Wage
 
What's new in Doctrine
What's new in DoctrineWhat's new in Doctrine
What's new in DoctrineJonathan Wage
 
Sympal - Symfony CMS Preview
Sympal - Symfony CMS PreviewSympal - Symfony CMS Preview
Sympal - Symfony CMS PreviewJonathan Wage
 
Doctrine Php Object Relational Mapper
Doctrine Php Object Relational MapperDoctrine Php Object Relational Mapper
Doctrine Php Object Relational MapperJonathan Wage
 
Sympal - The Flexible Symfony Cms
Sympal - The Flexible Symfony CmsSympal - The Flexible Symfony Cms
Sympal - The Flexible Symfony CmsJonathan Wage
 
What's New In Doctrine
What's New In DoctrineWhat's New In Doctrine
What's New In DoctrineJonathan Wage
 

More from Jonathan Wage (20)

Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
OpenSky Infrastructure
OpenSky InfrastructureOpenSky Infrastructure
OpenSky Infrastructure
 
Doctrine In The Real World sflive2011 Paris
Doctrine In The Real World sflive2011 ParisDoctrine In The Real World sflive2011 Paris
Doctrine In The Real World sflive2011 Paris
 
Doctrine in the Real World
Doctrine in the Real WorldDoctrine in the Real World
Doctrine in the Real World
 
ZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine ProjectZendCon2010 The Doctrine Project
ZendCon2010 The Doctrine Project
 
Libertyvasion2010
Libertyvasion2010Libertyvasion2010
Libertyvasion2010
 
Symfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 IntegrationSymfony2 and Doctrine2 Integration
Symfony2 and Doctrine2 Integration
 
Doctrine 2 - Enterprise Persistence Layer For PHP
Doctrine 2 - Enterprise Persistence Layer For PHPDoctrine 2 - Enterprise Persistence Layer For PHP
Doctrine 2 - Enterprise Persistence Layer For PHP
 
Introduction To Doctrine 2
Introduction To Doctrine 2Introduction To Doctrine 2
Introduction To Doctrine 2
 
Doctrine 2 - Not The Same Old Php Orm
Doctrine 2 - Not The Same Old Php OrmDoctrine 2 - Not The Same Old Php Orm
Doctrine 2 - Not The Same Old Php Orm
 
Doctrine 2: Enterprise Persistence Layer for PHP
Doctrine 2: Enterprise Persistence Layer for PHPDoctrine 2: Enterprise Persistence Layer for PHP
Doctrine 2: Enterprise Persistence Layer for PHP
 
Sympal A Cmf Based On Symfony
Sympal   A Cmf Based On SymfonySympal   A Cmf Based On Symfony
Sympal A Cmf Based On Symfony
 
Symfony 1.3 + Doctrine 1.2
Symfony 1.3 + Doctrine 1.2Symfony 1.3 + Doctrine 1.2
Symfony 1.3 + Doctrine 1.2
 
Sympal - The flexible Symfony CMS
Sympal - The flexible Symfony CMSSympal - The flexible Symfony CMS
Sympal - The flexible Symfony CMS
 
What's new in Doctrine
What's new in DoctrineWhat's new in Doctrine
What's new in Doctrine
 
What Is Doctrine?
What Is Doctrine?What Is Doctrine?
What Is Doctrine?
 
Sympal - Symfony CMS Preview
Sympal - Symfony CMS PreviewSympal - Symfony CMS Preview
Sympal - Symfony CMS Preview
 
Doctrine Php Object Relational Mapper
Doctrine Php Object Relational MapperDoctrine Php Object Relational Mapper
Doctrine Php Object Relational Mapper
 
Sympal - The Flexible Symfony Cms
Sympal - The Flexible Symfony CmsSympal - The Flexible Symfony Cms
Sympal - The Flexible Symfony Cms
 
What's New In Doctrine
What's New In DoctrineWhat's New In Doctrine
What's New In Doctrine
 

Recently uploaded

Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...itnewsafrica
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxAna-Maria Mihalceanu
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Nikki Chapple
 
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...itnewsafrica
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsNathaniel Shimoni
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesThousandEyes
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sectoritnewsafrica
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integrationmarketing932765
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Jeffrey Haguewood
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructureitnewsafrica
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 

Recently uploaded (20)

Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...Zeshan Sattar- Assessing the skill requirements and industry expectations for...
Zeshan Sattar- Assessing the skill requirements and industry expectations for...
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance Toolbox
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
Microsoft 365 Copilot: How to boost your productivity with AI – Part two: Dat...
 
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
Irene Moetsana-Moeng: Stakeholders in Cybersecurity: Collaborative Defence fo...
 
Time Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directionsTime Series Foundation Models - current state and future directions
Time Series Foundation Models - current state and future directions
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyesHow to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
How to Effectively Monitor SD-WAN and SASE Environments with ThousandEyes
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
4. Cobus Valentine- Cybersecurity Threats and Solutions for the Public Sector
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS:  6 Ways to Automate Your Data IntegrationBridging Between CAD & GIS:  6 Ways to Automate Your Data Integration
Bridging Between CAD & GIS: 6 Ways to Automate Your Data Integration
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
 
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical InfrastructureVarsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
Varsha Sewlal- Cyber Attacks on Critical Critical Infrastructure
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 

Symfony2 from the Trenches

  • 1. Symfony2 - From the Trenches by Lukas Kahwe Smith, Kris Wallsmith, Thibault Duplessis, Jeremy Mikola, Jordi Boggiano, Jonathan H. Wage, Bulat Shakirzyanov
  • 2. Agenda Getting Setup Caching Code Flow Performance Tips Dependency Injection Asset Management Configuration Choices Testing Controller Choices Deployment Application Choices Third Party Bundles Doctrine Resources
  • 3. Getting the works) PHP 5.3+ with ext/intl (compat lib is in setup Read check.php for details (dev/prod php.ini's from Liip) Using OSX? php53-intl from liangzhenjing or build-entropy-php from chregu Blog post on installing PHP 5.3 with intl from Justin Hileman Initial setup symfony-sandbox symfony-bootstrap Symfony2Project Read the Coding Style Guide (Code Sniffer Rules) Managing external dependencies Submodule: not everything is in git (svn, mercurial, etc.) Vendor install/update scripts: risk of getting out of sync MR (not cross platform)
  • 4. Code Flow 1. Frontend Controller (web/app[_dev].php) Loads autoloader Creates/boots kernel Creates request (from globals) and passes to kernel 2. Kernel Loads app config (app/config/config_[prod|dev|test]) Resolves URL path to a controller (go to 3.) Outputs response returned by the controller 3. Controller Loads model and view Potentially creates a sub-request (go to 2.) Creates response and returns it
  • 6. Dependency Injection All objects are instantiated in one of two ways: Using the "new" operator Using an object factory All objects get collaborators in one of two ways Passed to object constructor Set using a setter
  • 8. <?xml version="1.0" encoding="utf-8" ?> <container xmlns="http://www.symfony-project.org/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <parameters> <parameter key="sitemap.class">BundleAvalancheSitemapBundleSitemap</parameter> </parameters> <services> <service id="sitemap" class="%sitemap.class%" /> </services> </container> Describe Your Services
  • 9. <?php class cachedDevDebugProjectContainer extends Container { /** * Gets the 'sitemap' service. * * @return BundleAvalancheSitemapBundleSitemap */ protected function getSitemapService() { return $this->services['sitemap'] = new BundleAvalancheSitemapBundleSitemap(); } /** * Gets the default parameters. * * @return array An array of the default parameters */ protected function getDefaultParameters() { return array( 'sitemap.class' => 'BundleAvalancheSitemapBundleSitemap' ); } } Service Definitions Are Dumped to Raw PHP
  • 10. Dependency Injection Container Benefits: No performance loss Lazy instantiation Readable service configurations Gotchas: Can become hard to work with if the DI extension tries to do too much Be aware of circular dependencies Might lead to code that cannot be used outside of DIC
  • 12. <?php class SomeClass { private $container; public function __construct(ContainerInterface $container) <service id="some_service" class="SomeClass"> { <argument type="service" id="service_container" /> $this->container = $container; </service> } <!-- or --> // or <service id="some_service" class="SomeClass"> public function setContainer(ContainerInterface $container) <call method="setContainer"> { <argument type="service" id="service_container" /> $this->container = $container; </call> } </service> public function getDocumentManager() { return $this->container->get('document_manager'); } } Container Injection
  • 13. <?php class SomeClass { private $documentManager; public function __construct(DocumentManager $documentManager) { $this->documentManager = $documentManager; } public function getDocumentManager() { return $this->documentManager; } } <service id="some_service" class="SomeClass"> <argument type="service" id="document_manager" /> </service> Constructor Injection
  • 14. <?php class SomeClass { private $documentManager; public function setDocumentManager(DocumentManager $documentManager) { $this->documentManager = $documentManager; } public function getDocumentManager() { return $this->documentManager; } } <service id="some_service" class="SomeClass"> <call method="setDocumentManager"> <argument type="service" id="document_manager" /> </call> </service> Setter Injection
  • 15. <?php interface SomeInterface { function setDocumentManager(DocumentManager $documentManager); } class SomeClass implements SomeInterface { private $documentManager; public function setDocumentManager(DocumentManager $documentManager) { $this->documentManager = $documentManager; } public function getDocumentManager() { return $this->documentManager; } } <interface id="some_service" class="SomeInterface"> <call method="setDocumentManager"> <argument type="service" id="document_manager" /> </call> </interface> <service id="some_service" class="SomeClass" /> Interface Injection
  • 16. Configuration Choices Symfony supports XML, YAML and PHP for configuration YAML and PHP uses underscore to separate words XML uses dashes to separate words XML attributes usually map to array values for YAML/PHP YAML merge key syntax to reuse pieces within a file XSD-aware editors provide auto-completion and validation XML is recommended for Bundle/DI configuration YAML is recommended for application configuration Doctrine does not like it when you mix formats!
  • 17. Controller Choices Defining Controllers as services is optional Non-service controllers must use container injection Create a Bundle Extension to load Bundle services It's recommended to not extend from the base Controller The base controller is mainly a tool for beginners It provides convenience methods that invoke services generateUrl(), redirect(), render()
  • 18. Application Choices Security system makes it possible to have just one application for both frontend and admin backend Location of application is totally flexible, just update the frontend controllers accordingly Large projects should use multiple applications Better separation when multiple teams work Facilitate step-by-step updating and refactoring For example: main, mobile, API, admin
  • 19. Doctrine Examples Retrieve references to entity/document without DB queries Using raw SQL queries with Doctrine2 ORM Simple search engine with Doctrine MongoDB ODM
  • 20. Retrieving References w/o DB Queries $tags = array('baseball', 'basketball'); foreach ($tags as $tag) { $product->addTag($em->getReference('Tag', $tag)); }
  • 21. Raw SQL Queries $rsm = new ResultSetMapping; $rsm->addEntityResult('User', 'u'); $rsm->addFieldResult('u', 'id', 'id'); $rsm->addFieldResult('u', 'name', 'name'); $query = $this->_em->createNativeQuery('SELECT id, name FROM users WHERE name = ?', $rsm); $query->setParameter(1, 'romanb'); $users = $query->getResult(); http://www.doctrine-project.org/docs/orm/2.0/en/reference/native-sql.html
  • 22. Simple Search Engine interface HasKeywords { function setKeywords(); function getKeywords(); }
  • 23. Simple Search Engine /** @mongodb:EmbeddedDocument */ class Keyword { // ... /** @mongodb:String @mongodb:Index */ private $keyword; /** @mongodb:Integer */ private $score; // ... }
  • 24. Simple Search Engine /** @mongodb:Document */ class Product implements HasKeywords { /** @mongodb:Id */ private $id; /** @mongodb:String */ private $title; /** @mongodb:EmbedMany(targetDocument="Keyword") */ private $keywords = array(); // ... }
  • 25. Simple Search Engine class KeywordListener { public function preUpdate(PreUpdateEventArgs $eventArgs) { $entity = $eventArgs->getEntity(); if ($entity instanceof HasKeywords) { $entity->setKeywords($this->buildKeywords($entity)); } } private function buildKeywords(HasKeywords $entity) { $keywords = array(); // build keywords from title, description, etc. return $keywords; } }
  • 26. Simple Search Engine // find products by keyword $products = $dm->createQueryBuilder() ->field('keywords.keyword')->all($keywords) ->getQuery() ->execute();
  • 28. Caching with Edge Side Includes Symfony2 provides support for Edge Side Includes (ESI) Proxy assembles page from snippets of HTML Snippets can have different cache rules Develop without ESI, test with Symfony2 internal ESI proxy, deploy using ultra fast Varnish Proxy Break up page into different controller actions based on cache invalidation rules Do not worry about overhead from multiple render calls Never mix content that has different cache timeouts Varnish Reverse Proxy Super fast, PHP cannot touch the performance Cache full pages for anonymous users Not just for HTML, also useful for JSON/XML API
  • 29. Page Rendered Behind a Reverse Proxy
  • 30. Performance Tips Dump routes to apache rewrite rules Cache warming Do not add optional services to controllers Do minimal work in the controller, let templates pull additional data as needed Use a bytecode cache with MapFileClassLoader
  • 31. Asset Management Go see Kris's talk later today!
  • 32. Testing Symfony2 rocks for unit and functional testing because Dependency Injection No base classes, no static dependencies, no ActiveRecord Client fakes "real" requests for functional testing Functional Testing Pros: Tests configuration, Tests API not implementation Unit Testing Pros: Pinpoints issues, Very directed Testing Recommendation: Functional testing is recommended for controller actions Symfony2 provides WebTestCase and BrowserKit Unit testing for complex algorithms, third party API's too hard to mock Use LiipFunctionalTesting to load fixtures, validate HTML5
  • 33. Deployment Debian style aka Liip Debian Packager Write a manifest in YAML Build Debian packages with MAKE Install with apt-get install Server specific settings are asked during install, change later with dpkg-reconfigure Maintain a global overview of all application dependencies in case of (security) updates
  • 34. Third Party Bundles @weaverryan Ryan Weaver Here's a new year's resolution: to *always* work on an existing Symfony2 bundle and never recreate my own. #focus #teamwork 27 Dec http://twitter.com/weaverryan/status/19565706752299009
  • 35. Third Party Bundles Many vendors have already published bundles: FriendsOfSymfony (http://github.com/friendsofsymfony) UserBundle (forked from knplabs' DoctrineUserBundle) FacebookBundle (forked from kriswallsmith) Liip (http://github.com/liip) FunctionalTestBundle MultiplexBundle ViewBundle Sonata (http://github.com/sonata-project) BaseApplicationBundle Additionally, a few sites currently index community bundles: http://symfony2bundles.org/ http://symfohub.com/
  • 36. Third Party Bundles Bundles should follow the best practices No version-tagging or official package manager (yet) Use bundles by adding git submodules to your project Maintain your own fork and "own" what you use Not all bundles are equally maintained Symfony2 API changes => broken bundles If you track fabpot/symfony, learn to migrate bundles Avoid rewriting a bundle's services/parameters directly The bundle's DI extension should allow for such configuration; if not, submit a pull request If absolutely necessary, a CompilerPass is cleaner
  • 37. Contributing to Third Party Bundles Similar to Symfony2's own patch guidlines Fork and add remote repository Merge regularly to keep up-to-date Avoid committing directly to your master Merges from upstream should be fast-forwards Once upstream changes are stable, bump your project's submodule pointer
  • 38. Contributing to Third Party Bundles Create branches for patches and new features Can't wait to use this in your project? Temporarily change your project submodule to point to your branch until your pull request is accepted. Help ensure that your pull request merges cleanly Create feature branch based on upstream's master Rebase on upstream's master when finished
  • 39. Contributing to Third Party Bundles Was your pull request accepted? Congratulations! Don't merge your feature branch into master! Doing so would cause your master to divert Merge upstream's master into your master Delete your feature branch Update your project's submodule to point to master
  • 40. Resources If you want to jump in and contribute: http://docs.symfony-reloaded.org/master/contributing/community/other. html If you are still fuzzy on Dependency Injection: http://fabien.potencier.org/article/11/what-is-dependency-injection If you keep up with Fabien's Symfony2 repository: http://docs.symfony-reloaded.org/master/