SlideShare a Scribd company logo
1 of 43
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 setup
PHP 5.3+ with ext/intl (compat lib is in the works)
    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
<?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
Service Container (aka DIC)

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
<?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 in
   YAML/PHP
   YAML merge key syntax to reuse pieces within a file
   XSD-aware editors provide auto-completion/validation
XML is recommended for Bundle/DI configuration
YAML is recommended for application configuration
Bundle extensions can optionally utilize the Config
component to normalize/parse configurations in any format
   See FrameworkExtension, SecurityExtension, TwigExtension
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,
     such as generateUrl(), redirect(), render()
Application Choices

Security system makes it possible to have just one
application for both frontend and admin backend
Location of AppKernel 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();
Doctrine in the Real World

Go see Jon Wage's talk at later today!
Database Migrations

Deploy DB schema changes before the code
Prevent DB schema BC breaks
Use DoctrineMigrationBundle
   app/console doctrine:migrations:diff
   app/console doctrine:migrations:migrate
   Do not use entities in migration scripts ever!
Write fixtures as migrations or make the fixtures able to
update existing data gracefully
   app/console doctrine:data:load --fixtures=app/fixtures
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
   Consider caching user specific content in the client
 Varnish Reverse Proxy
   Super fast, PHP cannot match its performance
   Cache full pages for anonymous users
   Not just for HTML, also useful for JSON/XML API's
Page Rendered Behind a Reverse Proxy
Asset Management

Go see Kris Wallsmith's talk next!
Performance Tips

Dump routes to Apache rewrite rules
   app/console router:dump-apache
Write custom cache warmers
Do not explicitly inject optional services to controllers
   If your controller receives many services, which are
   optional or unused by some actions, that's probably a
   hint that you should break it up into multiple controllers
Do minimal work in the controller, let templates pull
additional data as needed
Use a bytecode cache with MapFileClassLoader
Testing
Symfony2 rocks for unit and functional testing
   Dependency Injection, core classes have interfaces (easy mocking)
   No base classes, no static dependencies, no ActiveRecord
   Client fakes "real" requests for functional testing (BrowserKit
   component)
Functional Testing
   Pros: tests configuration, tests API not implementation
Unit Testing
   Pros: pinpoints issues, very directed testing
   http://www.slideshare.net/avalanche123/clean-code-5609451
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
   Watch Lukas' unconference talk later today!

