SlideShare a Scribd company logo
symfony
An Open-Source Framework
     for Professionals
         Fabien Potencier
      Stefan Koopmanschap
Before we begin



     How many have already
    used symfony for a project,
even a very small personal project?
Who are we?
•  Fabien Potencier
  –  Founder of Sensio
     •  Web Agency
     •  Since 1998
     •  45 people
     •  Open-Source Specialists
     •  Big corporate customers
  –  Creator and lead developer of symfony


•  Stefan Koopmanschap
  –  Consultant at Ibuildings
  –  Initiator of symfony-framework.nl and symfonyCamp
  –  symfony developer for 2 years
symfony
•  PHP Web framework
•  Based on
   –  10 years of Sensio experience
   –  Existing Open-Source projects


•  Built for :
   –  Professional websites
   –  Complex needs
   –  Demanding environments
Framework
Whatever the application, a
  framework is build to ease
development by providing tools
for recurrent and boring tasks.
Maintainability & Evolutivity
Structure & Standardisation
MVC
Model
View
Controller
1



                 Internet

             2

           Controleur             6

      3                 5

  Modèle                    Vue

  4

BDD
Develop Faster & Better
Write less code


                          less code
                              
                       less complexity
                              
                          less bugs
                              
                      more productivity
                              
                          more time


More time for edge cases, business rules, …
Each line of code has an initial cost

                     Costinitial = Costdeveloppement + Costtests


… and there is a cost to maintain the line


                           Costmaintenance >> Costinitial




    Costmaintenance = Costunderstanding + Costchange + Costtests + Costdeployment




                          Kent Beck (based on Yourdon and Constantine)
symfony
An Open-Source Framework
MIT Licence


  « It is a permissive license, meaning that it permits
   reuse within proprietary software on the condition
   that the license is distributed with that software. »
An Open-Source Documentation
•  Open-Source documentation
  –  The book (450 pages - GFDL)
  –  Askeet Tutorial (250 pages)


•  Translation in 12 langages
  –     (Chinese)      –  Polski
  –  Deutsch           –  Português
  –  Español           –  Russian
  –  Français          –  Ukrainian
  –  Italiano          –  Čeština
  –       (Japanese)
                       –  Nederlands
symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)
A great Community
Mailing-list support / forums / IRC

240 available plugins

300k unique visitors per month on the official
  website www.symfony-project.org
« Entreprise » Version
Version 1.0 released early 2007

  – Maintained for 3 years (early 2010)
  – ~1 release a month (1.0.16 now)
    • Bug and security fixes, compatibility with
      new PHP versions fixes
    • No new features (even small ones)
    • Upgrading is simple and safe
Version 1.1 to be released this month
  – Maintained for 1 year
  – Same release cycle as 1.0


Roadmap
  – Version 1.2 Q4 2008
  – Version 1.3 Q1 2009
symfony is a set of cohesive
  but decoupled classes
symfony platform
symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)
symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)
symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)
symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)
symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)
sfEventDispatcher
// sfUser!
$event = new sfEvent($this, ‘user.change_culture’,
   array(‘culture’ => $culture));!
$dispatcher->notify($event);!

// sfI18N!
$callback = array($this, ‘listenToChangeCultureEvent’);!
$dispatcher->connect(‘user.change_culture’, $callback);!


•  sfI18N and sfUser are decoupled
•  « Anybody » can listen to any event
•  You can notify existing events or create new ones
the symfony MVC framework
         is based on
    the symfony platform
symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)
symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)
symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)
Let’s start a Project
The Project
•  A simple blog system
  –  Posts
  –  Categories
  –  Authors
  –  Comments
•  Requirements
  –  Maintainable
  –  Customizable
  –  Secure
•  Use symfony 1.1
List of recent posts


             Excerpt



                                Categories
             Post information
Sidebar customization


List of comments




Add a comment
YUI stylesheets

                          homepage



Famfamfam icons



             post




  http://www.symfony-project.org/get/design.tgz
Project Initialization
Bootstrap a symfony Project

1.  Install symfony

2.  Initialize a new project

3.  Configure the Web Server

4.  Start coding
Installing symfony

Sandbox: Ready-to-run symfony application

PEAR: Install symfony globally on your machine

Subversion: Be free to have several versions around
symfony CLI
$ symfony!
Create a new Project

$ mkdir blog!
$ cd blog!
$ symfony generate:project blog!
Create a new Application
./symfony help generate:app!
Create a new secure Application
   ./symfony generate:app frontend !
             --escaping-strategy=on !
             --csrf-secret=A$ecret!
Project, Application, Module, Action
Which symfony Version?

./symfony -V!




