SlideShare a Scribd company logo
1 of 42
Download to read offline
UK Symfony Meetup
             November, 2012




                                           Symfony
                                           War Stories

                                                          Jakub Zalas
                                                         SensioLabsUK
http://www.rgbstock.com/bigphoto/mhY2DCY
Jakub Zalas a.k.a. Kuba


○ Remembers symfony 1.0
  (2007)
○ Open Source contributor
○ BDD advocate
○ Works at Sensio Labs UK
○ ZCE & Sensio Labs         ○ Twitter: @jakub_zalas
  Certified Symfony         ○ Blog: http://zalas.eu
  Developer                 ○ Github: @jakzal
Symfony War Stories
● Bundling the code
● Thinking outside of the bundle
● Being lazy
● Learning your stuff
● Keeping your playground clean
● Building the quality in
Bundling
                                           the code
http://www.rgbstock.com/bigphoto/mfXkYUq
VS
Whenever in doubt...
● Start simple and let the design emerge
● Extract bundles when you need to reuse it
  or you see it would improve clarity
● Avoid two-way dependencies between
  bundles
Thinking
                                            outside of
                                           the bundle




http://www.rgbstock.com/bigphoto/mfBYR2S
VS
To keep your design clean...
● Treat bundles as an integration layer
  between PHP libraries and the Symfony
  framework
● In your libraries, avoid dependencies on
  bundles
Being lazy




http://www.sxc.hu/photo/858871
There's a bundle for that!
Learning
                                  your stuff




http://www.sxc.hu/photo/1095604
Have you ever used?

● Event listeners and subscribers
● Form data transformers
● Twig extensions
● Profiler extensions
● DIC compiler passes
● more...
It's easy!




             let's see few examples...
Event listeners and subscribers (Doctrine)


 services:
    sensio.listener.search_indexer:
        class: SensioListenerSearchIndexer
        tags:
            -
                name: doctrine.event_listener
                event: postPersist
namespace SensioListener;

use DoctrineORMEventLifecycleEventArgs;
use SensioEntityProduct;

class SearchIndexer
{
    public function postPersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();
        $entityManager = $args->getEntityManager();

        if ($entity instanceof Product) { /* Index me */ }
    }
}
Lifecycle callbacks (Doctrine)

/**
  * @ORMEntity()
  * @ORMHasLifecycleCallbacks()
  */
class User
{
     /**
      * @ORMPrePersist
      */
     public function updateCreatedAt() { /* ... */ }
}
Event listeners and subscribers (Symfony)


services:
  sensio.action_listener:
    class: SensioMyBundleEventListenerMyListener
    tags:
      -
        name: kernel.event_listener
        event: kernel.controller
        method: onKernelController
namespace SensioMyBundleEventListener;

class MyListener
{
    public function onKernelController(
                             FilterControllerEvent $event)
    {
        $controller = $event->getController();
        $request = $event->getRequest();

        // ...
    }
}
Event listeners and subscribers (Forms)

$callback = function(FormEvent $event) {
    if (null === $event->getData()) {
        $formData = $event->getForm()->getData();
        $event->setData($formData);
    }
};

$builder->add('email', 'text');
$builder->get('email')
    ->addEventListener(
        FormEvents::PRE_BIND, $callback
    );
Data transformers (Forms)
class IssueToNumberTransformer
                 implements DataTransformerInterface
{
    public function transform($issue)
    {
        // return issue number
    }

    public function reverseTransform($number)
    {
        // return Issue instance
    }
}
$field = $builder->create('issue', 'text')
    ->addModelTransformer(new IssueToNumberTransformer());

$builder->add($field);
Twig extensions

<!-- Instead of: -->

<div class="price">
    ${{ 9800.333|number_format(2, '.', ',') }}
</div>

<!-- just do: -->

<div class="price">
    {{ 9800.333|price }}
</div>
class SensioExtension extends Twig_Extension
{
    public function getFilters()
    {
        return array(
            'price' => new Twig_Filter_Method(
                                     $this, 'priceFilter')
        );
    }

    public function getName()
    {
        return 'sensio_extension';
    }

    public function priceFilter($number, /* ... */ ) {}
}
public function priceFilter(
    $number, $decimals = 0, $decPoint = '.', $sep = ',')
{
    $price = number_format(
        $number, $decimals, $decPoint, $sep
    );

    return '$'.$price;
}
services:
    sensio.twig.acme_extension:
        class: SensioTwigSensioExtension
        tags:
            - { name: twig.extension }
Web profiler
Debugging commands



./app/console container:debug
./app/console container:debug twig.loader

./app/console router:debug
./app/console router:debug homepage

./app/console router:match /logout
Debugging commands
http://www.rgbstock.com/bigphoto/mZTKnw6




