Symfony2 components to the rescue of your PHP projects

91
Xavier Lacot – June 2012 Symfony2 components to the rescue of your PHP projects

description

Symfony2 components can be of a great help when trying to improve the level of existing PHP projects. This presentation explains how PHP and its ecosystem evolved during the last 10 years, and focuses on the successive use of several Symfony2 components, to show how useful they are for the PHP developer. The presentation gives some migration strategies, and explains component by component the migration plan and the (possible) implications on the historical code.

Transcript of Symfony2 components to the rescue of your PHP projects

Page 1: Symfony2 components to the rescue of your PHP projects

Xavier Lacot – June 2012

Symfony2 components to the rescue of your PHP projects

Page 2: Symfony2 components to the rescue of your PHP projects

2Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Hello

My name is Xavier Lacot

■ Web and Mobile at http://jolicode.com

■ Formerly PHP technical leader at Clever Age

■ Open Source convinced and contributor

■ In PHP, mainly Symfony

■ In javascript, etc.

■ Président of AFUP – the French PHP Users Association (afup.org)

■ Forum PHP

■ PHP Tour

■ http://twitter.com/xavierlacot

Page 3: Symfony2 components to the rescue of your PHP projects

3Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Summary

1. PHP in 2012, a living ecosystem

2. 2005's PHP is now just pain

3. Migration strategies

■ The slow path

■ Switch progressively

4. Symfony components for your pleasure

■ Your prefered migration toolkit

■ Case Study

Page 4: Symfony2 components to the rescue of your PHP projects

4Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Before we start

How many of you use a framework on a regular basis?

How many of you must deal with no-framework applications?

Page 5: Symfony2 components to the rescue of your PHP projects

PHP in 2012, a living ecosystem

Page 6: Symfony2 components to the rescue of your PHP projects

6Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

A few things about PHP

■ A pragmatic language built for the Web

■ PHP5 since 2005

■ One of the most used languages on the Web

PHP – solves problems since 1995

Page 7: Symfony2 components to the rescue of your PHP projects

7Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

The language improves

■ PHP 5.3 introduced new concepts :

■ Usage of namespaces

■ Lambda and closures

■ Phar archives

■ “goto” WTF ???

namespace JoliCode\Conferences;use General\Talk\Session;

