Download - Symfony2 components to the rescue of your PHP projects

Transcript
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