Keeping your playground clean
Use the service container!
public function publishAction($date)
{
    $show = $this->findShow($date);
    $fileName = sprintf('show-%s.json', $date->format('Y-m-d'));

    while (file_exists($fileName)) {
        $fileName = $fileName.preg_replace('/.json$/', '-1.json');
    }

    $options = array( /* options here */ );
    $s3 = new AmazonS3($options);

    $objectOptions = array(
        'body' => json_encode($show), 'acl' => $options['objectAcl']);

    if (!$s3->create_object('my-bucket', $fileName, $objectOptions) {
        throw new Exception('Could not save file');
    }

    // ...
}
public function publishAction($date)
{
    $show = $this->findShow($date);

    $fileNameResolver = new FileNameResolver();
    $filesystem = $this->get('gafrette_filesystem');

    $publisher = new Publisher(
        $fileNameResolver, $filesystem
    );

    $publisher->publish($show, $date);
}
Use the service container!



public function publishAction($date)
{
    $show = $this->findShow($date);
    $publisher = $this->get('sensio.publisher');
    $publisher->publish($show, $date);
}
Be SOLID!
/**
  * @ORMEntity()
  */
class Product
{
     // ...

    public function createOrderReport($month)
    {
        // $this->em->getRepository() ...
    }

    public function setEntityManager($em)
    {
        $this->em = $em;
    }
}
class OrderReportGenerator
{
    private $em = null;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function generate(Product $product, $month)
    {
        // ...
    }
}
Building quality in




http://www.rgbstock.com/photo/nrcyovQ/perfect
Unit tests

class ReportTest extends PHPUnit_Framework_TestCase
{
    public function testThatItReturnsFilePath()
    {
        $report = new Report();

        $file = $report->create('January');

        $this->assertSame('/january.csv', $file);
    }
}
... or specs


namespace spec;

class Report extends PHPSpec2ObjectBehavior
{
    function it_returns_file_path()
    {
        $this->create('January')
             ->shouldReturn('/january.csv');
    }
}
Managing expectations
Feature: Viewing recent news on the homepage
  As a Marketing Manager
  I want Visitors to see recent news on the homepage
  In order to get them interested in the content

 Scenario: Viewing recent news
   Given there are 10 news items
     And there were 5 news items written since yesterday
    When I visit the homepage
    Then I should see 5 recent news items in the news section

 Scenario: There is not enough news
   Given there are 10 news items
     But there were 3 news items written since yesterday
    When I visit the homepage
    Then I should see 3 recent news items in the news section
Thank you!

More Related Content

What's hot

Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mockingKonstantin Kudryashov
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & RESTHugo Hamon
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of LithiumNate Abele
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Kris Wallsmith
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of LithiumNate Abele
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201Fabien Potencier
 
Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Fabien Potencier
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteLeonardo Proietti
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkG Woo
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixturesBill Chang
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP GeneratorsMark Baker
 
Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)Fabien Potencier
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium AppsNate Abele
 
Dealing with Continuous Data Processing, ConFoo 2012
Dealing with Continuous Data Processing, ConFoo 2012Dealing with Continuous Data Processing, ConFoo 2012
Dealing with Continuous Data Processing, ConFoo 2012Michael Peacock
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Leonardo Proietti
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patternsSamuel ROZE
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionNate Abele
 

What's hot (20)

Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
Silex meets SOAP & REST
Silex meets SOAP & RESTSilex meets SOAP & REST
Silex meets SOAP & REST
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 
Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)Introducing Assetic (NYPHP)
Introducing Assetic (NYPHP)
 
The Origin of Lithium
The Origin of LithiumThe Origin of Lithium
The Origin of Lithium
 
Dependency Injection IPC 201
Dependency Injection IPC 201Dependency Injection IPC 201
Dependency Injection IPC 201
 
Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)Beyond symfony 1.2 (Symfony Camp 2008)
Beyond symfony 1.2 (Symfony Camp 2008)
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
PHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php frameworkPHP 5.3 and Lithium: the most rad php framework
PHP 5.3 and Lithium: the most rad php framework
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
 
Electrify your code with PHP Generators
Electrify your code with PHP GeneratorsElectrify your code with PHP Generators
Electrify your code with PHP Generators
 
Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)Symfony 2 (PHP Quebec 2009)
Symfony 2 (PHP Quebec 2009)
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Building Lithium Apps
Building Lithium AppsBuilding Lithium Apps
Building Lithium Apps
 
Dealing with Continuous Data Processing, ConFoo 2012
Dealing with Continuous Data Processing, ConFoo 2012Dealing with Continuous Data Processing, ConFoo 2012
Dealing with Continuous Data Processing, ConFoo 2012
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 
How I started to love design patterns
How I started to love design patternsHow I started to love design patterns
How I started to love design patterns
 