config/ProjectConfiguration.class.php!
Configure the Web Server
<VirtualHost *:80>
  ServerName myapp.example.com
  DocumentRoot "/path/to/blog/web"
  DirectoryIndex index.php

  <Directory "/path/to/blog/web">
    AllowOverride All
    Allow from All                   Web root directory is web/
  </Directory>
</VirtualHost>
symfony Assets
Used by the default pages and the Web Debug Toolbar

Configure the Web Server to serve symfony assets
            <VirtualHost *:80>
              …
              Alias /sf /$sf_symfony_data_dir/web/sf
              <Directory "/$sf_symfony_data_dir/web/sf">
                AllowOverride All
                Allow from All
              </Directory>
            </VirtualHost>


Or, create a symlink
         $ cd web/
         $ ln -sf ../lib/vendor/symfony/data/web/sf sf
Environments
developers   customers     end users




development     staging      production
environment   environment   environment
cache        cache         cache

   debug        debug         debug

    logs         logs          logs

                              stats
    stats        stats


development     staging      production
environment   environment   environment
Try a 404
dev environment!
                               prod environment!
Front Controllers
dev environment!




                                 environment


                                       prod environment!




                                    environment
Environment Configuration
apps/frontend/config/settings.yml!

      environment




           Web debug toolbar
Web Debug Toolbar

      Web debug toolbar
Create a Module for Posts
Create a new ‘post’ module in the ‘frontend’
  application

      $ php symfony generate:module frontend post!
Project, Application, Module, Action
Action and Template Naming
/frontend_dev.php/blog/index


                 module action

// in apps/frontend/modules/blog/actions/actions.class.php
<?php

class blogActions extends sfActions
{
  public function executeIndex()
  {
    // do things
  }
}

// in apps/frontend/modules/blog/templates/indexSuccess.php
<!–- do things -->
Browse
/frontend_dev.php/post/index!
Create the Blog Homepage
apps/frontend/modules/post/templates/indexSuccess.php!

•  Copy homepage.html into indexSuccess.php
•  Copy the images/ and css/ under web/
•  Add the base.css CSS in view.yml
•  Fix images and css paths
                                /frontend_dev.php/post/index!
Create an Action to show a Post
apps/frontend/modules/post/actions/actions.class.php!

•  Create an empy executeShow() action
•  Copy post.html into showSuccess.php
•  Fix images and css paths
                                /frontend_dev.php/post/show!
Project, Application, Module, Action
Extract common Code

                            Post page specific content




Homepage specific content
The Layout
   A layout wraps the template content

          header.php
                                   page content
                         include

                                      decoration

          page content


include


           footer.php
                                           layout.php
The Layout
Move the common code from homepage and post to
  the layout

         apps/frontend/templates/layout.php!
Customize the Sidebar and the Title
                            The title depends on the page




         The sidebar depends on the page
Layout with Several "holes"
A slot content depends on the template context


           Slot1
                          Main
                         content
 Slot 2




           Main     +                =
          content
                          Slot 1
                          Slot 2


    Layout              Template         Rendered
                        with slots         Page
Create Slots for Title and Sidebar
apps/frontend/templates/layout.php!
Fill the Slots
apps/frontend/modules/blog/templates/showSuccess.php!
Passing Data from Action to Template
apps/frontend/modules/blog/actions/actions.class.php!




    apps/frontend/modules/blog/templates/indexSuccess.php!
Make the Counter dynamic
Database Schema


A post has an author

A post can be in a category

A post can have comments
Propel : The symfony ORM
ORM = Object-Relational Mapping
Mapping a relational database to an object-oriented
  model
Database Abstraction

            Relational    Object-Oriented
         table            class
         row, record      object
         field, column    proterty
Schema Conventions
post:
  id:           #   primary key, autoincrement integer
  author_id:    #   foreign key to Author
  created_at:   #   timestamp, set to current time on creation
  updated_at:   #   timestamp, set to current time on update

 # column types
 published_at: timestamp
 title:         varchar(255)
 content:       longvarchar
 is_spam:       boolean

 # complex column definitions
 last_name:   { type: varchar(100), index: true, required: true }
 category_id:     { type: integer, foreignTable: category,
    foreignReference: id, required: false, onDelete: setnull }
Database Schema
config/schema.yml!
Build the Model Classes
./symfony propel:build-model!
From Schema to Object Model

             $ ./symfony propel:build-model!

propel:                               lib/
  post:                                 model/
    id:   ~                                om/
    name: varchar(255)                       BasePost.php
                                             BasePostPeer.php
                                           Post.php
                                           PostPeer.php




                         1 table > 4 classes?
Base and Custom Classes
lib/
  model/
                          Base classes
     om/                     Under model/om/, prefixed by Base
       BasePost.php
       BasePostPeer.php      Generated by Propel
     Post.php                Overwritten each time the schema
     PostPeer.php
                               changes and the model is
                               generated
                             Never edit these files!
