Tata AIG General Insurance Company - Insurer Innovation Award 2024
Starting your new Symfony2 project
1. Starting your new
project with
Symfony2
Ryan Weaver
@weaverryan
Thursday, August 18, 11
2. Who is this dude?
• Co-author of the Symfony2 Docs
• Core Symfony2 contributor
• Co-owner of KnpLabs US
• Fiancee of the much more
talented @leannapelham
http://www.knplabs.com/en
http://www.github.com/weaverryan
Thursday, August 18, 11
3. KnpLabs
Quality. Innovation. Excitement.
• Training
• Coaching / Consulting
• Fun, high-quality custom dev
Thursday, August 18, 11
4. Act 1:
Downloading the Symfony
Standard Edition
http://bit.ly/sf2-install
Thursday, August 18, 11
5. The “Standard Distribution”
• Symfony offers “distributions” (think Ubuntu)
• The “Standard Distribution” is a fully-functional
skeleton web application
• The Standard Distribution *is* the starting
point for your new project: download it and
begin developing your new application
Thursday, August 18, 11
6. Step 1: Get it!
http://symfony.com/download
Thursday, August 18, 11
7. Step 2: Unzip it!
$ cd /path/to/webroot
$ tar zxvf /path/to/Symfony_Standard_2.0.0.tgz
Thursday, August 18, 11
8. Step 3: Download the vendors
• Run the following command:
php bin/vendors install
• ...which should fill up your vendor/ directory
Thursday, August 18, 11
9. Step 3: Explained
• The “standard edition” project itself is just a
few directories and a few files
• But it relies a group of 3rd-party libraries
• The Standard edition packages a script that
downloads these libraries into your vendor/
directory by reading the “deps” file
php bin/vendors install
Thursday, August 18, 11
11. Step 4: Check your config
http://localhost/Symfony/web/config.php
Thursday, August 18, 11
12. Tend to your Garden
• Fix any major problems (e.g. missing libraries,
permissions issues) that Symfony reports
Thursday, August 18, 11
13. Cache and log permissions
• The app/cache and app/logs directories must
be writable by your web server
• There are several ways to do this depending
on your setup and platform
D o cs
T he http://bit.ly/sf2-perms
Thursday, August 18, 11
14. Head to the homepage!
This *is* your
first Symfony2
page!!!
http://localhost/Symfony/web/app_dev.php
Thursday, August 18, 11
15. End of Act1
• So far we’ve:
‣ Downloaded the Standard Distribution
‣ Downloaded the vendor libraries
‣ Setup any pre-reqs needed for Symfony
‣ Navigated to the homepage of our project:
a sample page packaged with the distribution
Thursday, August 18, 11
16. Act 2:
Storing the new project in git
http://bit.ly/sf2-git
Thursday, August 18, 11
17. Version Control
• The Standard Distribution *is* the starting
point for your new project
• We’ll use “git” as our version control tool
• Initialize a new git repository inside your
project:
git init
git status
Thursday, August 18, 11
19. Ignore Some Files
• Most of the files are *your* files: you’ll edit
them and commit them to git
• Some files, however, shouldn’t be shared:
‣ database configuration files
• Others simply don’t need to be committed
‣ 3rd party libraries (each developer can
download them via “bin/vendors install”)
‣ cache files
Thursday, August 18, 11
20. Ignore Some Files
• To ignore certain files in git, create a .gitignore
file at the root of your project and specify file
patterns that shouldn’t be stored in git
Thursday, August 18, 11
21. Recommended “.gitignore” file
{
/web/bundles/
/app/bootstrap*
“generated” /app/cache/*
files
/app/logs/*
/vendor/
db config { /app/config/parameters.ini
Thursday, August 18, 11
22. Initial Commit
• Once you’ve created the .gitignore file, you
can create an initial commit
• This commit represents the starting point of
your project: a fresh project with Symfony
git add .
git commit -m “Initial commit of the project”
Thursday, August 18, 11
23. Database Configuration
• By convention, database (and other server-
specific) configuration is stored in the app/
config/parameters.ini file
• We’ve placed this file in our .gitignore
• Every new developer that downloads the
project will need to create this file
Thursday, August 18, 11
24. Database Configuration
• To make the creation of the parameters.ini file
easy, create a parameters.ini.dist sample file that
we *will* commit to git
cp app/config/parameters.ini app/config/parameters.ini.dist
git add app/config/parameters.ini.dist
git commit -m “adding a sample parameters file”
Thursday, August 18, 11
25. Removing demo pages
• The Standard Distribution comes with some
sample pages inside a demo bundle
• Remove these before developing your own
application
https://github.com/symfony/symfony-standard
Thursday, August 18, 11
26. Finishing up Act 2
• Where are we now?
‣ The new project is stored in git
‣ Certain files are set to be ignored by git
‣ A database configuration “template” file
was created to help when the project is
cloned by new developers
Thursday, August 18, 11
27. Act 3:
What Symfony does...
in exactly 3 slides
http://bit.ly/sf2-http
Thursday, August 18, 11
28. Your job: turn a request into a response
the request
/foo
Client
Your App
(e.g. browser)
<h1>Foo!</h1>
the response
But as your app grows, staying organized is
tough, wheels are reinvented and code tends
towards spaghetti
Thursday, August 18, 11
29. Request to Response Structure
• Symfony gives you structure for reading each
request and creating the appropriate response
e.g. app.php
1) a request executes 2) matches a route 3) executes a PHP function
the front controller that you write
Thursday, August 18, 11
30. Tools for Development
• In addition to basic structure, Symfony is full of
optional tools that you can choose to use when
developing your application:
‣ security
‣ render templates
‣ send emails
‣ work with the database
‣ handle HTML forms
‣ validation
‣ caching
Thursday, August 18, 11
31. Act 4:
Creating your app
http://bit.ly/sf2-page-creation
Thursday, August 18, 11
32. Bundles!
• A standard Symfony project looks like this:
app/ app config - nothing too heavy
src/ your bundles!
vendor/ third-party libraries
web/ front controllers, CSS, JS, etc
Thursday, August 18, 11
33. Bundles: first-class plugins
• A bundle is a directory that holds *everything*
for a single “feature” - from routing files to PHP
classes to JS files
• A bundle is like a plugin, except that
everything (including the core Symfony2 files)
exists in a bundle
(this means you could replace the core framework libraries
with your own...)
Thursday, August 18, 11
34. Creating the MainBundle
• Symfony can generate a nice bundle skeleton
on your behalf:
php app/console generate:bundle
Answer the prompts:
• Acme/MainBundle
• MainBundle
• ... enter the defaults for the rest
Thursday, August 18, 11
35. Initialize the bundle
• The following was added by the task to your
app/AppKernel.php file:
public function registerBundles()
{
$bundles = array(
// ...
new AcmeMainBundleMainBundle(),
);
}
Thursday, August 18, 11
36. Where now?
• Now that you have a bundle, you can start
creating your app page-by-page:
‣ create a route
‣ create a controller
‣ create and return a Response object
(usually via a template)
• As you develop more features, you may
create more bundles, but it’s up to you
Thursday, August 18, 11
37. Open Source Bundles
• Lots of 3rd-party bundles are also available
to help you:
‣ FOSUserBundle - user management
‣ KnpMenuBundle - really smart menus
‣ DoctrineFixturesBundle
‣ StofDoctrineExtensionsBundle - easy doctrine
behaviors
‣ AvalancheImagineBundle - image manipulation
‣ KnpPaginatorBundle
... and many more...
Thursday, August 18, 11
39. Act 5:
Playing with Behat
http://behat.org
Thursday, August 18, 11
40. What is Behat
• Behat is a tool that lets you focus on
developing to the intended behavior of your
application
• You write scenarios that describe the behavior
of the features needed, which are then executed
as tests against your application
Thursday, August 18, 11
41. Example Behat Feature
Feature: Registration
In order to have an account with the system
As an unauthenticated user
I can register for a new account
Scenario: Navigate to the registration page
Given I am on "/"
When I follow "Register"
Then the response status code should be 200
And the "h1" element should contain "Register"
Thursday, August 18, 11
42. Installing Behat
• To use behat to test the functionality of your
application, you’ll need to install both Behat and
Mink
• Behat is a command-line executable that you
install via pear
• Details: behat.org
Thursday, August 18, 11
43. Installing Behat
• To use behat to test the functionality of your
application, you’ll need to install both Behat and
Mink
• Behat is a command-line executable that you
install via pear
pear channel-discover pear.behat.org
pear channel-discover pear.symfony.com
pear install behat/behat
pear install behat/mink
Thursday, August 18, 11
44. Integrating into your project
• To use Behat and Mink in your project, install
BehatBundle and MinkBundle
1. Add the deps file
2. Configure the autoloader
3. Enable the bundles
4. Configure the bundles
5. Start describing your features!
http://bit.ly/mink-bundle
Thursday, August 18, 11
45. Behavior-Driven Development
• Remember that the goal of Behat is to let you
describe the behavior of your application as
human-readable sentences
• This allows you to describe the behavior of
each feature in a common language, which is
executed as tests against your application
• Develop a feature until the test passes,
then move on
Thursday, August 18, 11
46. registration.feature
Describes your feature, but This “format” is called
not executed by Behat “Gherkin”
Feature: Registration
{ In order to have an account with the system
As an unauthenticated user
I can register for a new account
Scenario: Navigate to the registration page
{
Given I am on "/"
When I follow "Register"
Then the response status code should be 200
And the "h1" element should contain "Register"
Each Scenario is actually
executed as a test against
your application
http://bit.ly/gherkin-docs
Thursday, August 18, 11
48. Behind-the-scenes
• Behind the scenes, each line of the scenario is
executed against a collection of “definitions”
• A definition is a regular expression pattern and
a function
• When a line in your scenario matches a
definition’s regular expression, that definition is
executed
• Mink comes with a great list of
built-in definitions
Thursday, August 18, 11
50. Testing Javascript
• By default, tests are run in a “headless” or
command-line-only browser
• This means that your testing your application
as if Javascript were off
• You can also do in-browser testing by
leveraging another library called Sahi
Thursday, August 18, 11
51. In-browser testing
Feature: Registration
In order to have an account with the system
As an unauthenticated user
I can register for a new account
Activates Sahi
@javascript
Scenario: Navigate to the registration page
Given I am on "/"
When I follow "Register"
Then the response status code should be 200
And the "h1" element should contain "Register"
Thursday, August 18, 11
52. Testing Javascript
• By adding “@javascript”, the test will be run
through Sahi
• Sahi will physically open up a browser and
execute the test
• You can use headless browsers for some tests
and Sahi for others that require Javascript
functionality
Thursday, August 18, 11
54. HTTP is Simple
• HTTP is a text language that allows two
machines to communicate with each other
• Communication on the web is always a two-
step process:
1) The client sends an HTTP request
2) The server send back an HTTP response
Thursday, August 18, 11
55. HTTP Communication - from space
the request
/foo
Client
Your App
(e.g. browser)
<h1>Foo!</h1>
the response
Thursday, August 18, 11
56. The Request
• The actual request looks something like this:
GET /foo HTTP/1.1
Host: knplabs.com
Accept: text/html
User-Agent: Mozilla/5.0 (Macintosh)
Thursday, August 18, 11
57. This simple message
communicates everything
necessary about exactly which
resource the client is requesting
Thursday, August 18, 11
58. The Request
• The first line contains the two most important
pieces of information:
HTTP method URI
GET /foo HTTP/1.1
Host: knplabs.com
Accept: text/html
User-Agent: Mozilla/5.0 (Macintosh)
Thursday, August 18, 11
59. The Request
URI The unique address or location that
identifies the resource the client wants
HTTP method
The “verb” of the request: what action
you would like to perform with the
resource
Thursday, August 18, 11
60. Request Methods
Retrieve the resource
GET
from the server
Create a resource on
POST
the server
Update the resource on
PUT
the server
Delete the resource
DELETE
from the server
Thursday, August 18, 11
61. The Response
• And the response looks like this:
HTTP/1.1 200 OK
Date: Tue, 04 Jun 2011 21:05:05 GMT
Server: lighttpd/1.4.19
Content-Type: text/html
<html>
<h1>Foo!</h1>
</html>
Thursday, August 18, 11
62. The Response
HTTP Status code
HTTP/1.1 200 OK
Date: Tue, 04 Jun 2011 21:05:05 GMT
Server: lighttpd/1.4.19
Content-Type: text/html
{
<html>
Request <h1>Foo!</h1>
body </html>
Thursday, August 18, 11
63. HTTP Request-Response
• In every application, and every language, you
always have the same goal:
To read the HTTP request and create the
appropriate HTTP response
Thursday, August 18, 11
64. Request Response in PHP
• So how do you interact with HTTP requests
and responses in PHP?
<?php
$uri = $_SERVER['REQUEST_URI'];
$foo = $_GET['foo'];
header('Content-type: text/html');
echo 'The URI requested is: '.$uri;
echo 'The "foo" parameter is: '.$foo;
Thursday, August 18, 11
65. Request Response in PHP
• PHP gives you access to the HTTP request
via several “superglobal” arrays
• To create the HTTP response, use the the
header() method to set the header lines and
print content to populate the request body
Thursday, August 18, 11
66. The user sends the HTTP request...
• http://knplabs.com/testing.php?foo=symfony
<?php
// this is testing.php
$uri = $_SERVER['REQUEST_URI'];
$foo = $_GET['foo'];
header('Content-type: text/html');
echo 'The URI requested is: '.$uri;
echo 'The "foo" parameter is: '.$foo;
Thursday, August 18, 11
67. ... and PHP sends back the HTTP response
• http://knplabs.com/testing.php?foo=symfony
HTTP/1.1 200 OK
Date: Sat, 03 Apr 2011 02:14:33 GMT
Server: Apache/2.2.17 (Unix)
Content-Type: text/html
The URI requested is: /testing?
foo=symfony
The "foo" parameter is: symfony
Thursday, August 18, 11
68. Request and Responses in Symfony
• Symfony offers a Request and Response
objects that abstract the HTTP text messages
into an object-oriented format
Thursday, August 18, 11
69. use SymfonyComponentHttpFoundationRequest;
use SymfonyComponentHttpFoundationResponse;
$request = Request::createFromGlobals();
$c = 'URI: '.$request->getPathInfo();
$c .= '”foo”: '.$request->query->get('foo');
$response = new Response();
$response->setContent($c);
$response->setStatusCode(200);
$response->headers->set('Content-Type', 'text/
html')
//sets the headers and then prints the content
$response->send();
Thursday, August 18, 11
70. Thanks!
Questions?
Ryan Weaver
@weaverryan
Thursday, August 18, 11