Upload
ryan-weaver
View
27.522
Download
2
Embed Size (px)
Citation preview
Starting your newproject withSymfony2
Ryan Weaver@weaverryan
Thursday, August 18, 11
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/enhttp://www.github.com/weaverryan
Thursday, August 18, 11
Quality. Innovation. Excitement.
• Training
• Coaching / Consulting
• Fun, high-quality custom dev
KnpLabs
Thursday, August 18, 11
Act 1:
Downloading the Symfony Standard Edition
http://bit.ly/sf2-install
Thursday, August 18, 11
• 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
The “Standard Distribution”
Thursday, August 18, 11
Step 1: Get it!
http://symfony.com/download
Thursday, August 18, 11
Step 2: Unzip it!
$ cd /path/to/webroot
$ tar zxvf /path/to/Symfony_Standard_2.0.0.tgz
Thursday, August 18, 11
php bin/vendors install
• Run the following command:
• ...which should fill up your vendor/ directory
Step 3: Download the vendors
Thursday, August 18, 11
php bin/vendors install
• 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
Step 3: Explained
Thursday, August 18, 11
[symfony] git=http://github.com/symfony/symfony.git version=v2.0.0
[twig] git=http://github.com/fabpot/Twig.git version=v1.1.1
[monolog] git=http://github.com/Seldaek/monolog.git version=1.0.0
[doctrine] git=http://github.com/doctrine/doctrine2.git version=2.1.0
[swiftmailer] git=http://github.com/swiftmailer/swiftmailer.git version=v4.1.0
The “deps” file
Thursday, August 18, 11
Step 4: Check your config
http://localhost/Symfony/web/config.php
Thursday, August 18, 11
• Fix any major problems (e.g. missing libraries, permissions issues) that Symfony reports
Tend to your Garden
Thursday, August 18, 11
http://bit.ly/sf2-permsThe Docs
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
Thursday, August 18, 11
Head to the homepage!
This *is* your first Symfony2
page!!!
http://localhost/Symfony/web/app_dev.php
Thursday, August 18, 11
• 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
End of Act1
Thursday, August 18, 11
Act 2:
Storing the new project in git
http://bit.ly/sf2-git
Thursday, August 18, 11
• 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:
Version Control
git init
git status
Thursday, August 18, 11
Thursday, August 18, 11
• 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
Ignore Some Files
Thursday, August 18, 11
• 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
Ignore Some Files
Thursday, August 18, 11
Recommended “.gitignore” file
/web/bundles//app/bootstrap*/app/cache/*/app/logs/*/vendor//app/config/parameters.ini
{{
“generated”files
db config
Thursday, August 18, 11
• 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
Initial Commit
git add .
git commit -m “Initial commit of the project”
Thursday, August 18, 11
• 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
Database Configuration
Thursday, August 18, 11
• To make the creation of the parameters.ini file easy, create a parameters.ini.dist sample file that we *will* commit to git
Database Configuration
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
• The Standard Distribution comes with some sample pages inside a demo bundle
• Remove these before developing your own application
Removing demo pages
https://github.com/symfony/symfony-standard
Thursday, August 18, 11
• 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
Finishing up Act 2
Thursday, August 18, 11
Act 3:
What Symfony does...in exactly 3 slides
http://bit.ly/sf2-http
Thursday, August 18, 11
Your job: turn a request into a response
Client(e.g. browser) Your App
/foo
the request
<h1>Foo!</h1>
the response
But as your app grows, staying organized is tough, wheels are reinvented and code tends
towards spaghettiThursday, August 18, 11
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 the front controller
2) matches a route 3) executes a PHP function that you write
Thursday, August 18, 11
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
Act 4:
Creating your app
http://bit.ly/sf2-page-creation
Thursday, August 18, 11
• A standard Symfony project looks like this:
Bundles!
app/src/vendor/web/
app config - nothing too heavy
your bundles!
third-party libraries
front controllers, CSS, JS, etc
Thursday, August 18, 11
• 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...)
Bundles: first-class plugins
Thursday, August 18, 11
• Symfony can generate a nice bundle skeleton on your behalf:
Creating the MainBundle
php app/console generate:bundle
• Acme/MainBundle• MainBundle• ... enter the defaults for the rest
Answer the prompts:
Thursday, August 18, 11
Initialize the bundle
• The following was added by the task to your app/AppKernel.php file:
public function registerBundles(){ $bundles = array( // ... new Acme\MainBundle\MainBundle(), );}
Thursday, August 18, 11
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
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
http://symfony2bundles.org/
Thursday, August 18, 11
Act 5:
Playing with Behat
http://behat.org
Thursday, August 18, 11
• 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
What is Behat
Thursday, August 18, 11
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
• 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
Installing Behat
Thursday, August 18, 11
• 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
Installing Behat
pear channel-discover pear.behat.orgpear channel-discover pear.symfony.compear install behat/behatpear install behat/mink
Thursday, August 18, 11
• To use Behat and Mink in your project, install BehatBundle and MinkBundle
1. Add the deps file2. Configure the autoloader3. Enable the bundles4. Configure the bundles5. Start describing your features!
Integrating into your project
http://bit.ly/mink-bundleThursday, August 18, 11
• 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
Behavior-Driven Development
Thursday, August 18, 11
registration.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"
{Describes your feature, but
not executed by Behat
http://bit.ly/gherkin-docs
{Each Scenario is actually executed as a test against
your application
This “format” is called “Gherkin”
Thursday, August 18, 11
Thursday, August 18, 11
• 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 ofbuilt-in definitions
Behind-the-scenes
Thursday, August 18, 11
Thursday, August 18, 11
• 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
Testing Javascript
Thursday, August 18, 11
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
@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"
Activates Sahi
Thursday, August 18, 11
• 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
Testing Javascript
Thursday, August 18, 11
After dinner mint:
The HTTP Lifecycle
Thursday, August 18, 11
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 request2) The server send back an HTTP response
Thursday, August 18, 11
HTTP Communication - from space
Client(e.g. browser) Your App
/foo
the request
<h1>Foo!</h1>
the response
Thursday, August 18, 11
The Request
• The actual request looks something like this:
GET /foo HTTP/1.1Host: knplabs.comAccept: text/htmlUser-Agent: Mozilla/5.0 (Macintosh)
Thursday, August 18, 11
This simple message communicates everything
necessary about exactly which resource the client is requesting
Thursday, August 18, 11
The Request
GET /foo HTTP/1.1Host: knplabs.comAccept: text/htmlUser-Agent: Mozilla/5.0 (Macintosh)
• The first line contains the two most important pieces of information:
HTTP method URI
Thursday, August 18, 11
The Request
HTTP method
URI The unique address or location thatidentifies the resource the client wants
The “verb” of the request: what actionyou would like to perform with theresource
Thursday, August 18, 11
Request Methods
GET Retrieve the resource from the server
POST Create a resource on the server
PUT Update the resource on the server
DELETE Delete the resource from the server
Thursday, August 18, 11
The Response
• And the response looks like this:
HTTP/1.1 200 OKDate: Tue, 04 Jun 2011 21:05:05 GMTServer: lighttpd/1.4.19Content-Type: text/html
<html> <h1>Foo!</h1></html>
Thursday, August 18, 11
The Response
HTTP/1.1 200 OKDate: Tue, 04 Jun 2011 21:05:05 GMTServer: lighttpd/1.4.19Content-Type: text/html
<html> <h1>Foo!</h1></html>
HTTP Status code
{Requestbody
Thursday, August 18, 11
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
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
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
The user sends the HTTP request...
<?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;
• http://knplabs.com/testing.php?foo=symfony
Thursday, August 18, 11
... and PHP sends back the HTTP response
HTTP/1.1 200 OKDate: Sat, 03 Apr 2011 02:14:33 GMTServer: Apache/2.2.17 (Unix)Content-Type: text/html
The URI requested is: /testing?foo=symfonyThe "foo" parameter is: symfony
• http://knplabs.com/testing.php?foo=symfony
Thursday, August 18, 11
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
use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpFoundation\Response;
$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
Thanks!Questions?
Ryan Weaver@weaverryan
Thursday, August 18, 11