Fabric (used at OpenSky)
   Repository managed with git-flow
   Clone tagged release branch, init submodules
   Fix permissions (e.g. cache, log), delete dev/test controllers
   Replace password/API-key placeholders with prod values in config
   files
   Upload in parallel to production nodes, swap "current" symlink
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
       ViewBundle
   OpenSky (http://github.com/opensky)
       LdapBundle
   Sonata (http://github.com/sonata-project)
       AdminBundle

Additionally, a couple 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 symfony/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 or merge 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 Symfony2 repository on github:
http://docs.symfony-reloaded.org/master/
Application Using Dependency Injection
Circular Dependency Example
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

More Related Content

What's hot

React, Redux and es6/7
React, Redux and es6/7React, Redux and es6/7
React, Redux and es6/7Dongho Cho
 
Hooks and Events in Drupal 8
Hooks and Events in Drupal 8Hooks and Events in Drupal 8
Hooks and Events in Drupal 8Nida Ismail Shah
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
Node.js in action
Node.js in actionNode.js in action
Node.js in actionSimon Su
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8Alexei Gorobets
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesCiaranMcNulty
 
Opencast Admin UI - Introduction to developing using AngularJS
Opencast Admin UI - Introduction to developing using AngularJSOpencast Admin UI - Introduction to developing using AngularJS
Opencast Admin UI - Introduction to developing using AngularJSbuttyx
 
td_mxc_rubyrails_shin
td_mxc_rubyrails_shintd_mxc_rubyrails_shin
td_mxc_rubyrails_shintutorialsruby
 
JavaScript
JavaScriptJavaScript
JavaScriptSunil OS
 
Backbone js
Backbone jsBackbone js
Backbone jsrstankov
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - TryoutMatthias Noback
 
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...탑크리에듀(구로디지털단지역3번출구 2분거리)
 
How to Design a Great API (using flask) [ploneconf2017]
How to Design a Great API (using flask) [ploneconf2017]How to Design a Great API (using flask) [ploneconf2017]
How to Design a Great API (using flask) [ploneconf2017]Devon Bernard
 
Events: The Object Oriented Hook System.
Events: The Object Oriented Hook System.Events: The Object Oriented Hook System.
Events: The Object Oriented Hook System.Nida Ismail Shah
 
Behavioral pattern 4
Behavioral pattern 4Behavioral pattern 4
Behavioral pattern 4Naga Muruga
 
Demystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback CommandsDemystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback CommandsMichael Miles
 
Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]Devon Bernard
 

What's hot (19)

React, Redux and es6/7
React, Redux and es6/7React, Redux and es6/7
React, Redux and es6/7
 
Hooks and Events in Drupal 8
Hooks and Events in Drupal 8Hooks and Events in Drupal 8
Hooks and Events in Drupal 8
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Alfredo-PUMEX
Alfredo-PUMEXAlfredo-PUMEX
Alfredo-PUMEX
 
Node.js in action
Node.js in actionNode.js in action
Node.js in action
 
RicoLiveGrid
RicoLiveGridRicoLiveGrid
RicoLiveGrid
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
 
Building a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing StrategiesBuilding a Pyramid: Symfony Testing Strategies
Building a Pyramid: Symfony Testing Strategies
 
Opencast Admin UI - Introduction to developing using AngularJS
Opencast Admin UI - Introduction to developing using AngularJSOpencast Admin UI - Introduction to developing using AngularJS
Opencast Admin UI - Introduction to developing using AngularJS
 
td_mxc_rubyrails_shin
td_mxc_rubyrails_shintd_mxc_rubyrails_shin
td_mxc_rubyrails_shin
 
JavaScript
JavaScriptJavaScript
JavaScript
 
Backbone js
Backbone jsBackbone js
Backbone js
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - Tryout
 
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
#31.스프링프레임워크 & 마이바티스 (Spring Framework, MyBatis)_스프링프레임워크 강좌, 재직자환급교육,실업자국비지원...
 
How to Design a Great API (using flask) [ploneconf2017]
How to Design a Great API (using flask) [ploneconf2017]How to Design a Great API (using flask) [ploneconf2017]
How to Design a Great API (using flask) [ploneconf2017]
 
Events: The Object Oriented Hook System.
Events: The Object Oriented Hook System.Events: The Object Oriented Hook System.
Events: The Object Oriented Hook System.
 
Behavioral pattern 4
Behavioral pattern 4Behavioral pattern 4
Behavioral pattern 4
 
Demystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback CommandsDemystifying Drupal AJAX Callback Commands
Demystifying Drupal AJAX Callback Commands
 
Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]
 

Viewers also liked

Practical PHP 5.3
Practical PHP 5.3Practical PHP 5.3
Practical PHP 5.3Nate Abele
 
The Contextual Experience of the Mobile Web
The Contextual Experience of the Mobile WebThe Contextual Experience of the Mobile Web
The Contextual Experience of the Mobile WebJeff Carouth
 