class SymfonyLive extends Session{ public function runPresentation() { // do something nice... }}

Page 8: Symfony2 components to the rescue of your PHP projects

8Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Namespaces manipulation

■ Pro

■ No more collisions

■ Less ambiguity

■ Ahah, short class names. No more long classnames

■ Cons

■ Don't forget the use statement

use One\Full\Classname as Something;

$object = new Something;

Page 9: Symfony2 components to the rescue of your PHP projects

9Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

And it still evolves

■ PHP 5.4

■ Some deprecated features removed

■ Performance improvements

■ Instance Method Calls

■ Closures inside objects

■ Traits, aka. assisted copy/paste

■ Arrays manipulation

$post = (new Post)->setTitle('Hello poneys')->save();

function fruits() { return ['apple', 'banana', 'orange'];}

echo fruits()[0]; // Outputs: apple

Page 10: Symfony2 components to the rescue of your PHP projects

10Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

The ecosystem improves

■ Last years = bunch of new things

■ New (versions of) frameworks

■ New tools

■ Dependancies resolution

■ Code analysis

■ Continuous integration

■ Structuration of the projects

■ Standards

■ Discussions

■ More and more conferences

Page 11: Symfony2 components to the rescue of your PHP projects

11Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

New frameworks

Page 12: Symfony2 components to the rescue of your PHP projects

12Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

New frameworks

Page 13: Symfony2 components to the rescue of your PHP projects

13Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

ClassLoader and PSR-0

■ PSR-0 :

■ A standardization agreement

■ Scope: classes naming and organization

■ Idea : match the path of the file containg a class to this full class name

class: Symfony\Component\HttpFoundation\Requestpath: vendor/src/Symfony/Component/HttpFoundation/Request.php

class: Twig_Extension_Corepath: vendor/twig/lib/Twig/Extension/Core.php

Page 14: Symfony2 components to the rescue of your PHP projects

14Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

ClassLoader and PSR-0

class: Symfony\Component\HttpFoundation\Requestpath: vendor/src/Symfony/Component/HttpFoundation/Request.php

class: Twig_Extension_Corepath: vendor/twig/lib/Twig/Extension/Core.php

PEAR naming style

Namespaced classes styleautoloading path prefix

Page 15: Symfony2 components to the rescue of your PHP projects

15Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Composer

■ A packages management tool

■ Launched in 2012

■ Composer : a tool for managing dependancies

■ Packagist.org : a repository of packages

■ See the talk of Jordi Boggiano and Nils Adermann

Page 16: Symfony2 components to the rescue of your PHP projects

16Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Dependancies resolution using Composer

■ And more:

■ Post install commands

■ Configuration variables

■ etc.

{ "name": "joli/demo-project", "description": "A simple demo project", "require": { "php": ">=5.3.3", "symfony/symfony": "2.1.*", "seld/jsonlint": "1.0.0" }}

composer.json

$ php composer.phar installInstalling dependencies from lock file - Updating twig/twig (dev-master)

Page 17: Symfony2 components to the rescue of your PHP projects

17Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Packagist

■ The packages repository behind packagist

■ A great resource for finding high quality contributions

■ Definitively forget about PEAR or distro packages

■ Fear that packagist might break? Build your own repository with satis - https://github.com/composer/satis

Page 18: Symfony2 components to the rescue of your PHP projects

18Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Page 19: Symfony2 components to the rescue of your PHP projects

19Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

PHP gets is a professional language

■ PHP is not anymore an amateur language

■ Continuous integration (hi Jenkins, Sismo and Travis)

■ Unit tests (hi PHPUnit, SimpleTest, Atoum)

■ Code quality analysis and metrics

■ Code improvement tools (Hi PHP-CS-Fixer)

■ etc.

■ PHP developers have grew up since 2002

■ The language is more mature

■ The community too

Page 20: Symfony2 components to the rescue of your PHP projects

20Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Page 21: Symfony2 components to the rescue of your PHP projects

21Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Cheers GitHub

Page 22: Symfony2 components to the rescue of your PHP projects

22Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

GitHub

■ Social coding

■ Gathers many Open Source contributions

■ Watch, fork, comment, request pulls

■ Fun and nice

■ 2,500,000 projects,

~ 150,000 PHP projects

■ A great market for the developer!

PHP switched from SVN to Git

Page 23: Symfony2 components to the rescue of your PHP projects

23Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Page 24: Symfony2 components to the rescue of your PHP projects

24Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Summary

1. PHP in 2012, a living ecosystem

2. 2005's PHP is now just pain

3. Migration strategies

■ The slow path

■ Switch progressively

4. Symfony components for your pleasure

■ Your prefered migration toolkit

■ Case study

Page 25: Symfony2 components to the rescue of your PHP projects

2005's PHP is now just pain

Page 26: Symfony2 components to the rescue of your PHP projects

26Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Oh yes we did it...

<html> <body> <?php include("includes/menu.inc.php"); $file = (isset($_GET['pages'])) ? "pages/".$_GET['page'].".php" : "pages/404.php";

if ( !file_exists($file) ) { @include("pages/404.php"); } else { $allowed = realpath('./pages');

if ( !@ereg($allowed."*", realpath($file)) ) { @include("pages/404.php"); } else { @include($file); } } ?> </body></html>

somewhere in 2002...

Page 27: Symfony2 components to the rescue of your PHP projects

27Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Oh yes we did it...

<html> <body> <?php include("includes/menu.inc.php"); $file = (isset($_GET['pages'])) ? "pages/".$_GET['page'].".php" : "pages/404.php";

if ( !file_exists($file) ) { @include("pages/404.php"); } else { $allowed = realpath('./pages');

if ( !@ereg($allowed."*", realpath($file)) ) { @include("pages/404.php"); } else { @include($file); } } ?> </body></html>

somewhere in 2002...

■ HTML and PHP mix

Page 28: Symfony2 components to the rescue of your PHP projects

28Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Oh yes we did it...

<html> <body> <?php include("includes/menu.inc.php"); $file = (isset($_GET['pages'])) ? "pages/".$_GET['page'].".php" : "pages/404.php";

if ( !file_exists($file) ) { @include("pages/404.php"); } else { $allowed = realpath('./pages');

if ( !@ereg($allowed."*", realpath($file)) ) { @include("pages/404.php"); } else { @include($file); } } ?> </body></html>

somewhere in 2002...

■ HTML and PHP mix

■ Direct access to superglobals

Page 29: Symfony2 components to the rescue of your PHP projects

29Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Oh yes we did it...

<html> <body> <?php include("includes/menu.inc.php"); $file = (isset($_GET['pages'])) ? "pages/".$_GET['page'].".php" : "pages/404.php";

if ( !file_exists($file) ) { @include("pages/404.php"); } else { $allowed = realpath('./pages');

if ( !@ereg($allowed."*", realpath($file)) ) { @include("pages/404.php"); } else { @include($file); } } ?> </body></html>

somewhere in 2002...

■ HTML and PHP mix

■ Direct access to superglobals

■ Use of the @ operator

Page 30: Symfony2 components to the rescue of your PHP projects

30Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Oh yes we did it...

<html> <body> <?php include("includes/menu.inc.php"); $file = (isset($_GET['pages'])) ? "pages/".$_GET['page'].".php" : "pages/404.php";

if ( !file_exists($file) ) { @include("pages/404.php"); } else { $allowed = realpath('./pages');

if ( !@ereg($allowed."*", realpath($file)) ) { @include("pages/404.php"); } else { @include($file); } } ?> </body></html>

somewhere in 2002...

■ HTML and PHP mix

■ Direct access to superglobals

■ Use of the @ operator

■ Urls tied to code structure

Page 31: Symfony2 components to the rescue of your PHP projects

31Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Oh yes we did it...

<html> <body> <?php include("includes/menu.inc.php"); $file = (isset($_GET['pages'])) ? "pages/".$_GET['page'].".php" : "pages/404.php";

if ( !file_exists($file) ) { @include("pages/404.php"); } else { $allowed = realpath('./pages');

if ( !@ereg($allowed."*", realpath($file)) ) { @include("pages/404.php"); } else { @include($file); } } ?> </body></html>

somewhere in 2002...

■ HTML and PHP mix

■ Direct access to superglobals

■ Use of the @ operator

■ Urls tied to code structure

■ Duplicate code

Page 32: Symfony2 components to the rescue of your PHP projects

32Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Page 33: Symfony2 components to the rescue of your PHP projects

33Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Not bad at all

■ That was 10 years ago!

■ No PHP5 at that time

■ That was still flexible

■ Just missed some concepts

Page 34: Symfony2 components to the rescue of your PHP projects

34Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

The shit of today was great yesterday

So how did we improve things?

Page 35: Symfony2 components to the rescue of your PHP projects

35Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

2004 → 2007

■ First professional PHP frameworks

■ Zend Framework

■ Code Igniter

■ Seagull PHP

■ Cake PHP

■ symfony 1

■ Jelix

■ Pluf

■ Yii

■ etc.

Page 36: Symfony2 components to the rescue of your PHP projects

36Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

symfony 1

■ End 2005 : first public version (release 0.4)

■ Developers say “hurra”

ORM

Ajax

Plugins

Console

Conventions

Debug toolbar

Documentation

Functionnal and Unit tests

Internationalisation

Community

Helpers

Routing

Cache

MVC

Page 37: Symfony2 components to the rescue of your PHP projects

37Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Still not sufficient

■ Several limits:

■ Very monolithic

■ Not very flexible

■ Almost no components - use it all or don't use it

■ Some things were a pain to achieve

■ Extensive use of Singleton

■ Hard (impossible) to write complete test suites

■ Developers only

■ Performances... !

■ Lots of bad contribs

■ Low average community level

Page 38: Symfony2 components to the rescue of your PHP projects

38Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Page 39: Symfony2 components to the rescue of your PHP projects

Migration strategies

Page 40: Symfony2 components to the rescue of your PHP projects

40Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Summary

1. PHP in 2012, a living ecosystem

2. 2005's PHP is now just pain

3. Migration strategies

■ The slow path

■ Switch progressively

4. Symfony components for your pleasure

■ Your prefered migration toolkit

■ Case study

Page 41: Symfony2 components to the rescue of your PHP projects

41Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Pre-conditions

■ You work since more than 5 years on your project

■ A bunch of functionnalities

■ The app is in production

■ Lots of users and data

■ A competent team

■ But

■ New developments are slow

■ Infrastructure problems

■ Hard to improve things

■ You want to trash it all, and code like in 2012

Page 42: Symfony2 components to the rescue of your PHP projects

42Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Your reality

Pre-conditions

Page 43: Symfony2 components to the rescue of your PHP projects

43Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Your expectations

Pre-conditions

Page 44: Symfony2 components to the rescue of your PHP projects

44Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Strategy #1 – big bang

■ Most natural approach : rewrite everything

■ Pro:

■ A new solid and modern framework

■ Leave away from the old crappy codebase

■ Feel more happy

■ Cons:

■ Stop the company's business

■ Spend 1y+ re-developing everything

■ Have client cry

■ Complex migration scripts

■ Very risky

Page 45: Symfony2 components to the rescue of your PHP projects

45Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

■ Don't do that

■ Too risky

■ Lot of pressure

■ Might lead to a disaster

■ Your boss won't be happy

■ Prefer a gradual approach

Strategy #1 – big bang

Page 46: Symfony2 components to the rescue of your PHP projects

46Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Strategy #2 – Be progressive

■ Being progressive :

■ Re-write step by step

■ Control the way you build things

■ Use Framework parts, not the complete framework

■ Choose which parts to use

■ Gradually raise the level of your team

■ Less risky

■ And your boss will love you

Page 47: Symfony2 components to the rescue of your PHP projects

47Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Step #1

Switch to PHP 5.3 or PHP 5.4

NOW.

thanks w3techs.com*

*

Historical codebase

PHP x.x

Historical codebase

PHP 5.3

Page 48: Symfony2 components to the rescue of your PHP projects

48Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Step #1

■ Debian users :

■ Update your distribution version (eventually)

■ Update your packages (5 seconds)

■ Mac Users :

■ Please trash wamp and go grab http://php-osx.liip.ch/ (kudos Liip)

■ Windows users

Doh!

Page 49: Symfony2 components to the rescue of your PHP projects

49Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Step #2

■ Create a solid foundation for your future new developments

■ Put new things in your project

■ Symfony components are up! Start with:

■ ClassLoader

■ DependencyInjection

■ HTTPFoundation

Historical codebase

Historical codebase

ClassLoader

DIC

HTTPFoundation

Page 50: Symfony2 components to the rescue of your PHP projects

50Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Step #2 – install the components

■ Use composer

{ "autoload": { "psr-0": {} }, "name": "xavierlacot/blog", "description": "My old blog on steroids", "require": { "php": ">=5.3.3", "symfony/class-loader": "2.1.*", "symfony/dependency-injection": "2.1.*", "symfony/http-foundation": "2.1.*" }}

$ php composer.phar installInstalling dependencies from lock file - Updating symfony/class-loader (dev-master)

Page 51: Symfony2 components to the rescue of your PHP projects

51Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Step #2 – install the components

■ What did we install while doing this?

■ ClassLoader allows to load classes automagically, when required, if they follow a naming convention defined by PSR-0;

■ DependancyInjection provides a set of tools for building object and classes in a standardized way, and reduce the BC breaks;

■ HTTPFoundation is the basic toolkit when working with HTTP requests (all web pages, for example).

■ We'll see all three later un the presentation

Page 52: Symfony2 components to the rescue of your PHP projects

52Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Step #2 – install the components

■ Composer is great

■ It comes with an autoloader

■ Using the classes is simple :

■ And we're ready to start using the component classes!

<?phprequire 'vendor/autoload.php';

index.php

Page 53: Symfony2 components to the rescue of your PHP projects

53Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Step #3 – start using the components

■ HTTPFoundation is the easiest component to start with – the one you can immediately use without breaking things

use Symfony\Component\HttpFoundation\Request;$request = Request::createFromGlobals();

CreateFromGlobals() analyses the superglobals and populates the Request object

index.php

Page 54: Symfony2 components to the rescue of your PHP projects

54Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Step #3 – use HTTPFoundation

Time to change your historical code...

becomes

$pagename = (isset($_GET['page'])) ? $_GET['page'] : "404"; $file = sprintf('pages/%s.php', $pagename);

$pagename = $request->query->get('page', '404'); $file = sprintf('pages/%s.php', $pagename);

Page 55: Symfony2 components to the rescue of your PHP projects

55Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Step #4

■ There's no step #4

■ The rest of the process is very similar

■ Integrate the component

■ Use it

■ Refactor your code

■ Simplify

■ Iterate – don't break everything at once. Use components gradually

Page 56: Symfony2 components to the rescue of your PHP projects

Symfony components for your pleasure

Page 57: Symfony2 components to the rescue of your PHP projects

57Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Summary

1. PHP in 2012, a living ecosystem

2. 2005's PHP is now just pain

3. Migration strategies

■ The slow path

■ Switch progressively

4. Symfony components for your pleasure

■ Your prefered migration toolkit

■ Case study

Page 58: Symfony2 components to the rescue of your PHP projects

58Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

So what are the Symfony Components ?

■ Symfony components are :

■ A set of independent libraries

■ You can use them separately

■ High quality code components, tested and documented

■ Symfony components are not :

■ A bootstrap

■ They do not provide end user fonctionnalities

■ They are the bricks of your new platform, but you will have to glue them together

Page 59: Symfony2 components to the rescue of your PHP projects

59Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Symfony components

■ The complete list is available at http://symfony.com/components

■ Symfony2 is built with the Symfony components

■ You will often use the symfony standard distribution, which contains all the components plus some bundles

■ Components do not depend on any third party library

■ All kind of stuff:

■ HTTP management

■ Cache

■ Files finder

■ Routing management

■ Internationalization process

■ Templating

■ Forms management

■ etc.

Page 60: Symfony2 components to the rescue of your PHP projects

60Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Symfony components

■ Here is the list of what you can get :

■ BrowserKit

■ ClassLoader

■ Config

■ Console

■ CssSelector

■ DependencyInjection

■ DomCrawler

■ EventDispatcher

■ Finder

■ Form

■ HttpFoundation

■ HttpKernel

■ Locale

■ Process

■ Routing

■ Security

■ Serializer

■ Templating

■ Translation

■ Validator

■ Yaml

Page 61: Symfony2 components to the rescue of your PHP projects

61Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Your prefered migration toolkit

■ I won't detail all the components

■ Here are (AMHA) the most useful (and straightforward) when migrating an old application:

■ ClassLoader

■ Console

■ DependencyInjection

■ Finder

■ HttpFoundation

■ Routing

■ Templating

■ Validator

■ If you want to use more, consider using Symfony2 at some point

Page 62: Symfony2 components to the rescue of your PHP projects

62Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

ClassLoader

■ loads classes automatically if they follow PSR-0;

■ Migration process:

1. have your classes organization follow PSR-0 (renaming stuff)

2. Configure the ClassLoader

<?php

class prefixedLdapConnector{ public function __construct() { // stuff }}

ldap.php<?phpnamespace Prefix/Ldap/Client;

class Client{ public function __construct() { // stuff }}

src/Ldap/Client.php

Page 63: Symfony2 components to the rescue of your PHP projects

63Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

ClassLoader

■ loads classes automatically if they follow PSR-0;

■ Migration process:

1. have your classes organization follow PSR-0 (renaming stuff)

2. Configure the ClassLoader

<?php

class prefixedLdapConnector{ public function __construct() { // stuff }}

ldap.php<?phpnamespace Prefix/Ldap;

class Client{ public function __construct() { // stuff }}

src/Prefix/Ldap/Client.php

Page 64: Symfony2 components to the rescue of your PHP projects

64Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

ClassLoader

■ Composer's autoloader is taking care of vendors installed by composer

■ We must declare “our” classes:

■ Possible to declare several namespaces at once: registerNamespaces(array(...))

use Symfony\Component\ClassLoader\UniversalClassLoader;

$loader = new UniversalClassLoader();$loader->registerNamespace('Prefix', __DIR__.'/src/');$loader->register();

index.php

Page 65: Symfony2 components to the rescue of your PHP projects

65Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Console

■ Your best friend for writing:

■ Command line tasks

■ Cron jobs

■ Repetitive asynchron tasks

■ Pros:

■ Input / Output management

■ Colorization

■ Well written

■ Extensible

Page 66: Symfony2 components to the rescue of your PHP projects

66Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Console

■ Add the Console component to composer.json

■ Update the dependencies :

"require": { "php": ">=5.3.3", "symfony/class-loader": "2.1.*", "symfony/console": "2.1.*", "symfony/dependency-injection": "2.1.*", "symfony/http-foundation": "2.1.*"}

$ php composer.phar updateUpdating dependencies - Installing symfony/console (dev-master)

Writing lock fileGenerating autoload files

Page 67: Symfony2 components to the rescue of your PHP projects

67Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Console■ Write a new command:

<?phpnamespace Prefix\Command;

class TwitterCommand extends Command{ protected function configure() { $this ->setName('joli:twitter') ->setDescription('Gets updates from twitter') ; }

protected function execute(InputInterface $input, OutputInterface $output) { $puller = $this->getContainer()->get('joli.twitter.puller'); $output->writeln("Contacting Twitter..."); $data = $puller->pull();

// do stuff with $data

$output->writeln(sprintf('Tweets fetched. %s new tweets', count($tweets))); }}

Hint: I did remove some “use” statements

src/Prefix/Command/TwitterCommand.php

Page 68: Symfony2 components to the rescue of your PHP projects

68Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Console

■ Then create the executable file itself:

■ Fix this file's permissions:

#!/usr/bin/env php<?phprequire 'autoload.php';

use Prefix\Command\TwitterCommand;use Symfony\Component\Console\Application;

$application = new Application();$application->add(new TwitterCommand);$application->run();

console.php

$ chmod 755 console.php

Page 69: Symfony2 components to the rescue of your PHP projects

69Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Console

■ And finally run the command:

$ ./console joli:twitterContacting Twitter...Tweets successfuly fetched. 0 new tweets

$ ./console Console Tool

Usage: [options] command [arguments]

Options: --help -h Display this help message. --quiet -q Do not output any message. --verbose -v Increase verbosity of messages. --version -V Display this application version. --ansi Force ANSI output. --no-ansi Disable ANSI output. --no-interaction -n Do not ask any interactive question.

Available commands: help Displays help for a command list Lists commandsjoli joli:twitter Gets updates from twitter

Page 70: Symfony2 components to the rescue of your PHP projects

70Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Dependency Injection

■ “Dependency Injection” is a rather cryptic name

■ No drugs here, promise

■ Here is an “old school” function prototype:

■ It is bad, because:

■ The prototype will change when you will have new requirements

■ The order of the parameters is a hard constraint

■ Maybe one day you'll store menu items in a NoSQL database, and not in a relational one anymore

function makeMenu($sqlConnection, $menu, $nbItems = null, $level = 0, $startingWith = null)

Copyright me a long long long time ago*

*

Page 71: Symfony2 components to the rescue of your PHP projects

71Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Page 72: Symfony2 components to the rescue of your PHP projects

72Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Your existing app

■ Your existing app does a lot of things

■ Sending emails

■ Parsing data

■ Writing logs

■ Storing data in databases

Page 73: Symfony2 components to the rescue of your PHP projects

73Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Dependency Injection

■ The Dependency Injection component provides a dependency injection container

■ Imagine a large array of resources widely used in the whole application

■ This “DIC” has some capacities:

■ Resources are instantiated only when required;

■ It is extensible;

■ Each item of this DIC is called a “service”

■ The SQL connection is a service

■ Passing the DIC to a class automatically gives access to a large collection of services...!

Page 74: Symfony2 components to the rescue of your PHP projects

74Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Dependency Injection

DICDIC

Initialization Execution

bootstrapCreate services $container->get('mailer')

Instantiate a non-existing

service

Call the service

Page 75: Symfony2 components to the rescue of your PHP projects

75Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Implement your own services

■ In the migration plan:

■ convert the “service” functionnalities into real Symfony2 services,

■ Create binding to the existing calls

■ use them like before

■ In the future, put all your services in the container.

■ And use them from there

Page 76: Symfony2 components to the rescue of your PHP projects

76Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

DIC migration

■ Imagine we have a “Mailer” class:

■ A mail is sent in our code with:

<?phpnamespace Prefix\Mailer;

class Mailer{ $prefix = '';

public function send($to, $subject, $body) { // etc. }}

function saveUser($name, $email){ // stuff here $mailer = new Mailer; $mailer->send($user->getEmail(), 'Welcome '.$user->getName(), 'A test'); }

Page 77: Symfony2 components to the rescue of your PHP projects

77Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

DIC migration

■ Create the service container:

■ Pass it to our users management class

■ Use it:

use Symfony\Component\DependencyInjection\ContainerBuilder;

$container = new ContainerBuilder();$container->register('mailer', 'Mailer');

function saveUser($name, $email){ // stuff here $mailer = $this->container->get('mailer'); $mailer->send($user->getEmail(), 'Welcome '.$user->getName(), 'A test');

}

Page 78: Symfony2 components to the rescue of your PHP projects

78Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

DIC migration

■ Benefits:

■ The Mailer object is now only created in one place

■ Its configuration is centralized

■ It is easy to override in the user management class

Page 79: Symfony2 components to the rescue of your PHP projects

79Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

HttpFoundation

■ We have already used a little the HTTP Foundation component

■ One core concept of Symfony2 is the coverage of the framework

■ It handles Requests

■ And returns Responses

ApplicationUser

Request

Response

HTTP

Page 80: Symfony2 components to the rescue of your PHP projects

80Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

HttpFoundation

■ HttpFoundation provides concepts for Request and Responses

■ Every input from the user, or output to the user should pass through this component

■ Request:

■ $request→request represents $_POST

■ $request→query represents $_GET

■ $request→cookies represents $_COOKIE

■ etc.

use Symfony\Component\HttpFoundation\Request;$request = Request::createFromGlobals();

Page 81: Symfony2 components to the rescue of your PHP projects

81Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

HttpFoundation

■ Response:

■ Represents the stuff returned to the user through HTTP

■ It implements HTTP 1.1, the response is customizable:

use Symfony\Component\HttpFoundation\Response;$response = new Response();

$response->setContent('This will be the response content');$response->headers->set('Content-Type', 'text/html');$response->setStatusCode(200);

// send the Response$response->prepare($request);$response->send();

Page 82: Symfony2 components to the rescue of your PHP projects

82Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Migration plan for using HttpFoundation

■ HTTPFoundation will help:

■ Making your application more secure

■ Enforce a normalization of the way the output is sent ot the user

■ Migration plan:

■ Start with systematically using the Request ibject in place of the superglobals

■ Use Response objects whenever possible

■ ob_* may help you

■ Use a templating system to move view content in separate files

Page 83: Symfony2 components to the rescue of your PHP projects

83Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Routing Component – what we did before...

■ Didn't you find nasty the way we manage urls in our old app?

$file = (isset($_GET['pages'])) ? "pages/".$_GET['page'].".php" : "pages/404.php";

if ( !file_exists($file) ) { @include("pages/404.php"); } else { $allowed = realpath('./pages');

if ( !@ereg($allowed."*", realpath($file)) ) { @include("pages/404.php"); } else { @include($file); } }

Page 84: Symfony2 components to the rescue of your PHP projects

84Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

■ Yes, it is far from perfect:

■ Urls enforce code organization

■ This system may cause security problems

■ What if the “$allowed” check doesn't work?

■ It is not extensible

■ The url ↔ action matching is hardcoded, which means no possible alternative

■ Bad for SEO

■ http://example.org/index.php?page=news&id=3657

■ The Symfony2 Routing component helps handling urls in an abstract way

Routing Component – what we did before...

Page 85: Symfony2 components to the rescue of your PHP projects

85Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Routing Component

■ Routing is a mechanism which allows to manage the address map of an application

■ Very useful:

■ Better SEO

■ Better security

■ Help reorganize the application internally

■ Do not expose the technology you use

Page 86: Symfony2 components to the rescue of your PHP projects

86Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Routing

■ There are two types of routing

■ “Descending” routing: maps an URI to an action the application must complete:

■ /blog must display the list of posts

■ /blog/2010/05/12/un-message.html must display the right post

■ /contact must display the contact form

■ “ascending” routing helps generate nice, SEO compliant URLs

/blog

Descending routingUser

Page 87: Symfony2 components to the rescue of your PHP projects

87Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Routing component – migration plan

■ The migration plan for using this component will strongly depend on the way you developed your application.

■ Usually:

■ Add the component to composer.json, update

■ In the front controller, use the routing to match certain urls and handle the request in a clean way

■ This way, it won't affect other URLs

■ Once installed, always use the Router when exposing new URLs

Page 88: Symfony2 components to the rescue of your PHP projects

88Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

In our example...

■ First, declare the routes

■ Then, match the requests to find the page to load

// declare the routes$routes = new RouteCollection();$routes->add( 'blog_show', new Route( '/blog/{year}/{month}/{slug}', array('pagename' => 'display_blog') ));

$context = new RequestContext();$context->fromRequest($request);$matcher = new UrlMatcher($routes, $context);

try{ $route = $matcher->match($request->getRequestUri()); // do things}catch (ResourceNotFoundException $e){ // handle exception }

Hint: I did remove some “use” statements

$route now contains the matched route parameters

Page 89: Symfony2 components to the rescue of your PHP projects

89Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Generating URLs with the Routing Component

■ $router::generate() allows to generate a URL with parameters:

■ Of course, add the Routing as a service to the container!

$generator = new UrlGenerator($routes, $context);$url = $generator->generate('blog_show', array( 'slug' => 'hello-les-poneys', 'year' => '2011', 'month' => '11'));$response->setContent('Please go <a href="'.$url.'">here</a>');$response->send();

Page 90: Symfony2 components to the rescue of your PHP projects

90Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Questions ?Contact

Xavier [email protected] 51 48 59 73

http://jolicode.comTwitter : @JoliCode

Page 91: Symfony2 components to the rescue of your PHP projects

91Symfony2 components to the rescue of your PHP projectsJoliCode | Xavier Lacot | Symfony Live 2012

Credits

■ Photos – thanks to the photographers:

■ http://www.flickr.com/photos/artbandito/67829362/

■ http://capsizedatsea.tumblr.com/post/9559345143

■ http://memegenerator.net