lib/                       Custom classes
  model/
     om/                      Under model/, no prefix
       BasePost.php
                              Inherit from Base classes
       BasePostPeer.php
     Post.php                 Never overwritten
     PostPeer.php
                              Put custom methods here
                              Override base methods here
Peer and Object Classes
lib/                      Peer classes
  model/
     om/                     Suffixed by Peer
       BasePost.php          Useful to retrieve a collection of objects
       BasePostPeer.php
    Post.php                 Methods return objects
     PostPeer.php            Only static methods (::, self)


lib/                      Object classes
  model/
     om/
                             No suffix
       BasePost.php          Useful to create / inspect / update
       BasePostPeer.php       records
     Post.php                Methods return column values
    PostPeer.php             Only object methods (->, $this)
Database Initialization



mysqladmin create dutchconference!
./symfony configure:database mysql://localhost/dutchconference!
Build the SQL queries
./symfony propel:build-sql!




./symfony propel:insert-sql!
Shortcut for all the previous Tasks



          ./symfony propel:build-all!
Initial Data
data/fixtures/01-data.yml!


             Define PKs with names




             Use names instead of Pks

                            Dynamic values
Load Data
$ ./symfony propel:data-load frontend!
Summary of Code Generation

           2                     Object model
           propel:build-model!   Base, Custom,
                                 Peer and object classes

1
 schema.yml

       3   propel:build-sql!
           propel:insert-sql!
                                 Relational database
                                 Tables, columns, keys, indexes
If the Database preexists the Project

           3                      Object model
            propel:build-model!   Base, Custom,
                                  Peer and object classes

2
 schema.yml

       1
           propel:build-schema!
                                  Relational database
                                  Tables, columns, keys, indexes
Generated Methods of Object Classes
Getter for columns
  $title     = $post->getTitle();           CamelCase version
  $content   = $post->getContent();         of the column name
  $createdAt = $post->getCreatedAt();


Some getters have special options
  $date      = $post->getCreatedAt($dateFormat);


Getter by name
  $title     = $post->getByName('title');
Generated Methods of Object Classes
Manipulate primary keys
   $commentId = $comment->getId();
   // for composite keys, prefer
   $commentId = $comment->getPrimaryKey();


Manipulate foreign keys
   $postId = $comment->getPostId();
   // in practice, these methods are not used much
   // use getter for foreign objects instead
   $post    = $comment->getPost();     // Post object
   // as the result is an object, you can chain method calls
   $content = $comment->getPost()->getContent();


One-to-Many smart getters
   $comments   = $post->getCommments();   // Array of Comments
   $nb         = $post->countCommments(); // Integer
Get the Posts from the Database
What the Model Layer does
Action                Model                     Database


    PostPeer::doSelect(new Criteria())!

                           Criteria to SQL translation
                           SELECT * FROM post!


                                                         Query execution
                                        resultset!


                           Object hydrating
  Array of Post objects!
What the Model Layer does
Template                Model                   Database


   $post->getTitle()!

                            Looking up internal attribute
           String!
Make the Post show Page dynamic

/frontend_dev.php/post/show?id=1!
Make the Post show Page dynamic




           Display a 404 error if the post does not exist
Change the Date Format
getPublishedAt() first argument accepts the date()
  format or the strftime() format

symfony format_date() helper is i18n aware
Helper Groups
•  Tag
•  URLs
•  Assets (images, JavaScript, CSS, …)
•  Subtemplate inclusion (slot, partial, component)
•  Links
•  Form
•  Javascript and Ajax
•  Text, number, date manipulation
•  I18N
•  …
Permalinks
•  Many applications provide an alternative to
   functional URLs
•  Permalinks look like links to permanent content
   while the resource they reference is dynamically
   generated
•  Primarily focused at search engines, permalink
   often carry more readable data for end users

http://www.symfony-project.org/blog/2008/05/21/new-symfony-security-policy
Links to the Post Page
apps/frontend/config/routing.yml!




                                   lib/modełPost.php!
Links to the Post Page

apps/frontend/modules/post/templates/indexSuccess.php!




        apps/frontend/modules/post/actions/actions.class.php!
Link to the Homepage
Add the Comments
apps/frontend/modules/post/templates/showSuccess.php!
What the Model Layer does
Template              Model                  Database


    $post->getComments()!


                            SELECT * FROM comment!
                            WHERE comment.post_id= ?!


                                                    Query execution!
                                       resultset!


Array of Comment objects!
                            Object hydrating!