Security audits as integral part of php application development (version 2012...
Security audits as integral part of php application development (version 2012...Security audits as integral part of php application development (version 2012...
Security audits as integral part of php application development (version 2012...Sijmen Ruwhof
 
PHP Days 2011 - Keynote: Microsoft WebMatrix
PHP Days 2011 - Keynote: Microsoft WebMatrixPHP Days 2011 - Keynote: Microsoft WebMatrix
PHP Days 2011 - Keynote: Microsoft WebMatrixpietrobr
 
Von Dinosauriern, Bienen und Wespen
Von Dinosauriern, Bienen und WespenVon Dinosauriern, Bienen und Wespen
Von Dinosauriern, Bienen und WespenTomas Caspers
 

Viewers also liked (6)

Practical PHP 5.3
Practical PHP 5.3Practical PHP 5.3
Practical PHP 5.3
 
The Contextual Experience of the Mobile Web
The Contextual Experience of the Mobile WebThe Contextual Experience of the Mobile Web
The Contextual Experience of the Mobile Web
 
Security audits as integral part of php application development (version 2012...
Security audits as integral part of php application development (version 2012...Security audits as integral part of php application development (version 2012...
Security audits as integral part of php application development (version 2012...
 
Html5 by gis tec
Html5 by gis tecHtml5 by gis tec
Html5 by gis tec
 
PHP Days 2011 - Keynote: Microsoft WebMatrix
PHP Days 2011 - Keynote: Microsoft WebMatrixPHP Days 2011 - Keynote: Microsoft WebMatrix
PHP Days 2011 - Keynote: Microsoft WebMatrix
 
Von Dinosauriern, Bienen und Wespen
Von Dinosauriern, Bienen und WespenVon Dinosauriern, Bienen und Wespen
Von Dinosauriern, Bienen und Wespen
 

Similar to Symfony2 - from the trenches

Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
Zend Framework 2 - Basic Components
Zend Framework 2  - Basic ComponentsZend Framework 2  - Basic Components
Zend Framework 2 - Basic ComponentsMateusz Tymek
 
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
 
Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 3camp
 
Web internship Yii Framework
Web internship  Yii FrameworkWeb internship  Yii Framework
Web internship Yii FrameworkNoveo
 
Web applications with Catalyst
Web applications with CatalystWeb applications with Catalyst
Web applications with Catalystsvilen.ivanov
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJSWei Ru
 
Phpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsPhpne august-2012-symfony-components-friends
Phpne august-2012-symfony-components-friendsMichael Peacock
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS ArchitectureEyal Vardi
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS InternalEyal Vardi
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rulesSrijan Technologies
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentNuvole
 
CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)brian d foy
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207patter
 

Similar to Symfony2 - from the trenches (20)

Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Dependency Injection
Dependency InjectionDependency Injection
Dependency Injection
 
Zend Framework 2 - Basic Components
Zend Framework 2  - Basic ComponentsZend Framework 2  - Basic Components
Zend Framework 2 - Basic Components
 
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
 
Yii Introduction
Yii IntroductionYii Introduction
Yii Introduction
 
Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2
 
Web internship Yii Framework
Web internship  Yii FrameworkWeb internship  Yii Framework
Web internship Yii Framework
 
Introduction to angular js
Introduction to angular jsIntroduction to angular js
Introduction to angular js
 
Web applications with Catalyst
Web applications with CatalystWeb applications with Catalyst
Web applications with Catalyst
 
Practical AngularJS
Practical AngularJSPractical AngularJS
Practical AngularJS
 
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
 
AngularJS Architecture
AngularJS ArchitectureAngularJS Architecture
AngularJS Architecture
 
AngularJS Internal
AngularJS InternalAngularJS Internal
AngularJS Internal
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
 
First Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven DevelopmentFirst Steps in Drupal Code Driven Development
First Steps in Drupal Code Driven Development
 
Symfony2 revealed
Symfony2 revealedSymfony2 revealed
Symfony2 revealed
 
CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)CGI::Prototype (NPW 2006)
CGI::Prototype (NPW 2006)
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
 

Recently uploaded

Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsYoss Cohen
 
Dublin_mulesoft_meetup_API_specifications.pptx
Dublin_mulesoft_meetup_API_specifications.pptxDublin_mulesoft_meetup_API_specifications.pptx
Dublin_mulesoft_meetup_API_specifications.pptxKunal Gupta
 
Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024
Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024
Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024BookNet Canada
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Deliver Latency Free Customer Experience
Deliver Latency Free Customer ExperienceDeliver Latency Free Customer Experience
Deliver Latency Free Customer ExperienceOpsTree solutions
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observabilityitnewsafrica
 
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
 
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
 
Transcript: Green paths: Learning from publishers’ sustainability journeys - ...
Transcript: Green paths: Learning from publishers’ sustainability journeys - ...Transcript: Green paths: Learning from publishers’ sustainability journeys - ...
Transcript: Green paths: Learning from publishers’ sustainability journeys - ...BookNet Canada
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Mark Simos
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkPixlogix Infotech
 
Introduction-to-Wazuh-and-its-integration.pptx
Introduction-to-Wazuh-and-its-integration.pptxIntroduction-to-Wazuh-and-its-integration.pptx
Introduction-to-Wazuh-and-its-integration.pptxmprakaash5
 
Landscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfLandscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfAarwolf Industries LLC
 
Accelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessAccelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessWSO2
 
Transport in Open Pits______SM_MI10415MI
Transport in Open Pits______SM_MI10415MITransport in Open Pits______SM_MI10415MI
Transport in Open Pits______SM_MI10415MIRomil Mishra
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesKari Kakkonen
 
Automation Ops Series: Session 3 - Solutions management
Automation Ops Series: Session 3 - Solutions managementAutomation Ops Series: Session 3 - Solutions management
Automation Ops Series: Session 3 - Solutions managementDianaGray10
 

Recently uploaded (20)

Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platforms
 
Dublin_mulesoft_meetup_API_specifications.pptx
Dublin_mulesoft_meetup_API_specifications.pptxDublin_mulesoft_meetup_API_specifications.pptx
Dublin_mulesoft_meetup_API_specifications.pptx
 
Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024
Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024
Green paths: Learning from publishers’ sustainability journeys - Tech Forum 2024
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Deliver Latency Free Customer Experience
Deliver Latency Free Customer ExperienceDeliver Latency Free Customer Experience
Deliver Latency Free Customer Experience
 
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security ObservabilityGlenn Lazarus- Why Your Observability Strategy Needs Security Observability
Glenn Lazarus- Why Your Observability Strategy Needs Security Observability
 
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
 
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
 
Transcript: Green paths: Learning from publishers’ sustainability journeys - ...
Transcript: Green paths: Learning from publishers’ sustainability journeys - ...Transcript: Green paths: Learning from publishers’ sustainability journeys - ...
Transcript: Green paths: Learning from publishers’ sustainability journeys - ...
 
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
Tampa BSides - The No BS SOC (slides from April 6, 2024 talk)
 
React Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App FrameworkReact Native vs Ionic - The Best Mobile App Framework
React Native vs Ionic - The Best Mobile App Framework
 
Introduction-to-Wazuh-and-its-integration.pptx
Introduction-to-Wazuh-and-its-integration.pptxIntroduction-to-Wazuh-and-its-integration.pptx
Introduction-to-Wazuh-and-its-integration.pptx
 
Landscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfLandscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdf
 
Accelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with PlatformlessAccelerating Enterprise Software Engineering with Platformless
Accelerating Enterprise Software Engineering with Platformless
 
Transport in Open Pits______SM_MI10415MI
Transport in Open Pits______SM_MI10415MITransport in Open Pits______SM_MI10415MI
Transport in Open Pits______SM_MI10415MI
 
Testing tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examplesTesting tools and AI - ideas what to try with some tool examples
Testing tools and AI - ideas what to try with some tool examples
 
Automation Ops Series: Session 3 - Solutions management
Automation Ops Series: Session 3 - Solutions managementAutomation Ops Series: Session 3 - Solutions management
Automation Ops Series: Session 3 - Solutions management
 

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 setup PHP 5.3+ with ext/intl (compat lib is in the works) 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. <?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
  • 7. <?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
  • 8. Service Container (aka DIC) 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
  • 9. <?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
  • 10. <?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
  • 11. <?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
  • 12. <?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
  • 13. 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 in YAML/PHP YAML merge key syntax to reuse pieces within a file XSD-aware editors provide auto-completion/validation XML is recommended for Bundle/DI configuration YAML is recommended for application configuration Bundle extensions can optionally utilize the Config component to normalize/parse configurations in any format See FrameworkExtension, SecurityExtension, TwigExtension
  • 14. 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, such as generateUrl(), redirect(), render()
  • 15. Application Choices Security system makes it possible to have just one application for both frontend and admin backend Location of AppKernel 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
  • 16. Doctrine Examples Retrieve references to entity/document without DB queries Using raw SQL queries with Doctrine2 ORM Simple search engine with Doctrine MongoDB ODM
  • 17. Retrieving References w/o DB Queries $tags = array('baseball', 'basketball'); foreach ($tags as $tag) { $product->addTag($em->getReference('Tag', $tag)); }
  • 18. 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
  • 19. Simple Search Engine interface HasKeywords { function setKeywords(); function getKeywords(); }
  • 20. Simple Search Engine /** @mongodb:EmbeddedDocument */ class Keyword { // ... /** @mongodb:String @mongodb:Index */ private $keyword; /** @mongodb:Integer */ private $score; // ... }
  • 21. Simple Search Engine /** @mongodb:Document */ class Product implements HasKeywords { /** @mongodb:Id */ private $id; /** @mongodb:String */ private $title; /** @mongodb:EmbedMany(targetDocument="Keyword") */ private $keywords = array(); // ... }
  • 22. 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; } }
  • 23. Simple Search Engine // find products by keyword $products = $dm->createQueryBuilder() ->field('keywords.keyword')->all($keywords) ->getQuery() ->execute();
  • 24. Doctrine in the Real World Go see Jon Wage's talk at later today!
  • 25. Database Migrations Deploy DB schema changes before the code Prevent DB schema BC breaks Use DoctrineMigrationBundle app/console doctrine:migrations:diff app/console doctrine:migrations:migrate Do not use entities in migration scripts ever! Write fixtures as migrations or make the fixtures able to update existing data gracefully app/console doctrine:data:load --fixtures=app/fixtures
  • 27. 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 Consider caching user specific content in the client Varnish Reverse Proxy Super fast, PHP cannot match its performance Cache full pages for anonymous users Not just for HTML, also useful for JSON/XML API's
  • 28. Page Rendered Behind a Reverse Proxy
  • 29. Asset Management Go see Kris Wallsmith's talk next!
  • 30. Performance Tips Dump routes to Apache rewrite rules app/console router:dump-apache Write custom cache warmers Do not explicitly inject optional services to controllers If your controller receives many services, which are optional or unused by some actions, that's probably a hint that you should break it up into multiple controllers Do minimal work in the controller, let templates pull additional data as needed Use a bytecode cache with MapFileClassLoader
  • 31. Testing Symfony2 rocks for unit and functional testing Dependency Injection, core classes have interfaces (easy mocking) No base classes, no static dependencies, no ActiveRecord Client fakes "real" requests for functional testing (BrowserKit component) Functional Testing Pros: tests configuration, tests API not implementation Unit Testing Pros: pinpoints issues, very directed testing http://www.slideshare.net/avalanche123/clean-code-5609451 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
  • 32. 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 Watch Lukas' unconference talk later today! Fabric (used at OpenSky) Repository managed with git-flow Clone tagged release branch, init submodules Fix permissions (e.g. cache, log), delete dev/test controllers Replace password/API-key placeholders with prod values in config files Upload in parallel to production nodes, swap "current" symlink
  • 33. 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
  • 34. 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 ViewBundle OpenSky (http://github.com/opensky) LdapBundle Sonata (http://github.com/sonata-project) AdminBundle Additionally, a couple sites currently index community bundles: http://symfony2bundles.org/ http://symfohub.com/
  • 35. 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 symfony/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
  • 36. 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
  • 37. 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 or merge upstream's master when finished
  • 38. 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
  • 39. 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 Symfony2 repository on github: http://docs.symfony-reloaded.org/master/
  • 40.
  • 43. 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