Nubilus Perl
Nubilus PerlNubilus Perl
Nubilus Perl
 
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo EditionLithium: The Framework for People Who Hate Frameworks, Tokyo Edition
Lithium: The Framework for People Who Hate Frameworks, Tokyo Edition
 

Similar to Symfony War Stories

How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmersAlexander Varwijk
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8Alexei Gorobets
 
Symfony tips and tricks
Symfony tips and tricksSymfony tips and tricks
Symfony tips and tricksJavier Eguiluz
 
Writing JavaScript that doesn't suck
Writing JavaScript that doesn't suckWriting JavaScript that doesn't suck
Writing JavaScript that doesn't suckRoss Bruniges
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016Kacper Gunia
 
Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...go_oh
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014Matthias Noback
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksNate Abele
 
Symfony Under the Hood
Symfony Under the HoodSymfony Under the Hood
Symfony Under the HoodeZ Systems
 
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
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - TryoutMatthias Noback
 
The Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaThe Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaMatthias Noback
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumMatthias Noback
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to DjangoJames Casey
 
Symfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusSymfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusIgnacio Martín
 
TypeScript for Java Developers
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java DevelopersYakov Fain
 

Similar to Symfony War Stories (20)

How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Multilingualism makes better programmers
Multilingualism makes better programmersMultilingualism makes better programmers
Multilingualism makes better programmers
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
 
Symfony tips and tricks
Symfony tips and tricksSymfony tips and tricks
Symfony tips and tricks
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
Writing JavaScript that doesn't suck
Writing JavaScript that doesn't suckWriting JavaScript that doesn't suck
Writing JavaScript that doesn't suck
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016
 
Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...
 
The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014The Naked Bundle - Symfony Live London 2014
The Naked Bundle - Symfony Live London 2014
 
Lithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate FrameworksLithium: The Framework for People Who Hate Frameworks
Lithium: The Framework for People Who Hate Frameworks
 
Symfony Under the Hood
Symfony Under the HoodSymfony Under the Hood
Symfony Under the Hood
 
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
 
The Naked Bundle - Tryout
The Naked Bundle - TryoutThe Naked Bundle - Tryout
The Naked Bundle - Tryout
 
The Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony BarcelonaThe Naked Bundle - Symfony Barcelona
The Naked Bundle - Symfony Barcelona
 
Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
The Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup BelgiumThe Naked Bundle - Symfony Usergroup Belgium
The Naked Bundle - Symfony Usergroup Belgium
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
Symfony 4 Workshop - Limenius
Symfony 4 Workshop - LimeniusSymfony 4 Workshop - Limenius
Symfony 4 Workshop - Limenius
 
TypeScript for Java Developers
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java Developers
 

Recently uploaded

Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesZilliz
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 

Recently uploaded (20)

Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Vector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector DatabasesVector Databases 101 - An introduction to the world of Vector Databases
Vector Databases 101 - An introduction to the world of Vector Databases
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 