Comment Form
$ ./symfony propel:build-forms!
Base and Custom Classes
lib/                              Base classes
  form/
     base/
                                     Under form/base/, prefixed by Base
       BasePostForm.class.php        Generated by symfony
     PostForm.class.php
                                     Overwritten when the schema
                                       changes and the forms are
                                       generated
                                     Never edit these files!
 lib/                              Custom classes
   form/
      base/                           Under form/, no prefix
        BasePost.Form.class.php
                                      Inherit from Base classes
      PostForm.class.php
                                      Never overwritten
                                      Put custom methods here
                                      Override base methods here
Create a Comment Form
apps/frontend/modules/post/actions/actions.class.php!




apps/frontend/modules/post/templates/showSuccess.php!
Create a Comment Form
Propel Forms
•  Generated by propel:build-forms
•  1 table = 1 form
•  Model introspection to determine
  –  The widget
  –  The validation rules
•  Automatically converts a form to a Propel object
   and save it to the database
•  Extensible
Bind The Form to the Post
Customize the Form
lib/form/CommentForm.class.php!
Form Life Cycle
Comments
Security: XSS
Security: CSRF
Create the Category Page
lib/modełPostPeer.class.php!




         apps/frontend/modules/blog/actions/actions.class.php!
Create the Category Page
apps/frontend/config/routing.yml!




                           apps/frontend/templates/layout.php!
Create a Partial for the List
apps/frontend/modules/blog/templates/_list.php!




apps/frontend/modules/blog/templates/listByCategorySuccess.php!
Create a Component
apps/frontend/modules/post/actions/components.class.php!




apps/frontend/modules/post/templates/_categories.php!




                              apps/frontend/templates/layout.php!
Create a Web Service for Posts
apps/frontend/config/routing.yml!




  apps/frontend/modules/post/templates/indexSuccess.xml.php!
If we have time…
•  Functional Tests

•  Cache

•  CRUD to manage posts
Sensio S.A.
                     26, rue Salomon de Rothschild
                         92 286 Suresnes Cedex
                                FRANCE
                         Tél. : +33 1 40 99 80 80

                                Contact
                           Fabien Potencier
                     fabien.potencier@sensio.com




http://www.sensiolabs.com/                http://www.symfony-project.com/

More Related Content

