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.
2. 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
Symfony2 components to the rescue of your PHP projects 2
JoliCode | Xavier Lacot | Symfony Live 2012
3. 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
Symfony2 components to the rescue of your PHP projects 3
JoliCode | Xavier Lacot | Symfony Live 2012
4. Before we start
How many of you use a framework on a regular basis?
How many of you must deal with no-framework
applications?
Symfony2 components to the rescue of your PHP projects 4
JoliCode | Xavier Lacot | Symfony Live 2012
6. 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
Symfony2 components to the rescue of your PHP projects 6
JoliCode | Xavier Lacot | Symfony Live 2012
7. The language improves
■ PHP 5.3 introduced new concepts :
■ Usage of namespaces
namespace JoliCodeConferences;
use GeneralTalkSession;
class SymfonyLive extends Session
{
public function runPresentation()
{
// do something nice...
}
}
■ Lambda and closures
■ Phar archives
■ “goto” WTF ???
Symfony2 components to the rescue of your PHP projects 7
JoliCode | Xavier Lacot | Symfony Live 2012
8. Namespaces manipulation
■ Pro
■ No more collisions
■ Less ambiguity
■ Ahah, short class names. No more long classnames
■ Cons
■ Don't forget the use statement
use OneFullClassname as Something;
$object = new Something;
Symfony2 components to the rescue of your PHP projects 8
JoliCode | Xavier Lacot | Symfony Live 2012
9. And it still evolves
■ PHP 5.4
■ Some deprecated features removed
■ Performance improvements
■ Instance Method Calls
$post = (new Post)->setTitle('Hello poneys')->save();
■ Closures inside objects
■ Traits, aka. assisted copy/paste
■ Arrays manipulation
function fruits() {
return ['apple', 'banana', 'orange'];
}
echo fruits()[0]; // Outputs: apple
Symfony2 components to the rescue of your PHP projects 9
JoliCode | Xavier Lacot | Symfony Live 2012
10. 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
Symfony2 components to the rescue of your PHP projects 10
JoliCode | Xavier Lacot | Symfony Live 2012
13. ClassLoader and PSR-0
■ PSR-0 :
■ A standardization agreement
■ Scope: classes naming and organization
class: SymfonyComponentHttpFoundationRequest
path: vendor/src/Symfony/Component/HttpFoundation/Request.php
class: Twig_Extension_Core
path: vendor/twig/lib/Twig/Extension/Core.php
■ Idea : match the path of the file containg a class to
this full class name
Symfony2 components to the rescue of your PHP projects 13
JoliCode | Xavier Lacot | Symfony Live 2012
14. ClassLoader and PSR-0
Namespaced classes style
autoloading path prefix
class: SymfonyComponentHttpFoundationRequest
path: vendor/src/Symfony/Component/HttpFoundation/Request.php
class: Twig_Extension_Core
path: vendor/twig/lib/Twig/Extension/Core.php
PEAR naming style
Symfony2 components to the rescue of your PHP projects 14
JoliCode | Xavier Lacot | Symfony Live 2012
15. 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
Symfony2 components to the rescue of your PHP projects 15
JoliCode | Xavier Lacot | Symfony Live 2012
16. Dependancies resolution using Composer
composer.json
{
"name": "joli/demo-project",
"description": "A simple demo project",
"require": {
"php": ">=5.3.3",
"symfony/symfony": "2.1.*",
"seld/jsonlint": "1.0.0"
}
}
$ php composer.phar install
Installing dependencies from lock file
- Updating twig/twig (dev-master)
■ And more:
■ Post install commands
■ Configuration variables
■ etc.
Symfony2 components to the rescue of your PHP projects 16
JoliCode | Xavier Lacot | Symfony Live 2012
17. 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
Symfony2 components to the rescue of your PHP projects 17
JoliCode | Xavier Lacot | Symfony Live 2012
18. Symfony2 components to the rescue of your PHP projects 18
JoliCode | Xavier Lacot | Symfony Live 2012
19. 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
Symfony2 components to the rescue of your PHP projects 19
JoliCode | Xavier Lacot | Symfony Live 2012
20. Symfony2 components to the rescue of your PHP projects 20
JoliCode | Xavier Lacot | Symfony Live 2012
22. 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
Symfony2 components to the rescue of your PHP projects 22
JoliCode | Xavier Lacot | Symfony Live 2012
23. Symfony2 components to the rescue of your PHP projects 23
JoliCode | Xavier Lacot | Symfony Live 2012
24. 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
Symfony2 components to the rescue of your PHP projects 24
JoliCode | Xavier Lacot | Symfony Live 2012
26. Oh yes we did it...
somewhere in 2002...
<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>
Symfony2 components to the rescue of your PHP projects 26
JoliCode | Xavier Lacot | Symfony Live 2012
27. Oh yes we did it...
somewhere in 2002...
<html>
<body>
<?php
include("includes/menu.inc.php");
■ HTML and PHP mix
$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>
Symfony2 components to the rescue of your PHP projects 27
JoliCode | Xavier Lacot | Symfony Live 2012
28. Oh yes we did it...
somewhere in 2002...
<html>
<body>
<?php
include("includes/menu.inc.php");
■ HTML and PHP mix
$file = (isset($_GET['pages'])) ? "pages/".$_GET['page'].".php" : "pages/404.php";
if ( !file_exists($file) )
{
■ Direct access to
}
@include("pages/404.php"); superglobals
else
{
$allowed = realpath('./pages');
if ( !@ereg($allowed."*", realpath($file)) )
{
@include("pages/404.php");
}
else
{
@include($file);
}
}
?>
</body>
</html>
Symfony2 components to the rescue of your PHP projects 28
JoliCode | Xavier Lacot | Symfony Live 2012
29. Oh yes we did it...
somewhere in 2002...
<html>
<body>
<?php
include("includes/menu.inc.php");
■ HTML and PHP mix
$file = (isset($_GET['pages'])) ? "pages/".$_GET['page'].".php" : "pages/404.php";
if ( !file_exists($file) )
{
■ Direct access to
}
@include("pages/404.php"); superglobals
else
{ ■ Use of the @ operator
$allowed = realpath('./pages');
if ( !@ereg($allowed."*", realpath($file)) )
{
@include("pages/404.php");
}
else
{
@include($file);
}
}
?>
</body>
</html>
Symfony2 components to the rescue of your PHP projects 29
JoliCode | Xavier Lacot | Symfony Live 2012
30. Oh yes we did it...
somewhere in 2002...
<html>
<body>
<?php
include("includes/menu.inc.php");
■ HTML and PHP mix
$file = (isset($_GET['pages'])) ? "pages/".$_GET['page'].".php" : "pages/404.php";
if ( !file_exists($file) ) ■ Direct access to
{
@include("pages/404.php"); superglobals
}
else
{ ■ Use of the @ operator
$allowed = realpath('./pages');
if ( !@ereg($allowed."*", realpath($file)) )
■ Urls tied to code
{ structure
@include("pages/404.php");
}
else
{
@include($file);
}
}
?>
</body>
</html>
Symfony2 components to the rescue of your PHP projects 30
JoliCode | Xavier Lacot | Symfony Live 2012
31. Oh yes we did it...
somewhere in 2002...
<html>
<body>
<?php
include("includes/menu.inc.php");
■ HTML and PHP mix
$file = (isset($_GET['pages'])) ? "pages/".$_GET['page'].".php" : "pages/404.php";
if ( !file_exists($file) ) ■ Direct access to
{
@include("pages/404.php"); superglobals
}
else
{
■ Use of the @ operator
$allowed = realpath('./pages');
■ Urls tied to code
if ( !@ereg($allowed."*", realpath($file)) )
{ structure
@include("pages/404.php");
}
else
■ Duplicate code
{
@include($file);
}
}
?>
</body>
</html>
Symfony2 components to the rescue of your PHP projects 31
JoliCode | Xavier Lacot | Symfony Live 2012
32. Symfony2 components to the rescue of your PHP projects 32
JoliCode | Xavier Lacot | Symfony Live 2012
33. Not bad at all
■ That was 10 years ago!
■ No PHP5 at that time
■ That was still flexible
■ Just missed some concepts
Symfony2 components to the rescue of your PHP projects 33
JoliCode | Xavier Lacot | Symfony Live 2012
34. The shit of today was great yesterday
So how did we improve things?
Symfony2 components to the rescue of your PHP projects 34
JoliCode | Xavier Lacot | Symfony Live 2012
35. 2004 → 2007
■ First professional PHP frameworks
■ Zend Framework
■ Code Igniter
■ Seagull PHP
■ Cake PHP
■ symfony 1
■ Jelix
■ Pluf
■ Yii
■ etc.
Symfony2 components to the rescue of your PHP projects 35
JoliCode | Xavier Lacot | Symfony Live 2012
36. symfony 1
■ End 2005 : first public version (release 0.4)
■ Developers say “hurra”
ORM Functionnal and Unit tests
Ajax Internationalisation
Plugins Community
Console Helpers
Conventions Routing
Debug toolbar Cache
Documentation MVC
Symfony2 components to the rescue of your PHP projects 36
JoliCode | Xavier Lacot | Symfony Live 2012
37. 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
Symfony2 components to the rescue of your PHP projects 37
JoliCode | Xavier Lacot | Symfony Live 2012
38. Symfony2 components to the rescue of your PHP projects 38
JoliCode | Xavier Lacot | Symfony Live 2012
40. 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
Symfony2 components to the rescue of your PHP projects 40
JoliCode | Xavier Lacot | Symfony Live 2012
41. 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
Symfony2 components to the rescue of your PHP projects 41
JoliCode | Xavier Lacot | Symfony Live 2012
42. Pre-conditions
Your reality
Symfony2 components to the rescue of your PHP projects 42
JoliCode | Xavier Lacot | Symfony Live 2012
43. Pre-conditions
Your expectations
Symfony2 components to the rescue of your PHP projects 43
JoliCode | Xavier Lacot | Symfony Live 2012
44. 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
Symfony2 components to the rescue of your PHP projects 44
JoliCode | Xavier Lacot | Symfony Live 2012
45. Strategy #1 – big bang
■ Don't do that
■ Too risky
■ Lot of pressure
■ Might lead to a disaster
■ Your boss won't be happy
■ Prefer a gradual approach
Symfony2 components to the rescue of your PHP projects 45
JoliCode | Xavier Lacot | Symfony Live 2012
46. 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
Symfony2 components to the rescue of your PHP projects 46
JoliCode | Xavier Lacot | Symfony Live 2012
47. Step #1
Switch to PHP 5.3 or PHP 5.4
NOW.
*
Historical Historical
codebase codebase
PHP x.x PHP 5.3
Symfony2 components to the rescue of your PHP projects 47
JoliCode | Xavier Lacot | Symfony Live 2012 thanks w3techs.com
48. 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!
Symfony2 components to the rescue of your PHP projects 48
JoliCode | Xavier Lacot | Symfony Live 2012
49. 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
ClassLoader
Historical Historical
codebase DIC
codebase
HTTPFoundation
Symfony2 components to the rescue of your PHP projects 49
JoliCode | Xavier Lacot | Symfony Live 2012
50. 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 install
Installing dependencies from lock file
- Updating symfony/class-loader (dev-master)
Symfony2 components to the rescue of your PHP projects 50
JoliCode | Xavier Lacot | Symfony Live 2012
51. 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
Symfony2 components to the rescue of your PHP projects 51
JoliCode | Xavier Lacot | Symfony Live 2012
52. Step #2 – install the components
■ Composer is great
■ It comes with an autoloader
■ Using the classes is simple :
index.php
<?php
require 'vendor/autoload.php';
■ And we're ready to start using the component classes!
Symfony2 components to the rescue of your PHP projects 52
JoliCode | Xavier Lacot | Symfony Live 2012
53. Step #3 – start using the components
■ HTTPFoundation is the easiest component to start
with – the one you can immediately use without
breaking things
index.php
use SymfonyComponentHttpFoundationRequest;
$request = Request::createFromGlobals();
CreateFromGlobals()
analyses the superglobals
and populates the Request
object
Symfony2 components to the rescue of your PHP projects 53
JoliCode | Xavier Lacot | Symfony Live 2012
54. Step #3 – use HTTPFoundation
Time to change your historical code...
$pagename = (isset($_GET['page'])) ? $_GET['page'] : "404";
$file = sprintf('pages/%s.php', $pagename);
becomes
$pagename = $request->query->get('page', '404');
$file = sprintf('pages/%s.php', $pagename);
Symfony2 components to the rescue of your PHP projects 54
JoliCode | Xavier Lacot | Symfony Live 2012
55. 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
Symfony2 components to the rescue of your PHP projects 55
JoliCode | Xavier Lacot | Symfony Live 2012
57. 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
Symfony2 components to the rescue of your PHP projects 57
JoliCode | Xavier Lacot | Symfony Live 2012
58. 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
Symfony2 components to the rescue of your PHP projects 58
JoliCode | Xavier Lacot | Symfony Live 2012
59. 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 ■ Internationalization process
■ Cache ■ Templating
■ Files finder ■ Forms management
■ Routing management ■ etc.
Symfony2 components to the rescue of your PHP projects 59
JoliCode | Xavier Lacot | Symfony Live 2012
60. Symfony components
■ Here is the list of what you can get :
■ BrowserKit
■ ClassLoader ■ HttpKernel
■ Config ■ Locale
■ Console ■ Process
■ CssSelector ■ Routing
■ DependencyInjection ■ Security
■ DomCrawler ■ Serializer
■ EventDispatcher ■ Templating
■ Finder ■ Translation
■ Form ■ Validator
■ HttpFoundation ■ Yaml
Symfony2 components to the rescue of your PHP projects 60
JoliCode | Xavier Lacot | Symfony Live 2012
61. 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
Symfony2 components to the rescue of your PHP projects 61
JoliCode | Xavier Lacot | Symfony Live 2012
62. ClassLoader
■ loads classes automatically if they follow PSR-0;
■ Migration process:
1. have your classes organization follow PSR-0 (renaming
stuff)
ldap.php src/Ldap/Client.php
<?php <?php
namespace Prefix/Ldap/Client;
class prefixedLdapConnector
{ class Client
public function __construct() {
{ public function __construct()
// stuff {
} // stuff
} }
}
2. Configure the ClassLoader
Symfony2 components to the rescue of your PHP projects 62
JoliCode | Xavier Lacot | Symfony Live 2012
63. ClassLoader
■ loads classes automatically if they follow PSR-0;
■ Migration process:
1. have your classes organization follow PSR-0 (renaming
stuff)
ldap.php src/Prefix/Ldap/Client.php
<?php <?php
namespace Prefix/Ldap;
class prefixedLdapConnector
{ class Client
public function __construct() {
{ public function __construct()
// stuff {
} // stuff
} }
}
2. Configure the ClassLoader
Symfony2 components to the rescue of your PHP projects 63
JoliCode | Xavier Lacot | Symfony Live 2012
64. ClassLoader
■ Composer's autoloader is taking care of vendors
installed by composer
■ We must declare “our” classes:
index.php
use SymfonyComponentClassLoaderUniversalClassLoader;
$loader = new UniversalClassLoader();
$loader->registerNamespace('Prefix', __DIR__.'/src/');
$loader->register();
■ Possible to declare several namespaces at once:
registerNamespaces(array(...))
Symfony2 components to the rescue of your PHP projects 64
JoliCode | Xavier Lacot | Symfony Live 2012
65. Console
■ Your best friend for writing:
■ Command line tasks
■ Cron jobs
■ Repetitive asynchron tasks
■ Pros:
■ Input / Output management
■ Colorization
■ Well written
■ Extensible
Symfony2 components to the rescue of your PHP projects 65
JoliCode | Xavier Lacot | Symfony Live 2012
66. Console
■ Add the Console component to composer.json
"require": {
"php": ">=5.3.3",
"symfony/class-loader": "2.1.*",
"symfony/console": "2.1.*",
"symfony/dependency-injection": "2.1.*",
"symfony/http-foundation": "2.1.*"
}
■ Update the dependencies :
$ php composer.phar update
Updating dependencies
- Installing symfony/console (dev-master)
Writing lock file
Generating autoload files
Symfony2 components to the rescue of your PHP projects 66
JoliCode | Xavier Lacot | Symfony Live 2012
67. Console
■ Write a new command:
src/Prefix/Command/TwitterCommand.php
<?php
namespace PrefixCommand;
class TwitterCommand extends Command
{
protected function configure()
{
Hint: I did
$this
remove some
->setName('joli:twitter')
“use”
->setDescription('Gets updates from twitter')
statements
;
}
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)));
}
}
Symfony2 components to the rescue of your PHP projects 67
JoliCode | Xavier Lacot | Symfony Live 2012
68. Console
■ Then create the executable file itself:
console.php
#!/usr/bin/env php
<?php
require 'autoload.php';
use PrefixCommandTwitterCommand;
use SymfonyComponentConsoleApplication;
$application = new Application();
$application->add(new TwitterCommand);
$application->run();
■ Fix this file's permissions:
$ chmod 755 console.php
Symfony2 components to the rescue of your PHP projects 68
JoliCode | Xavier Lacot | Symfony Live 2012
69. Console
■ And finally run the command:
$ ./console joli:twitter
Contacting 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 commands
joli
joli:twitter Gets updates from twitter
Symfony2 components to the rescue of your PHP projects 69
JoliCode | Xavier Lacot | Symfony Live 2012
70. Dependency Injection
■ “Dependency Injection” is a rather cryptic name
■ No drugs here, promise
■ Here is an “old school” function prototype:
function makeMenu($sqlConnection, $menu, $nbItems = null, $level =
0, $startingWith = null)
*
■ 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
Copyright
Symfony2 components to the rescue of your PHP projects me a long long long time ago 70
JoliCode | Xavier Lacot | Symfony Live 2012
71. Symfony2 components to the rescue of your PHP projects 71
JoliCode | Xavier Lacot | Symfony Live 2012
72. Your existing app
■ Your existing app does a lot of things
■ Sending emails
■ Parsing data
■ Writing logs
■ Storing data in databases
Symfony2 components to the rescue of your PHP projects 72
JoliCode | Xavier Lacot | Symfony Live 2012
73. 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...!
Symfony2 components to the rescue of your PHP projects 73
JoliCode | Xavier Lacot | Symfony Live 2012
74. Dependency Injection
Initialization Execution
Call the
service
Create services DIC
DIC $container->get('mailer')
bootstrap
Instantiate a
non-existing
service
Symfony2 components to the rescue of your PHP projects 74
JoliCode | Xavier Lacot | Symfony Live 2012
75. 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
Symfony2 components to the rescue of your PHP projects 75
JoliCode | Xavier Lacot | Symfony Live 2012
76. DIC migration
■ Imagine we have a “Mailer” class:
<?php
namespace PrefixMailer;
class Mailer
{
$prefix = '';
public function send($to, $subject, $body)
{
// etc.
}
}
■ A mail is sent in our code with:
function saveUser($name, $email)
{
// stuff here
$mailer = new Mailer;
$mailer->send($user->getEmail(), 'Welcome '.$user->getName(), 'A test');
}
Symfony2 components to the rescue of your PHP projects 76
JoliCode | Xavier Lacot | Symfony Live 2012
77. DIC migration
■ Create the service container:
use SymfonyComponentDependencyInjectionContainerBuilder;
$container = new ContainerBuilder();
$container->register('mailer', 'Mailer');
■ Pass it to our users management class
■ Use it:
function saveUser($name, $email)
{
// stuff here
$mailer = $this->container->get('mailer');
$mailer->send($user->getEmail(), 'Welcome '.$user->getName(), 'A test');
}
Symfony2 components to the rescue of your PHP projects 77
JoliCode | Xavier Lacot | Symfony Live 2012
78. 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
Symfony2 components to the rescue of your PHP projects 78
JoliCode | Xavier Lacot | Symfony Live 2012
79. 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
Request
User HTTP Application
Response
Symfony2 components to the rescue of your PHP projects 79
JoliCode | Xavier Lacot | Symfony Live 2012
80. HttpFoundation
■ HttpFoundation provides concepts for Request and Responses
■ Every input from the user, or output to the user should
pass through this component
■ Request:
use SymfonyComponentHttpFoundationRequest;
$request = Request::createFromGlobals();
■ $request→request represents $_POST
■ $request→query represents $_GET
■ $request→cookies represents $_COOKIE
■ etc.
Symfony2 components to the rescue of your PHP projects 80
JoliCode | Xavier Lacot | Symfony Live 2012
81. HttpFoundation
■ Response:
■ Represents the stuff returned to the user through HTTP
use SymfonyComponentHttpFoundationResponse;
$response = new Response();
■ It implements HTTP 1.1, the response is customizable:
$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();
Symfony2 components to the rescue of your PHP projects 81
JoliCode | Xavier Lacot | Symfony Live 2012
82. 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
Symfony2 components to the rescue of your PHP projects 82
JoliCode | Xavier Lacot | Symfony Live 2012
83. 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);
}
}
Symfony2 components to the rescue of your PHP projects 83
JoliCode | Xavier Lacot | Symfony Live 2012
84. Routing Component – what we did before...
■ 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
Symfony2 components to the rescue of your PHP projects 84
JoliCode | Xavier Lacot | Symfony Live 2012
85. 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
Symfony2 components to the rescue of your PHP projects 85
JoliCode | Xavier Lacot | Symfony Live 2012
86. 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
/blog
User
Descending routing
■ “ascending” routing helps generate nice, SEO compliant URLs
Symfony2 components to the rescue of your PHP projects 86
JoliCode | Xavier Lacot | Symfony Live 2012
87. 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
Symfony2 components to the rescue of your PHP projects 87
JoliCode | Xavier Lacot | Symfony Live 2012
88. In our example...
■ First, declare the routes Hint: I did
remove some
// declare the routes “use”
$routes = new RouteCollection(); statements
$routes->add(
'blog_show',
new Route(
'/blog/{year}/{month}/{slug}',
array('pagename' => 'display_blog')
)
);
■ Then, match the requests to find the page to load
$context = new RequestContext();
$context->fromRequest($request);
$matcher = new UrlMatcher($routes, $context);
try $route now
{ contains the
$route = $matcher->match($request->getRequestUri()); matched route
// do things parameters
}
catch (ResourceNotFoundException $e)
Symfony2 // handle the rescue of your } projects
{ components to exception PHP 88
JoliCode | Xavier Lacot | Symfony Live 2012
89. Generating URLs with the Routing Component
■ $router::generate() allows to generate a URL with
parameters:
$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();
■ Of course, add the Routing as a service to the
container!
Symfony2 components to the rescue of your PHP projects 89
JoliCode | Xavier Lacot | Symfony Live 2012
90. Questions ?
Contact
Xavier Lacot
xlacot@jolicode.com
06 51 48 59 73
http://jolicode.com
Twitter : @JoliCode
Symfony2 components to the rescue of your PHP projects 90
JoliCode | Xavier Lacot | Symfony Live 2012
91. Credits
■ Photos – thanks to the photographers:
■ http://www.flickr.com/photos/artbandito/67829362/
■ http://capsizedatsea.tumblr.com/post/9559345143
■ http://memegenerator.net
Symfony2 components to the rescue of your PHP projects 91
JoliCode | Xavier Lacot | Symfony Live 2012