Symfony War Stories

  • 1. UK Symfony Meetup November, 2012 Symfony War Stories Jakub Zalas SensioLabsUK http://www.rgbstock.com/bigphoto/mhY2DCY
  • 2. Jakub Zalas a.k.a. Kuba ○ Remembers symfony 1.0 (2007) ○ Open Source contributor ○ BDD advocate ○ Works at Sensio Labs UK ○ ZCE & Sensio Labs ○ Twitter: @jakub_zalas Certified Symfony ○ Blog: http://zalas.eu Developer ○ Github: @jakzal
  • 3. Symfony War Stories ● Bundling the code ● Thinking outside of the bundle ● Being lazy ● Learning your stuff ● Keeping your playground clean ● Building the quality in
  • 4. Bundling the code http://www.rgbstock.com/bigphoto/mfXkYUq
  • 5. VS
  • 6. Whenever in doubt... ● Start simple and let the design emerge ● Extract bundles when you need to reuse it or you see it would improve clarity ● Avoid two-way dependencies between bundles
  • 7. Thinking outside of the bundle http://www.rgbstock.com/bigphoto/mfBYR2S
  • 8. VS
  • 9. To keep your design clean... ● Treat bundles as an integration layer between PHP libraries and the Symfony framework ● In your libraries, avoid dependencies on bundles
  • 11. There's a bundle for that!
  • 12. Learning your stuff http://www.sxc.hu/photo/1095604
  • 13. Have you ever used? ● Event listeners and subscribers ● Form data transformers ● Twig extensions ● Profiler extensions ● DIC compiler passes ● more...
  • 14. It's easy! let's see few examples...
  • 15. Event listeners and subscribers (Doctrine) services: sensio.listener.search_indexer: class: SensioListenerSearchIndexer tags: - name: doctrine.event_listener event: postPersist
  • 16. namespace SensioListener; use DoctrineORMEventLifecycleEventArgs; use SensioEntityProduct; class SearchIndexer { public function postPersist(LifecycleEventArgs $args) { $entity = $args->getEntity(); $entityManager = $args->getEntityManager(); if ($entity instanceof Product) { /* Index me */ } } }
  • 17. Lifecycle callbacks (Doctrine) /** * @ORMEntity() * @ORMHasLifecycleCallbacks() */ class User { /** * @ORMPrePersist */ public function updateCreatedAt() { /* ... */ } }
  • 18. Event listeners and subscribers (Symfony) services: sensio.action_listener: class: SensioMyBundleEventListenerMyListener tags: - name: kernel.event_listener event: kernel.controller method: onKernelController
  • 19. namespace SensioMyBundleEventListener; class MyListener { public function onKernelController( FilterControllerEvent $event) { $controller = $event->getController(); $request = $event->getRequest(); // ... } }
  • 20. Event listeners and subscribers (Forms) $callback = function(FormEvent $event) { if (null === $event->getData()) { $formData = $event->getForm()->getData(); $event->setData($formData); } }; $builder->add('email', 'text'); $builder->get('email') ->addEventListener( FormEvents::PRE_BIND, $callback );
  • 21. Data transformers (Forms) class IssueToNumberTransformer implements DataTransformerInterface { public function transform($issue) { // return issue number } public function reverseTransform($number) { // return Issue instance } }
  • 22. $field = $builder->create('issue', 'text') ->addModelTransformer(new IssueToNumberTransformer()); $builder->add($field);
  • 23. Twig extensions <!-- Instead of: --> <div class="price"> ${{ 9800.333|number_format(2, '.', ',') }} </div> <!-- just do: --> <div class="price"> {{ 9800.333|price }} </div>
  • 24. class SensioExtension extends Twig_Extension { public function getFilters() { return array( 'price' => new Twig_Filter_Method( $this, 'priceFilter') ); } public function getName() { return 'sensio_extension'; } public function priceFilter($number, /* ... */ ) {} }
  • 25. public function priceFilter( $number, $decimals = 0, $decPoint = '.', $sep = ',') { $price = number_format( $number, $decimals, $decPoint, $sep ); return '$'.$price; }
  • 26. services: sensio.twig.acme_extension: class: SensioTwigSensioExtension tags: - { name: twig.extension }
  • 28. Debugging commands ./app/console container:debug ./app/console container:debug twig.loader ./app/console router:debug ./app/console router:debug homepage ./app/console router:match /logout
  • 31. Use the service container!
  • 32. public function publishAction($date) { $show = $this->findShow($date); $fileName = sprintf('show-%s.json', $date->format('Y-m-d')); while (file_exists($fileName)) { $fileName = $fileName.preg_replace('/.json$/', '-1.json'); } $options = array( /* options here */ ); $s3 = new AmazonS3($options); $objectOptions = array( 'body' => json_encode($show), 'acl' => $options['objectAcl']); if (!$s3->create_object('my-bucket', $fileName, $objectOptions) { throw new Exception('Could not save file'); } // ... }
  • 33. public function publishAction($date) { $show = $this->findShow($date); $fileNameResolver = new FileNameResolver(); $filesystem = $this->get('gafrette_filesystem'); $publisher = new Publisher( $fileNameResolver, $filesystem ); $publisher->publish($show, $date); }
  • 34. Use the service container! public function publishAction($date) { $show = $this->findShow($date); $publisher = $this->get('sensio.publisher'); $publisher->publish($show, $date); }
  • 36. /** * @ORMEntity() */ class Product { // ... public function createOrderReport($month) { // $this->em->getRepository() ... } public function setEntityManager($em) { $this->em = $em; } }
  • 37. class OrderReportGenerator { private $em = null; public function __construct(EntityManager $em) { $this->em = $em; } public function generate(Product $product, $month) { // ... } }
  • 39. Unit tests class ReportTest extends PHPUnit_Framework_TestCase { public function testThatItReturnsFilePath() { $report = new Report(); $file = $report->create('January'); $this->assertSame('/january.csv', $file); } }
  • 40. ... or specs namespace spec; class Report extends PHPSpec2ObjectBehavior { function it_returns_file_path() { $this->create('January') ->shouldReturn('/january.csv'); } }
  • 41. Managing expectations Feature: Viewing recent news on the homepage As a Marketing Manager I want Visitors to see recent news on the homepage In order to get them interested in the content Scenario: Viewing recent news Given there are 10 news items And there were 5 news items written since yesterday When I visit the homepage Then I should see 5 recent news items in the news section Scenario: There is not enough news Given there are 10 news items But there were 3 news items written since yesterday When I visit the homepage Then I should see 3 recent news items in the news section