PDF
symfony: An Open-Source Framework for Professionals (PHP Day 2008)
PPTX
Composer for Magento 1.x and Magento 2
PDF
Modern Web Application Development Workflow - web2day 2014
PPTX
Introduction to Apache Cordova (Phonegap)
PPTX
Zend con 2016 bdd with behat for beginners
PDF
Apache Cordova: Overview and Introduction
PDF
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2...
PDF
A Phing fairy tale - ConFoo13
symfony: An Open-Source Framework for Professionals (PHP Day 2008)
Composer for Magento 1.x and Magento 2
Modern Web Application Development Workflow - web2day 2014
Introduction to Apache Cordova (Phonegap)
Zend con 2016 bdd with behat for beginners
Apache Cordova: Overview and Introduction
symfony: Simplify your professional web development with PHP (IPC Frankfurt 2...
A Phing fairy tale - ConFoo13

What's hot (18)

PPTX
Debugging with Zend Studio for Eclipse
PDF
Apache cordova
PDF
symfony: Simplify your professional web development with PHP (Symfony PHP Que...
PPTX
WordPress and Zend Framework Integration with Vulnero
PDF
David Coletta Architecting A Shared Codebase For Browser And Desktop Final
PDF
Cordova: APIs and instruments
PDF
WordCamp Sacramento 2019: Modernizing Your Development Workflow Using Composer
PPT
PDF
Django in the Real World
PDF
Best Practices in PHP Application Deployment
PDF
Composer - The missing package manager for PHP
PDF
Apache Cordova
PPTX
Take Command of WordPress With WP-CLI
PDF
Cross-platform mobile apps with Apache Cordova
PDF
Symfony Day 2009 - Symfony vs Integrating products
PPTX
Creating a Plug-In Architecture
PPTX
From Ant to Maven to Gradle a tale of CI tools for JVM
PDF
Getting started-with-zend-framework
Debugging with Zend Studio for Eclipse
Apache cordova
symfony: Simplify your professional web development with PHP (Symfony PHP Que...
WordPress and Zend Framework Integration with Vulnero
David Coletta Architecting A Shared Codebase For Browser And Desktop Final
Cordova: APIs and instruments
WordCamp Sacramento 2019: Modernizing Your Development Workflow Using Composer
Django in the Real World
Best Practices in PHP Application Deployment
Composer - The missing package manager for PHP
Apache Cordova
Take Command of WordPress With WP-CLI
Cross-platform mobile apps with Apache Cordova
Symfony Day 2009 - Symfony vs Integrating products
Creating a Plug-In Architecture
From Ant to Maven to Gradle a tale of CI tools for JVM
Getting started-with-zend-framework
Ad

Similar to symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008) (20)

PDF
Symfony quick tour_2.3
PDF
symfony_from_scratch
PDF
symfony_from_scratch
PDF
C:\fake path\askeet 1.0-en
PDF
Symfony workshop introductory slides
PDF
Symfony for non-techies
PDF
Implementing a Symfony Based CMS in a Publishing Company
PDF
Symfony2 San Francisco Meetup 2009
PPT
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
PPTX
Dev traning 2016 symfony
PPTX
Building A Platform From Open Source At Yahoo
PDF
Symfony 2.0 on PHP 5.3
ODP
Routing
PDF
Hands-on with the Symfony2 Framework
PDF
Introducing symfony
PPTX
PDF
PHP Frameworks and Symfony
PDF
symfony: Open-Source Enterprise Framework
PDF
Symfony2 - OSIDays 2010
PDF
Symfony2 - WebExpo 2010
Symfony quick tour_2.3
symfony_from_scratch
symfony_from_scratch
C:\fake path\askeet 1.0-en
Symfony workshop introductory slides
Symfony for non-techies
Implementing a Symfony Based CMS in a Publishing Company
Symfony2 San Francisco Meetup 2009
Workshop: Symfony2 Intruduction: (Controller, Routing, Model)
Dev traning 2016 symfony
Building A Platform From Open Source At Yahoo
Symfony 2.0 on PHP 5.3
Routing
Hands-on with the Symfony2 Framework
Introducing symfony
PHP Frameworks and Symfony
symfony: Open-Source Enterprise Framework
Symfony2 - OSIDays 2010
Symfony2 - WebExpo 2010
Ad

More from Fabien Potencier (20)

PDF
PDF
Look beyond PHP
PDF
Dependency injection in PHP 5.3/5.4
PDF
Dependency injection-zendcon-2010
PDF
Caching on the Edge
PDF
Design patterns revisited with PHP 5.3
PDF
The state of Symfony2 - SymfonyDay 2010
PDF
PhpBB meets Symfony2
PDF
Dependency injection - phpday 2010
PDF
Symfony2 - WebExpo 2010
PDF
Dependency Injection IPC 201
PDF
Caching on the Edge with Symfony2
PDF
Unit and Functional Testing with Symfony2
PDF
News of the Symfony2 World
PDF
Dependency Injection - ConFoo 2010
PDF
Dependency Injection
PDF
Symfony Components
PDF
PHP 5.3 in practice
PDF
Symfony2 revealed
PDF
Dependency Injection with PHP 5.3
Look beyond PHP
Dependency injection in PHP 5.3/5.4
Dependency injection-zendcon-2010
Caching on the Edge
Design patterns revisited with PHP 5.3
The state of Symfony2 - SymfonyDay 2010
PhpBB meets Symfony2
Dependency injection - phpday 2010
Symfony2 - WebExpo 2010
Dependency Injection IPC 201
Caching on the Edge with Symfony2
Unit and Functional Testing with Symfony2
News of the Symfony2 World
Dependency Injection - ConFoo 2010
Dependency Injection
Symfony Components
PHP 5.3 in practice
Symfony2 revealed
Dependency Injection with PHP 5.3

Recently uploaded (20)

PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PPTX
Big Data Technologies - Introduction.pptx
PDF
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Empathic Computing: Creating Shared Understanding
PPTX
Spectroscopy.pptx food analysis technology
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
cuic standard and advanced reporting.pdf
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PPTX
Machine Learning_overview_presentation.pptx
PDF
Machine learning based COVID-19 study performance prediction
PDF
Encapsulation_ Review paper, used for researhc scholars
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
sap open course for s4hana steps from ECC to s4
PDF
Chapter 3 Spatial Domain Image Processing.pdf
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PPTX
A Presentation on Artificial Intelligence
The Rise and Fall of 3GPP – Time for a Sabbatical?
Big Data Technologies - Introduction.pptx
Profit Center Accounting in SAP S/4HANA, S4F28 Col11
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Empathic Computing: Creating Shared Understanding
Spectroscopy.pptx food analysis technology
Reach Out and Touch Someone: Haptics and Empathic Computing
Dropbox Q2 2025 Financial Results & Investor Presentation
cuic standard and advanced reporting.pdf
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Machine Learning_overview_presentation.pptx
Machine learning based COVID-19 study performance prediction
Encapsulation_ Review paper, used for researhc scholars
MYSQL Presentation for SQL database connectivity
sap open course for s4hana steps from ECC to s4
Chapter 3 Spatial Domain Image Processing.pdf
Digital-Transformation-Roadmap-for-Companies.pptx
Diabetes mellitus diagnosis method based random forest with bat algorithm
A Presentation on Artificial Intelligence

symfony: An Open-Source Framework for Professionals (Dutch Php Conference 2008)

  • 1. symfony An Open-Source Framework for Professionals Fabien Potencier Stefan Koopmanschap
  • 2. Before we begin How many have already used symfony for a project, even a very small personal project?
  • 3. Who are we? •  Fabien Potencier –  Founder of Sensio •  Web Agency •  Since 1998 •  45 people •  Open-Source Specialists •  Big corporate customers –  Creator and lead developer of symfony •  Stefan Koopmanschap –  Consultant at Ibuildings –  Initiator of symfony-framework.nl and symfonyCamp –  symfony developer for 2 years
  • 4. symfony •  PHP Web framework •  Based on –  10 years of Sensio experience –  Existing Open-Source projects •  Built for : –  Professional websites –  Complex needs –  Demanding environments
  • 6. Whatever the application, a framework is build to ease development by providing tools for recurrent and boring tasks.
  • 9. MVC
  • 10. Model
  • 11. View
  • 13. 1 Internet 2 Controleur 6 3 5 Modèle Vue 4 BDD
  • 15. Write less code less code  less complexity  less bugs  more productivity  more time More time for edge cases, business rules, …
  • 16. Each line of code has an initial cost Costinitial = Costdeveloppement + Costtests … and there is a cost to maintain the line Costmaintenance >> Costinitial Costmaintenance = Costunderstanding + Costchange + Costtests + Costdeployment Kent Beck (based on Yourdon and Constantine)
  • 19. MIT Licence « It is a permissive license, meaning that it permits reuse within proprietary software on the condition that the license is distributed with that software. »
  • 21. •  Open-Source documentation –  The book (450 pages - GFDL) –  Askeet Tutorial (250 pages) •  Translation in 12 langages –  (Chinese) –  Polski –  Deutsch –  Português –  Español –  Russian –  Français –  Ukrainian –  Italiano –  Čeština –  (Japanese) –  Nederlands
  • 24. Mailing-list support / forums / IRC 240 available plugins 300k unique visitors per month on the official website www.symfony-project.org
  • 26. Version 1.0 released early 2007 – Maintained for 3 years (early 2010) – ~1 release a month (1.0.16 now) • Bug and security fixes, compatibility with new PHP versions fixes • No new features (even small ones) • Upgrading is simple and safe
  • 27. Version 1.1 to be released this month – Maintained for 1 year – Same release cycle as 1.0 Roadmap – Version 1.2 Q4 2008 – Version 1.3 Q1 2009
  • 28. symfony is a set of cohesive but decoupled classes
  • 35. sfEventDispatcher // sfUser! $event = new sfEvent($this, ‘user.change_culture’, array(‘culture’ => $culture));! $dispatcher->notify($event);! // sfI18N! $callback = array($this, ‘listenToChangeCultureEvent’);! $dispatcher->connect(‘user.change_culture’, $callback);! •  sfI18N and sfUser are decoupled •  « Anybody » can listen to any event •  You can notify existing events or create new ones
  • 36. the symfony MVC framework is based on the symfony platform
  • 40. Let’s start a Project
  • 41. The Project •  A simple blog system –  Posts –  Categories –  Authors –  Comments •  Requirements –  Maintainable –  Customizable –  Secure •  Use symfony 1.1
  • 42. List of recent posts Excerpt Categories Post information
  • 43. Sidebar customization List of comments Add a comment
  • 44. YUI stylesheets homepage Famfamfam icons post http://www.symfony-project.org/get/design.tgz
  • 46. Bootstrap a symfony Project 1.  Install symfony 2.  Initialize a new project 3.  Configure the Web Server 4.  Start coding
  • 47. Installing symfony Sandbox: Ready-to-run symfony application PEAR: Install symfony globally on your machine Subversion: Be free to have several versions around
  • 49. Create a new Project $ mkdir blog! $ cd blog! $ symfony generate:project blog!
  • 50. Create a new Application ./symfony help generate:app!
  • 51. Create a new secure Application ./symfony generate:app frontend ! --escaping-strategy=on ! --csrf-secret=A$ecret!
  • 53. Which symfony Version? ./symfony -V! config/ProjectConfiguration.class.php!
  • 54. Configure the Web Server <VirtualHost *:80> ServerName myapp.example.com DocumentRoot "/path/to/blog/web" DirectoryIndex index.php <Directory "/path/to/blog/web"> AllowOverride All Allow from All Web root directory is web/ </Directory> </VirtualHost>
  • 55. symfony Assets Used by the default pages and the Web Debug Toolbar Configure the Web Server to serve symfony assets <VirtualHost *:80> … Alias /sf /$sf_symfony_data_dir/web/sf <Directory "/$sf_symfony_data_dir/web/sf"> AllowOverride All Allow from All </Directory> </VirtualHost> Or, create a symlink $ cd web/ $ ln -sf ../lib/vendor/symfony/data/web/sf sf
  • 57. developers customers end users development staging production environment environment environment
  • 58. cache cache cache debug debug debug logs logs logs stats stats stats development staging production environment environment environment
  • 59. Try a 404 dev environment! prod environment!
  • 60. Front Controllers dev environment! environment prod environment! environment
  • 62. Web Debug Toolbar Web debug toolbar
  • 63. Create a Module for Posts Create a new ‘post’ module in the ‘frontend’ application $ php symfony generate:module frontend post!
  • 65. Action and Template Naming /frontend_dev.php/blog/index module action // in apps/frontend/modules/blog/actions/actions.class.php <?php class blogActions extends sfActions { public function executeIndex() { // do things } } // in apps/frontend/modules/blog/templates/indexSuccess.php <!–- do things -->
  • 67. Create the Blog Homepage apps/frontend/modules/post/templates/indexSuccess.php! •  Copy homepage.html into indexSuccess.php •  Copy the images/ and css/ under web/ •  Add the base.css CSS in view.yml •  Fix images and css paths /frontend_dev.php/post/index!
  • 68. Create an Action to show a Post apps/frontend/modules/post/actions/actions.class.php! •  Create an empy executeShow() action •  Copy post.html into showSuccess.php •  Fix images and css paths /frontend_dev.php/post/show!
  • 70. Extract common Code Post page specific content Homepage specific content
  • 71. The Layout A layout wraps the template content header.php page content include decoration page content include footer.php layout.php
  • 72. The Layout Move the common code from homepage and post to the layout apps/frontend/templates/layout.php!
  • 73. Customize the Sidebar and the Title The title depends on the page The sidebar depends on the page
  • 74. Layout with Several "holes" A slot content depends on the template context Slot1 Main content Slot 2 Main + = content Slot 1 Slot 2 Layout Template Rendered with slots Page
  • 75. Create Slots for Title and Sidebar apps/frontend/templates/layout.php!
  • 77. Passing Data from Action to Template apps/frontend/modules/blog/actions/actions.class.php! apps/frontend/modules/blog/templates/indexSuccess.php!
  • 78. Make the Counter dynamic
  • 79. Database Schema A post has an author A post can be in a category A post can have comments
  • 80. Propel : The symfony ORM ORM = Object-Relational Mapping Mapping a relational database to an object-oriented model Database Abstraction Relational Object-Oriented table class row, record object field, column proterty
  • 81. Schema Conventions post: id: # primary key, autoincrement integer author_id: # foreign key to Author created_at: # timestamp, set to current time on creation updated_at: # timestamp, set to current time on update # column types published_at: timestamp title: varchar(255) content: longvarchar is_spam: boolean # complex column definitions last_name: { type: varchar(100), index: true, required: true } category_id: { type: integer, foreignTable: category, foreignReference: id, required: false, onDelete: setnull }
  • 83. Build the Model Classes ./symfony propel:build-model!
  • 84. From Schema to Object Model $ ./symfony propel:build-model! propel: lib/ post: model/ id: ~ om/ name: varchar(255) BasePost.php BasePostPeer.php Post.php PostPeer.php 1 table > 4 classes?
  • 85. Base and Custom Classes lib/ model/ Base classes om/ Under model/om/, prefixed by Base BasePost.php BasePostPeer.php Generated by Propel Post.php Overwritten each time the schema PostPeer.php changes and the model is generated Never edit these files! lib/ Custom classes model/ om/ Under model/, no prefix BasePost.php Inherit from Base classes BasePostPeer.php Post.php Never overwritten PostPeer.php Put custom methods here Override base methods here
  • 86. Peer and Object Classes lib/ Peer classes model/ om/ Suffixed by Peer BasePost.php Useful to retrieve a collection of objects BasePostPeer.php Post.php Methods return objects PostPeer.php Only static methods (::, self) lib/ Object classes model/ om/ No suffix BasePost.php Useful to create / inspect / update BasePostPeer.php records Post.php Methods return column values PostPeer.php Only object methods (->, $this)
  • 87. Database Initialization mysqladmin create dutchconference! ./symfony configure:database mysql://localhost/dutchconference!
  • 88. Build the SQL queries ./symfony propel:build-sql! ./symfony propel:insert-sql!
  • 89. Shortcut for all the previous Tasks ./symfony propel:build-all!
  • 90. Initial Data data/fixtures/01-data.yml! Define PKs with names Use names instead of Pks Dynamic values
  • 91. Load Data $ ./symfony propel:data-load frontend!
  • 92. Summary of Code Generation 2 Object model propel:build-model! Base, Custom, Peer and object classes 1 schema.yml 3 propel:build-sql! propel:insert-sql! Relational database Tables, columns, keys, indexes
  • 93. If the Database preexists the Project 3 Object model propel:build-model! Base, Custom, Peer and object classes 2 schema.yml 1 propel:build-schema! Relational database Tables, columns, keys, indexes
  • 94. Generated Methods of Object Classes Getter for columns $title = $post->getTitle(); CamelCase version $content = $post->getContent(); of the column name $createdAt = $post->getCreatedAt(); Some getters have special options $date = $post->getCreatedAt($dateFormat); Getter by name $title = $post->getByName('title');
  • 95. Generated Methods of Object Classes Manipulate primary keys $commentId = $comment->getId(); // for composite keys, prefer $commentId = $comment->getPrimaryKey(); Manipulate foreign keys $postId = $comment->getPostId(); // in practice, these methods are not used much // use getter for foreign objects instead $post = $comment->getPost(); // Post object // as the result is an object, you can chain method calls $content = $comment->getPost()->getContent(); One-to-Many smart getters $comments = $post->getCommments(); // Array of Comments $nb = $post->countCommments(); // Integer
  • 96. Get the Posts from the Database
  • 97. What the Model Layer does Action Model Database PostPeer::doSelect(new Criteria())! Criteria to SQL translation SELECT * FROM post! Query execution resultset! Object hydrating Array of Post objects!
  • 98. What the Model Layer does Template Model Database $post->getTitle()! Looking up internal attribute String!
  • 99. Make the Post show Page dynamic /frontend_dev.php/post/show?id=1!
  • 100. Make the Post show Page dynamic Display a 404 error if the post does not exist
  • 101. Change the Date Format getPublishedAt() first argument accepts the date() format or the strftime() format symfony format_date() helper is i18n aware
  • 102. Helper Groups •  Tag •  URLs •  Assets (images, JavaScript, CSS, …) •  Subtemplate inclusion (slot, partial, component) •  Links •  Form •  Javascript and Ajax •  Text, number, date manipulation •  I18N •  …
  • 103. Permalinks •  Many applications provide an alternative to functional URLs •  Permalinks look like links to permanent content while the resource they reference is dynamically generated •  Primarily focused at search engines, permalink often carry more readable data for end users http://www.symfony-project.org/blog/2008/05/21/new-symfony-security-policy
  • 104. Links to the Post Page apps/frontend/config/routing.yml! lib/modełPost.php!
  • 105. Links to the Post Page apps/frontend/modules/post/templates/indexSuccess.php! apps/frontend/modules/post/actions/actions.class.php!
  • 106. Link to the Homepage
  • 108. What the Model Layer does Template Model Database $post->getComments()! SELECT * FROM comment! WHERE comment.post_id= ?! Query execution! resultset! Array of Comment objects! Object hydrating!
  • 109. Comment Form $ ./symfony propel:build-forms!
  • 110. Base and Custom Classes lib/ Base classes form/ base/ Under form/base/, prefixed by Base BasePostForm.class.php Generated by symfony PostForm.class.php Overwritten when the schema changes and the forms are generated Never edit these files! lib/ Custom classes form/ base/ Under form/, no prefix BasePost.Form.class.php Inherit from Base classes PostForm.class.php Never overwritten Put custom methods here Override base methods here
  • 111. Create a Comment Form apps/frontend/modules/post/actions/actions.class.php! apps/frontend/modules/post/templates/showSuccess.php!
  • 113. Propel Forms •  Generated by propel:build-forms •  1 table = 1 form •  Model introspection to determine –  The widget –  The validation rules •  Automatically converts a form to a Propel object and save it to the database •  Extensible
  • 114. Bind The Form to the Post
  • 120. Create the Category Page lib/modełPostPeer.class.php! apps/frontend/modules/blog/actions/actions.class.php!
  • 121. Create the Category Page apps/frontend/config/routing.yml! apps/frontend/templates/layout.php!
  • 122. Create a Partial for the List apps/frontend/modules/blog/templates/_list.php! apps/frontend/modules/blog/templates/listByCategorySuccess.php!
  • 124. Create a Web Service for Posts apps/frontend/config/routing.yml! apps/frontend/modules/post/templates/indexSuccess.xml.php!
  • 125. If we have time… •  Functional Tests •  Cache •  CRUD to manage posts
  • 126. Sensio S.A. 26, rue Salomon de Rothschild 92 286 Suresnes Cedex FRANCE Tél. : +33 1 40 99 80 80 Contact Fabien Potencier [email protected] http://www.sensiolabs.com/ http://www.symfony-project.com/