Building a Framework using Symfony Components – II

Building a PHP Framework using Symfony Components

This is the continuation of a previous post based on Fabien Potencier’s tutorial on creating your own framework on-top of the Symfony 2 components.

In the last lesson, we covered the first 6 parts of Fabien’s excellent tutorial. This time around, we’ll cover off the last 6 parts. So without any further ado…

Part 7 – Implementing the Model View Controller pattern

The first improvement introduced in Part 7 is to utilise namespacing for the Simplex framework. Introduced in PHP 5.3, namespaces allow us to better manage the interoperation of libraries by avoiding naming collisions. When writing object oriented code for PHP 5.3 and above it’s highly recommended that you utilise namespaces as a best practice.

To start off with, we move the Framework class into the Simplex namespace, so its fully qualified name is now Simplex\Framework:

The next step is to formally create our Model and the primary Controller for the Calendar application. Because these are separate to the framework, we’ll add them to their own namespace, which we’ll call Calendar. For consistency, we can also break these further into Calendar\Controller and Calendar\Model to prepare for the growth of our application.

When we’re finished, we have:

In the process of making these namespace declarations, we also need to adjust the file structure of our project so that the autoloader will be able to find the required resources. When we’re finished, what we have should look like the following:

  • /vendor : third-party libraries managed by Composer.
  • /web : any files that need to be publicly accessible, such as the front-controller, JavaScript, stylesheets and images.
  • /src : the files that implement your web application.
  • /src/Simplex : files for the Simplex framework.
  • /src/Calendar : files for the Calendar namespace.
  • /src/Calendar/Controller : the controller code for the leap year web application.
  • /src/Calendar/Model : the model(s) for the web application.

Resources: The code, the full lesson

Part 8 – Adding Unit Tests

Now that the framework is starting to get quite large, it’s time to add Unit tests into the mix. This will enable us to continue to extend and develop the Simplex framework with the knowledge that our automated unit tests will prevent us from introducing bugs into our code.

The first thing to do is to change our core framework functions so that they work using “mockable” interfaces instead of concrete class implementations. See the example below:

Assuming we have PHPUnit set up, we can then define our tests in the tests/Simplex/Tests/ folder. An example is shown below:

Resources: The code, the full lesson

Part 9 – Extending the framework using Events

At the moment, if we want to add functionality to the Simplex framework, the only way to do it is to touch the core library code. Wouldn’t it be great if instead of editing the core code we could just “tell” Simplex when we wanted to intervene during the request handling process, perform our desired action(s) and then return execution to the framework? That’s precisely what we can do using the Symfony 2 Event Dispatcher component.

The Event Dispatcher gives us a centralised way to specify functions that are “interested” in certain actions occurring within the application. It’s up to us to register the functions as well as telling the dispatcher when an event has occurred.

For example, we can define a function that gets called when an event named response occurs. The function expects that the HTTP Response object will be provided at runtime, and it will add a HTML comment to the end of the response body when invoked. This would look as such:

Of course this code alone won’t do anything. We need to tell the event dispatcher when the event is occurring, which is shown in the Framework class below:

Resources: The code, the full lesson

Part 10 – Leveraging the HttpKernel Component and Caching

The Symfony HttpKernel provides us with a set of tools for building web based applications. It provides the kernel of a web framework, including a fully abstracted request-response life cycle, support for routing, lazy-loading of controllers, events and much more. We can leverage these features by adding the HttpKernel component to the project using our composer.json file and then changing the core Framework class to implement HttpKernelInterface as depicted below:

As we can see from the interface of the handle(...) function, the basic purpose of the framework is to handle an incoming HTTP request by generating a HTTP response. It’s hard to see what immediate benefit we get from implementing the HttpKernelInterface – aren’t we still doing the same thing? Essentially, yes, but because we’re implementing an interface instead of creating our own free-standing class, the internals of the HttpKernel class know how to interact with our framework code.

So if we want to add server-side caching, for example, it’s as easy as this:

Resources: The code, the full lesson

Part 11 – Embracing the HttpKernel

Instead of implementing the HttpKernelInterface in our framework code, what we can choose to do instead is actually use the concrete implementation of the kernel that comes with the component. This means we can strip out a lot of the code we’ve written to handle servicing the request, but it does mean we need to conform to some conventions in order for pre-rolled HttpKernel to work.

To start off with, we change the core framework file to the following:

Now we just need to modify our front controller to make sure it utilises the HttpKernel according to its interface:

… and that’s it!

As with the caching example, the benefit of doing this isn’t immediately available until we see what kind of additional functionality this gives us access to. For example, this implementation of HttpKernel provides us with events for different actions throughout the request-response life cycle. It also provides base classes for different kinds of handlers that can be used listen for these events. Using these two pieces of information, we can easily create a function that will handle exceptions thrown during the request handling process:

… and then attach it to the dispatcher as such:

Resources: The code, the full lesson

Part 12 – Inversion of Control via Dependency Injection

As software systems grow, certain design patterns than made sense initially can start to be cumbersome, ineffective or unscalable. In a web framework we notice this particularly when deciding how to manage dependencies between different classes and libraries.

We can manage the dependencies in the front controller by creating instances of singleton objects in “global” scope, injecting references via the constructors:

… but this introduces bloat in what should be a very simple file. The front controller should be application specific – it feels like we’re implementing too much of the framework in the front controller. Alternatively, we could move these dependencies into the framework code:

… but this just moves the problem into a different place. It also adds some other problems: if we want to customise events or the routing mechanism, we have to touch the framework code.

A possible solution to both of these problems is to introduce the concept of a dependency container. When implementing this pattern, we utilise a dedicated object to keep track of the classes that will be used for different contexts (routing, dispatching events) and specify what the dependencies of each of these classes are. Then at runtime instead of directly instantiating classes, we “ask” the container to give us a reference to an instance of the class that we want.

In the code below, we define the context and matcher classes, and register matcher as a dependency of context:

We can then get access to an instance of the matcher at runtime using the following:

$sc->get('matcher');

This is the core principle of dependency injection. It’s a fundamental change in the way we write web applications, but it provides a great deal of flexibility.

Resources: The code, the full lesson

Conclusion

This draws us to the end of the our summary of Fabien’s marathon 12 part tutorial on building your own framework. If you’ve stayed with us this long, congratulations! We highly recommend you work through the original exercises. Fabien’s tutorial is one of the best (advanced) PHP tutorials out there, and will definitely help you take your programming and architecture skills to the next level.

Until next time!

Building a Framework using Symfony 2 Components

Build your own Framework using Symfony 2 Components

This post is based on the excellent 12-part tutorial by Fabien Potencier, the creator of Symfony, on how to build your own framework on-top of the Symfony 2 components.

If you have the time, I highly recommend you work through all of the lessons in their original form. With that said, this post aims to provide a summary of what you’ll learn in each section, as well as a link to the completed code after each exercise. This will make it a breeze for you to work out what parts of Fabien’s original 12-part series are relevant to you without having to work through all of them.

I’ve created a repository on GitHub that contains the code used throughout the tutorial, tagged at the end of each exercise. This post will cover the first 6 of the lessons, and will be followed by another post summarising the last 6. So, let’s get started!

<br/><br/>

Part 1 – Installing Composer for Package Management

In the first lesson, we set-up the folder for our new web framework which we’ve named Simplex. We’re using a package manager named Composer, which will help us to define and manage the dependencies of our framework. Because we’re going to be building on-top of the Symfony 2 core components, this is handy as Composer will enable us to easily manage which versions of the third-party libraries our framework is compatible with.

The two key tasks in this lesson are: to install the Composer library and to create our manifest file, ‘composer.json,’ which is where we’ll manage library dependencies. The manifest file for Part 1 (obviously as our framework expands, so will its dependencies) can be seen below:

View the code on Gist.

Resources: The code, the full lesson

Part 2 – Using the HTTP Foundation classes

The basic model of a web application can be stated as: a system that maps “requests” to “responses.” In any object oriented design for such a system it would make sense to define objects that represent these “Request” and “Response” types, but in PHP this is not the case. The Symfony 2 HTTP Foundation component alleviates this shortcoming by providing an object oriented abstraction layer over the HTTP protocol.

Using this library, we can manipulate HTTP Requests and Responses as such:

View the code on Gist.

This introduces interesting possibilities, such as giving us the ability to “mock” HTTP interactions for testing purposes.

Resources: The code, the full lesson

Part 3 – Utilising the “Front Controller” design pattern

When designing web applications, typically we want to be able to handle requests for resources internally instead of letting the web server decide what to do with requests for different URLs. The front controller design pattern enables us to do this by providing a single entry-point for all requests throughout our application.

The first step in implementing a front controller is to separate our application into different folders. For Simplex, we’re going to use the following folder structure:

  • src/ : this is where the source code for our application will go (NOT publicly accessible)
  • vendor/ : any third-party libraries
  • web/ : the web folder will be used to house anything that needs to be accessible from the web server, including assets and our front controller

Our front controller, named “front.php”, contains the following:

View the code on Gist.

Resources: The code, the full lesson

Part 4 – Mapping URLs with the Symfony 2 Routing component

In the current version of Simplex, handling URLs is very messy. We can tidy this up significantly by using the Symfony 2 Routing component which provides a set of powerful tools for mapping URLs to functionality within our application.

We can define routes and then test the current Request to see if it matches any as follows:

View the code on Gist.

Resources: The code, the full lesson

Part 5 – Introducing Controllers

Including a different file based on the request URL to implement the control and business logic of our application works for smaller projects. As our application expands, however, it becomes messy and the need for a more elegant solution arises. We can achieve this by using programming constructs (functions or methods) to execute the behaviour instead of doing it directly in a PHP file. The HTTP Routing class used in Part 4 can enable us to do this:

View the code on Gist.

At the end of Part 5 a new application is introduced that will be used throughout the remainder of the tutorial.

Resources: The code, The new application code, the full lesson

Part 6 – Using The HTTP Kernel Component

In Part 6 we introduce the Symfony 2 HTTP Kernel into Simplex as a dependency. The Kernel gives us access to a range of functionality, including easy lazy-loading for Controllers, a pre-rolled framework interface, build-in events raised at useful points throughout the standard request processing lifecycle and much more. We could implement these features ourselves, of course, but why re-invent the wheel?

Using the HTTP Kernel’s Controller Resolver, our routing code now looks like this:

View the code on Gist.

Resources: The code, the full lesson

Until Next Time!

That concludes the summary of the first 6 parts of Fabien’s tutorial on building your own framework. Stay tuned for the next part in this series.

Securing your web application with Symfony

Dilbert cartoon on security

Introduction

As a web developer, securing your web applications is one of the most important and complex tasks you’ll regularly undertake. You may need to use some security mechanism to make sure the visitor has valid credentials (authentication) within the domain of your application. You may additionally need to check to make sure that the individual user has permissions that enable them to perform certain actions within your application (authorisation).

Implementing this functionality can be complex because it typically touches many different parts of your application. You may have “public” areas with no authentication required but then other sections of the application that do require authentication. Additionally, some parts of the application may require authentication and then also require that the user account have some special permission in order to access or perform it.

Symfony 2 is designed with security in mind. It comes with a powerful authentication and authorisation framework out-of-the-box – all we need to do is to set it up and configure it for our particular use-case.

The Process

When using Symfony’s security framework, we apply authentication and authorisation rules based on URL patterns. The sequence of events is as follows:

  1. The user tries to access a URL that is “secured.”

  2. The Symfony security framework triggers the authentication scheme. Based on the settings this may be form-based log-in, a HTTP basic dialog prompt, OAuth via Facebook / Twitter / etc. or some other method.

  3. Once the credentials are submitted, the security framework tries to authenticate the details against a repository of users. This repository may be in the form of a hardcoded configuration file, a database or a third-party service (again, depending on the configuration).

  4. If authentication passes, the request is re-tried with the identity of the user in-place. Note that the user may still be denied access at this point if we’re using role-based access control.

We configure security settings for different parts of our application by setting up firewalls.

Firewalls

Firewalls are sets of rules that we can create to tell the Symfony security system how certain parts of the application should be treated in terms of authentication / authorisation. Each firewall has a pattern associated with it, which is a regular expression. If the current URL for a request matches the pattern for a firewall, the rules for that firewall are applied. An example of a firewall is provided in the “security.yml” file provided below:

# app/config/security.yml
# ...
security:
    firewalls:
        firewalled_area:
            pattern:    ^/
            anonymous: ~
            http_basic:
                realm: "Name of the realm"
# ...

Just because a URL matches a firewall doesn’t mean all URLs that match the pattern are secured. In the example above, anonymous access is allowed because of the modifier: anonymous: ~. If we want all users to be authenticated before accessing the firewalled area, we should omit this line.

For the sake of illustration in this example, we want to allow anonymous access to the top level URLs, but require authorisation for URLs under the “/admin/” folder. We do this by specifying the URL(s) that should be secured using an access control clause, as demonstrated below:

# app/config/security.yml
security:
    firewalls:
    # ...

    access_control:
        - { path: ^/admin, roles: ROLE_ADMIN }
# ...

These settings mean that only users that are authorised with the role “ROLE ADMIN” will be able to access URLs under “/admin/”.

Roles

In Symfony a “role” is a string token that represents a set of permissions for a particular user group. We can define arbitrary roles and then use them in our application. For example:

# app/config/security.yml
security:
    firewalls:
        firewalled_area:
            pattern:    ^/
            anonymous: ~
            http_basic:
                realm: "Name of the realm"


    access_control:
        - { path: ^/admin, roles: ROLE_GRANDPOOBAR }
# ...

In the example above, URLs under “/admin” will only be accessible by those with the role “ROLE GRANDPOOBAR.” We can even define hierarchical role relationships in our “security.yml” file using the following syntax:

# app/config/security.yml
security:
    role_hierarchy:
        ROLE_ADMIN:       ROLE_USER
        ROLE_GRANDPOOBAR: ROLE_ADMIN
        ROLE_GOD: [ROLE_GRANDPOOBAR, ROLE_SUPERUSER]
#...

In this example, giving someone the role of ROLE ADMIN means they also can access any actions that require the ROLE USER. Also note that users who have ROLE GRANDPOOBAR can do everything that those with ROLE ADMIN can, which (because of the role hierarchy) includes everything ROLE USER can do. We can also specify multiple roles in the hierarchy using the array syntax shown above for ROLE GOD.

User Providers

There is, however, one important thing we haven’t discussed yet. How do we actually specify where the Symfony security framework will pull user credentials from? This is where “User Providers” come in. A User Provider is a class that implements the UserProviderInterface interface, which includes functions for interacting with a repository of Users.

Out of the box, Symfony provides a default “in_memory” User Provider which enables us to hard-code credentials into the configuration files. We can use this method using the following syntax in “security.yml”:

# app/config/security.yml
# ...
    providers:
        in_memory:
            users:
                thomas: { password: tomspass }
                ryan:  { password: secret, roles: 'ROLE_USER' }
                admin: { password: topsecret, roles: 'ROLE_ADMIN' }
# ...

This particular example creates three users, thomas, ryan and admin, two of which have roles applied.

Password encoding

If you’ve developed a security system for a web application before, the code snippet above should worry you slightly. One of the cardinal rules of web security is that passwords should not appear in plain text – ever. Symfony’s security framework has you covered here as well, as it enables you to use “encoders” to transform plain text passwords into hashes.

If you haven’t used hashing before, the core idea is that we use a “hashing function” to encode a plain-text string into a random-looking sequence of characters. We store the password in this “hashed” format so that if an attacker does gain access to our database, they don’t have access to the original plain text version of our users’ passwords. Hashing algorithms typically fulfil the following criteria:

  • The same input always yields the same output.
  • A small change in the input string should yield a large change in the output hash.
  • It should be mathematically difficult to “guess” the input string given the output string.

When a user tries to log in to our application, we take the supplied password, apply the hashing algorithm and then compare it to the entries in our database. Because of the first criteria in the list above, if the password is correct it will match the hash we have saved in the database.

So how do we set the hashing scheme in Symfony? Once again, we use the configuration file…

# app/config/security.yml    
security:
    encoders:
        MyCompany\BlogBundle\Entity\User:
            algorithm:        sha1
            encode_as_base64: false
            iterations:       1
# ...

This configuration will hash passwords using the “SHA1″ algorithm, and it will apply the algorithm once. If we are to use the “in_memory” User Provider, the entries should now become:

# app/config/security.yml
security
# ...
    providers:
        in_memory:
            users:
                thomas: { password: 00ec36bbda403aaf23a2eff34964f54239d22e5c }
                ryan:   { password: e5e9fa1ba31ecd1ae84f75caaa474f3a663f05f4, 
                          roles: 'ROLE_USER' }
                admin:  { password: 12201fe5e202883bd45fc97e87366ea05183e0e4, 
                          roles: 'ROLE_ADMIN' }

    encoders:
        Symfony\Component\Security\Core\User\User:
            algorithm:        sha1
            encode_as_base64: false
            iterations:       1
# ...

Using the Database as a User Provider

Using the method described above, we can now hardcode user credentials into our “security.yml” file. But this isn’t what we typically want to do in our web applications. Instead, we typically want to use dynamic user accounts that can be added, deleted and modified as required. So typically we’ll use a database to maintain our list of user credentials. In order to use the Symfony security system with our database, we need to implement a custom User Provider.

We need to do two things to make this happen:

  1. Define a custom user entity in our model that implements UserInterface.
  2. Create a class to interact with the user repository that implements UserProviderInterface.

The User Interface

You’ll notice the fieldname “salt” mentioned above. If you haven’t seen this before, the salt is just a random string we add to the password before applying the hash. We usually use a timestamp or randomly generated alphanumeric value. For more information on hashes and salting, I recommend reading this great article.

The User Provider Interface

You’ll notice that the function signatures of UserInterface and UserProviderInterface implemented above are actually agnostic in terms of the source of the data. This means that we can just as easily create a User Provider that uses OAuth, LDAP or some other scheme to authenticate the user.

Implementing the User and User Repository for Database Storage

The first thing to do if we want to use a database to store our user accounts is to create the User entity in our Symfony application. The easiest way to do this is by using the command line utility. For ease of implementation, we’ll create a very basic User type that only has the fields id, username, email, password and salt. Run this command from the base-level of your Symfony folder:

$ php app/console doctrine:generate:entity

… and create an entity, MyCompanyBlogBundle:User with the following fields:

  • username string (255)
  • email string (255)
  • password string (255)
  • salt string (255)

To make things easier later, make sure you enter “YES” to the question “Do you want to generate an empty repository class?.” This will create two files for us:

src/MyCompany/BlogBundle/Entity/User.php
src/MyCompany/BlogBundle/Entity/UserRepository.php

Open both of these files and change them to the following:

Now that we’ve defined a custom User and User Repository type, we need to tell the Symfony security framework to use this for authenticating and authorising users. We do this using the “security.yml” file:

security:
    encoders:
        MyCompany\BlogBundle\Entity\User:
            algorithm:        sha1
            encode_as_base64: false
            iterations:       1

    providers:
        users:
            entity: { class: MyCompanyBlogBundle:User, property: username }

    firewalls:
        admin_area:
            pattern:    ^/admin
            http_basic: ~

Now if we try and navigate to any page under the “/admin” path, we’ll be presented with a HTTP basic prompt requesting our username and password. The provided details will then be authenticated using our User and UserRepository classes defined above.

There is one last piece of the puzzle, and that is making the prompt to accept visitors’ usernames and passwords a little “nicer.” After all, not many websites use the standard HTTP basic dialog box anymore. The way we do this is by defining a “form-based” login. We’ll discuss that in the next article.

Conclusion

After reading through this tutorial you should be ready to start using Symfony’s security framework in your web applications. But that isn’t the end of it – the security framework includes a lot of features not discussed in this article. To find out more, check out the official Symfony documentation.

Models made easy with the Doctrine ORM

Doctrine ORM logo

Most web applications like to persist things, and as a web developer, you’re going to be spending a good portion of your development time pulling things in and out of databases.

If you’ve worked on more than a couple of projects, you know how quickly interfacing with your database becomes a bore. Especially if you’re dealing directly with SQL, the code that persists or retrieves your objects is usually verbose and repetitive. And if you think about it you’re really doing the same thing many times over: creating, reading, updating and deleting data with some sanitisation and error checking thrown in around the edges.

Luckily, Symfony comes bundled with an Object-Relational Mapper (ORM). An ORM provides a set of classes that map the generic datatypes from a programming language into their relational database counterparts. Using an ORM, we can automatically generate the code that we need to persist and retrieve PHP objects to a relational database.

Note: this article assumes that you’ve already configured the database for your Symfony installation.

Enter Doctrine

The ORM included in Symfony is called Doctrine, and without mixing words, it kicks arse. Using Doctrine we can either define our model and then generate the classes and database schema to implement it, or we can go the other way and introspect an existing database, generating the PHP classes required to access it. Boom.

Doctrine also provides loads of advanced features for things like complicated foreign key relationships, special field-types (timestampables, sluggables, etc), fixtures, migrations and much more.

Creating Doctrine Entities from the Command Line

Generating our models with the Symfony-Doctrine tag team is incredibly easy. From the command line (assuming you’re in the base folder of your Symfony project) we can run the following command:

$ php app/console doctrine:generate:entity

We’ll then be placed in an interactive mode with the Symfony command line interface (CLI) which will ask us for the information it requires to generate the model class. These questions include:

  • The “entity shortcut name.” This will be in the format [BUNDLE]:[ENTITY NAME], ie: MyCompanyBlogBundle:Article
  • The configuration format. This sets the file format that will be used to keep track of the entity’s definition. PHP annotation is the default (and I tend to stick with this).
  • The fields. Now the CLI will ask us to enter the names and datatypes of all the columns for our entity. This will continue until you leave the field blank and hit enter.
  • It will also ask us if we want to create an “empty repository class.” The default is no, but I recommend selecting yes. We’ll see the DoctrineRepository object later, but creating an empty instance of this will allow us to define our own methods to search the database.

This will then create the class that represents the entity. Note that we can also speed up the interactive CLI process by providing some of the values as command arguments. For example:

$ php app/console doctrine:generate:entity \
--entity="MyCompanyBlogBundle:Article" \
--fields="title:string(255) description:text"

And here’s the class that will be generated:

Simple, right? So simple that you would think you could write this class without using the command line tool – and you’d be right. But before we get too far ahead of ourselves, let’s look at this class in a little more depth.

The most important thing to notice is that this class looks really simple. A little bit too simple. And that’s because a lot of the magic is not actually occurring in the code, but in PHP annotations in the comments. For example, notice this section at the top of the file:

/**
 * Acme\BlogBundle\Entity\Article
 *
 * @ORM\Table()
 * @ORM\Entity
 */

This is letting Doctrine know that we’re defining a new table, and that the table is going to represent an entity. There are also a number of sections where we define the fields in the database which, funnily enough, match up with the information we provided in the configuration process. These look similar to the following:

/**
 * @var string $title
 *
 * @ORM\Column(name="title", type="string", length=255)
 */
private $title;

As you can see all the metadata about our columns is represented in the annotations, including the name of the field in the database, its type and any other relevant information. One thing you may have noticed is that Doctrine added something for us:

/**
 * @var integer $id
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

If you don’t explicitly define a primary key for your entity, Doctrine is nice enough to create an autoincrementing integer field for you. Great! Except for one minor thing… If you actually try and use this class anywhere in your code, you’ll notice it doesn’t actually work. Damn.

Updating the Database

So far we’ve only built one side of the bridge: the PHP classes. The next step is to build the other side of the bridge across the gaping chasm of modellessness so they meet in the middle. That construction process is surprisingly simple, thanks again to our good friend Doctrine. From the command line, we can type the following to force Doctrine to go and work its magic on the database:

php app/console doctrine:schema:update --force

Note

9 times out of 10 you’re going to get a big scary error message at this point about DateTime::__construct(). This is basically just complaining that you haven’t adjusted your timezone correctly and should do so in your “php.ini” file. To fix this, open the local “php.ini” file and add the declaration:

date.timezone = "[YOUR TIMEZONE]"

Where [YOUR TIMEZONE] is a valid value from here. Can’t find your “php.ini” file? Create a blank PHP file with a call to the phpinfo(); function in it. Navigate to it and you’ll see the .ini path under “Loaded Configuration File”.

Putting it all together

Now we have our PHP classes and we’ve generated our database schema, it’s time to get them talking. Let’s create two basic actions within a controller called “MyCompanyBlogBundle:Post.” One will display a basic form, the second will create an entry in the database based on the form values. We’ll also define a index page that will display a given article based on its ID.

Here we go! Be sure to read the comments for an explanation of the code – this is our controller:…

… and our two view files:

Conclusion

That is a lot of information to digest for one lesson!

You should now be able to build and use basic entities within your Symfony applications. This is incredibly powerful, especially when coupled with Symfony’s powerful Form and Validator frameworks, which will be explored in later lessons.

For now, check out the Symfony and Doctrine documentation sites for more information.

Creating Forms with Symfony

As a web developer, forms will either be your favourite thing or the bane of your existence (and sometimes both). But the reality of the situation is that in order to get data from users into your application, you’re probably going to be using a lot of forms. Symfony, being the smart framework that it is, understands this and provides us with a comprehensive framework to help us build and work with forms.

Flow of Control

The standard flow of control in any form-based interaction typically involves two steps: the display of the form and the post-back.

The display of the form occurs when the user navigates to the page and can view and edit the form. Once the user submits, the post-back sequence begins. In the post-back sequence, the user’s input is validated, application and/or model state may be updated and then the user is redirected to another location within the application.

So how do we handle this sequence of events in Symfony?

Form display

The diagram below depicts the first stage of the process: the display of the form.

Step 1 in the Form filling process

  • Controller builds a form using the FormBuilder class and passes it on to the view.
  • The template renders out the form elements.

Post-back

After user has filled out the form and hit the submit button, the next stage of the process (post-back) occurs.

Step 2 in the Form filling process

  • The form is POST’ed back to the same controller
  • The controller has form handling code wrapped in a “if ($method == ‘POST’)” block.
    • The controller “binds” the POST’ed values to the form. Because this is a new request, the form that we create in the controller is going to be empty. Binding the form fills it in with the POST’ed values.
    • The controller validates the form.
    • If validation passes, the data in the form is persisted to the database.
  • The user is redirected.

The Form object

As you can see in the diagrams above, Symfony builds an internal representation of your form in the controller. This form object is then passed to the view, which uses it to build the HTML for the form. So what does the form object look like, and how can we use it?

The part of the controller that does the heavy lifting in generating the form can be seen here:

$form = $this->createFormBuilder()
    ->add('title', 'text')
    ->add('body', 'textarea')
    ->getForm();

We use a call on the controller object ($this) to get access to an instance of the FormBuilder class. Using this instance, we add variables that we would like form fields for. The parameters supplied to add define the field that will be created. We can supply 3 parameters:

  • The name of the field.
  • The type of the field (optional). For a list of the available types, check out the official documentation.
  • An array of configuration options (optional).

Finally, we create the form by calling getForm() on the form builder. We can then pass the form on to the view using the return value of the controller:

return array('form' => $form->createView());

The view then uses this variable to render the form. We can see this in the template code below:

We can see that the form elements are being individually rendered using the properties of the FormView object passed to the template from the controller. In this particular example, each field has been broken into three elements:

{{ form_label(form.title) }}
{{ form_errors(form.title) }}
{{ form_widget(form.title) }}

If we don’t want to specify each individually (label, error and input element), we can also use this shortcut:

{{ form_row(form.title) }}

Or, if we just want to let Symfony render the whole form for us without individually placing fields:

{{ form_widget(form) }}

Substituting this into our template, the code becomes:

Persisting Data from our Form

Now we can display a form in our web application, it’s time to look at how we can actually use the data posted back from the user. We do this by “binding” the postback to the form and then using the “getData()” method. See below:

Moving Forms into separate classes

This is well and good for small, simple forms. But what about a form for a sign-up form? Or if we need multiple forms on the same page? Generating the form inside the controller code quickly becomes messy and, as it is closer to view than controller code, bad practice. Symfony solves this problem by allowing us to create Form classes. By doing this, all the information about fields and their properties is stored in a separate class that can then be referenced in the controller.

And how do we go about utilising this? Glad you asked…

Now that we’ve defined this form, we can use it in our controller:

CSRF Protection

One of the best things about the Symfony forms framework is that it protects us from cross-site request forgery attacks by default. It does this by inserting a unique token into each form in at hidden field. The field is then validated on post-back to make sure the request came from a Symfony-generated form.

Conclusion

You should now be able to create, embed, parse and persist forms using the Symfony Forms framework. Congratulations! For more information check out the Symfony official forms documentation. Stay tuned for more tutorials on advanced forms-usage, including validation and custom field-types.

Symfony does Validation

Xkcd on data sanitisation

Since the beginning of computing the single most error-prone and unreliable component of the system has been something that isn’t really part of the system at all. Talk to anyone who’s worked in tech support and they’ll tell you the most common problem when troubleshooting computer malfunctions: operator error.

Humans are fallible, especially so when trying to communicate their intentions to a piece of complicated technology. As well as this, some humans are malicious, and may wish to intentionally enter unexpected data into an application to cause it to function outside of normal operating conditions. As a result, it’s important that we validate and sanitise the data that users enter into our web applications, and Symfony can help us with this.

How does it work?

Symfony’s validation framework allows us to add constraints which limit the possible values that data moving through our model may have. These constraints are statements about variables in our Entity classes that must hold to be true, otherwise validation of the class will result in an error state. Some examples of the kinds of constraints we can impose include:

  • $name is not blank
  • $title is at least 3 characters long and at most 255 characters long
  • $modifiedAt is a date
  • $age is at least 18
  • and many more…

Symfony implements constraints using “assertions.” We apply one or more assertions to properties of our entity classes, and then after adding data to an instance of the class we can check whether or not the assertions hold. If not, we can alter the flow of control through our application to display an error message, forward the user to a different page or take some other course of action.

Defining constraints

We can define our constraints using a number of different methods.

  • In a YAML file (this is the default method).
  • Using PHP annotations.
  • In an XML file.
  • In a PHP file.

We can change the configuration method that is utilised by editing the file:

# app/config/config.yml
framework:
    # eg: use PHP annotations
    validation: { enable_annotations: true }

As you can see we’ve selected annotations in the configuration file above. Personally this is my preferred option, and the one we’ll use for the rest of the tutorial.

We can now define our constraints by adding assertions to the different properties of our entity classes, as illustrated below:

Here we can see the “not blank” assertion, which will cause the validation to fail if the $title variable is blank (null or the empty string). We have access to a wide range of validators like this for different datatypes; a full list of the possible assertions can be found at the official documentation.

Now that we’ve added this constraint to the entity, we can check it using a validator.

We’ll now have a nice and simple array of all the validation errors based on the data set in $article and the defined constraints. But of course this is an overly simplistic example. We usually don’t interact with validators by making the call to $this->get(‘validator’) directly. Instead, we normally use the validators in the context of defining and using forms, which is what we’ll look at next.

Using Validators with Forms

Of course the most obvious use-case for validators is making sure that data entered by users via a form fits the constraints which we (at least should) have defined when we created our model classes. We can do this using the combination of a custom form class, an entity class and assertions. See the controller below:

The first thing to notice is that when we create the form, we use custom form class ArticleType() and pass in an instance of the Article entity:

$form = $this->createForm(new ArticleType(), $article)

Obviously when the form is first displayed we won’t have any data to validate, so for the first stage of the form-filling process, we don’t need to do anything else apart from forward the form object to the view for rendering (not shown in the code sample above).

When the form is posted back, however, the situation changes somewhat. After checking is this is a postback, we need to take all of the variables supplied in the post data and apply them to the form object so the fields inside the instance of the form are populated. We do this using a call to ->bindRequest, as you can see below:

$form->bindRequest($request)

Finally, it’s time to check that the bound values are “valid” based on the assertions we’ve defined in the entity. We do this using a call on the form:

if ($form->isValid()) {
    ...
}

(Non-controversially) this method will return ‘true’ if all the assertions pass, and false otherwise.

All together now

Now that we’ve seen the general workflow for validating a form, here’s an example of a form class, an entity class, a view and a controller all working together to validate user input.

So let’s get started! This is the entity we’ll use, complete with assertions:

It’s important to note the uses statements at the top of the class – without these the assertions won’t work! Also note that we’re making some UniqueEntity assertions at the class level – these ensure that the same username and email address are not entered more than once.

A quick disclaimer: this implementation is incredibly insecure and only for the purposes of illustration. Passwords should never be stored in plaintext in the database! With that in mind, let’s continue…

Here’s the UserType class that is used to generate the form:

This is quite straight forward, and most of the heavy lifting can actually be done using the command line interface. If you’ve already created the entity class, you can get Symfony to generate the form using the following:

$ php app/console doctrine:generate:form MyCompanyBlogBundle:User

You will notice one important thing though: the ‘password’ field has a second parameter. This is because the field, being a string, will default to a standard ‘text’ type input field. We want to override this and make it a ‘password’ type input field so the entered text is not immediately visible.

Now for the fun part. Here’s our controller:

Let’s break it down. The indexAction() function is very basic: it just pulls back all of the users from the database (or ORM layer if we want to nitpick) and sends them to the view for rendering.

createAction() is where the magic happens. If you follow the comments, you can see that we create instances of the User entity and the UserType shown above and then use them to create a Form. Control then branches based on whether this is a postback or not. If this is not a postback, we simply send the empty form to the view for rendering. If this is a postback, we bind the request parameters to the form and then run the validation ( ->isValid() ). If validation fails, we simply pass the form to the view and let it render the errors. Otherwise we use the Doctrine EntityManager to persist the User object (with the bound values) to the database, then redirect.

Of course now we need to display everything. Here are our two view classes:

Wrap up

And that’s how to use Form validation in Symfony… Phew!

It may seem like a lot of code, but the workflow really does make sense, and once you understand the conventions it truly does cut your development time down significantly while providing some very powerful features.

Still hungry for more information? Head on over to the official documentation for validation.

Templating with Twig. Fun for all* the family!

Family fun with Twig

Writing PHP and HTML together is sooo 1998 – which is why Symfony uses the Twig templating language by default. This means instead of writing ugly code like this:

… we can use this:

Much nicer. Twig not only allows us to use a “friendlier” syntax when writing our presentation layer code, but it also provides some powerful features that make it more than just lipstick for your code.

But where do Twig templates fit in Symfony?

If you’ve poked around the Symfony folder structure (or created some Symfony projects) you’ve probably come across Twig templates already. They end in a “.twig” extension, and are commonly found in these folders:

// Application-wide templates
app/Resources/views

// Bundle-specific templates
src/MyCompany/BlogBundle/Resources/views

But where do they fit into the standard flow of control in the Symfony framework? Well, let’s look inside a standard controller.

You can see the template being invoked in the return statement, where two parameters are supplied. The first is the logical name of the template, the second is the set of parameters to pass-on to the template. These parameters are then used to dynamically modify the output of the template. Next we’ll check out the tools that Twig provides for us to make writing dynamic output easy.

Using Twig Tags

Twig uses braces to separate standard text (which should simply appear in the output as-is) from code (which should provide dynamic behaviour). There are three “kinds” of braces:

{{  }} ... used to "print" variables to the output
{%  %} ... used for control structures
{#  #} ... used for comments.

With this in mind, let’s have a look at a bigger example of a Twig template…

Modifying output with Filters

Because you have such a keen eye, you probably noticed something strange about the way variables are being rendered in the snippet above. Namely this:

{{ title|raw }}

We know that the variable name is “title” and that this is passed from the controller. The token after the pipe (|) character is called a filter, and is used to modify the output of the variable before inserting it into the template. Twig provides us with a range of filters for different purposes such as output escaping, capitalisation, encoding and sorting. You can learn about all the available Twig filters here.

Blocks and Inheritance

One of the most powerful features of Twig is the use of “blocks”. Blocks enable us to define sections of the template that can be overwritten if redefined at a later point. The power of this isn’t immediately evident when dealing with single templates, but can is easy to illustrate when we consider Twig’s inheritance mechanism.

Parent template

Child template

What we can see in the two code snippets above is that the child template is adding the content from the parent but before the template is rendered, any blocks that were redefined in the child overwrite those in the parent. This is an important distinction to make, as we can also “include” other templates, as illustrated below:

So what’s the difference between extending and including? The key difference is that when extending a base template, we can change the content in the base template. When including another template we cannot overwrite any content in the parent.

Automatic template selection

At the start of the lesson we had a look at a possible way that we could use to tell a controller which template to use. We did make things a little bit more difficult for ourselves in the suggested implementation of the method, as there’s an easier way to use templates with controllers, provided we stick to Symfony’s standard template naming convention. The way we can implement this (if using PHP annotations) is illustrated below.

When using the @Template annotation, Symfony will look in the src/Namespace/Bundle/Resources/view/ folder for a template that matches the name of the action and use the return value from the function as the variable scope for the template. In the case above, the template used would be:

/src/MyCompany/BlogBundle/Resources/views/view.html.twig

The end

That’s a very test-drive of the Twig templating language. The library itself is very comprehensive and includes some great features not even touched on in this brief examination. Learn more about Twig by checking out the official online documentation.

*: may not actually be fun for all family members.

Connecting everything together with Routing.yml

Connecting the dots - illustration courtesy of Hugh McLeod

In this article we’re going to talk about Symfony’s routing system. Because you’ve read our comprehensive dissection, you already know that Symfony uses a front controller (you have read it… right?). This means that all URLs are serviced by a single script – typically contained in the “app.php” file. Obviously all our application logic, data models and presentation code isn’t contained in this one file, so how does Symfony know how to locate these in order to service individual requests? That’s where routing comes in.

A single “route” defines a mapping between one or more URLs of a certain format and a controller. A Symfony application will usually have multiple routes set-up, and by default these will be configured in the following file:

/app/config/routing.yml  

Symfony also supports XML and PHP based routing files, which we can configure using the “/app/config/config.yml” file. This config file location and format are the defaults, so we’ll work with these. Personally I find the YAML format very easy to read and work with so I typically stick with it. Note that Symfony ends up parsing the routing configuration to a cached PHP file regardless of the format you use, so performance will be the same whether you use YAML, XML or PHP.

What does a route include?

  • An identifier: this is a (unique) name for the route that may be used when generating URLs for this route in controller or templating code.
  • A pattern: this is the string that the URL will be tested against. It may include “placeholder” values for dynamic URL parameters (see below for more information).
  • Defaults: this is used to specify default values for the attributes of a route. Note that the “_controller” field is *required* here to specify the controller to use. If you include placeholders in the pattern, you can make them optional by providing default values here.
  • Requirements (optional): it’s also possible to provide basic validation rules in the route. These are applied to the placeholders in the URL and will cause the route to be skipped if they do not match.

Now that we know what the standard components of a route are, we’re ready to see an live example.

Example routing.yml file

In the simple example above, we can see a few things: the name of the route is “contact”, it matches the URL pattern “/contact” and the route only responds to HTTP GET requests (so form POSTs will not match the route). The “_controller” attribute will determine where requests will be sent that match the “pattern” and “requirements” of the route. It will use the logical name of the route, so in the example above, this will resolve to the “contactAction” action in the “Home” controller in “MyCompanyBundle”.

A more complex route can be seen in the example from the official Symfony documentation provided below:

There are a few important aspects to note in this route. The first is that we’re using dynamic parameters, such as {culture}, {year}, {title} and {_format}. These values will match any value, so URLs such as these will work:

/articles/en/2012/article.html

The next important aspect to note is that we’re applying requirements to the parameters. These are regular expressions that check the following conditions:

  • “culture” is either “en” or “fr”
  • “_format” is either “html” or “rss”
  • “year” is a numerical value.

If any of these conditions fail, the route will not match.

Also, you should notice that a default value for “_format” has been provided. This means that if this parameter is omitted, its value will be set to “html” by default.

The final thing to pay attention to is the special meaning of the underscore character in the parameter names. Parameters that start with this character have special meaning. In the above example, “_controller” defines the controller and action to map the URL route to. “_format” has a special meaning as well; it defines the response type.

Parameters in controllers

But how are the parameters in URL routes actually used? Well, if you look at the definition of AcmeDemoBundle:Article:show provided below, it should become obvious:

The parameters in the routing rules end up being provided as arguments to the action referenced by the routing rule. To make things super-simple, the names of the arguments will match the names defined in the pattern for the routing rule.

Importing external routing files

Often it makes sense to define routes at the bundle level instead of at the application level (especially if you intend to repackage your bundle for other projects or public use). We can do this by referencing an external “resource” in the “app/config/routing.yml” file, as such:

Note the “prefix” value. This means the routing rules within this file will only respond to URLs beginning with “mycompany”, and all rules within the file will be prepended with “mycompany”.

Provided we’ve configured the bundle such that it refers to “/src/MyCompany/SomeBundle”, this will include the file at the following location:

/src/MyCompany/SomeBundle/Resources/config/routing.yml

Wrap-up

That should cover the basics of Symfony routing. To learn more about the routing system, check out the Symfony documentation.

Using Logical Names in Symfony

Logical (naming) illustrated... With monkeys.

The intention of Symfony is to make things easier for developers. One of the big pain points when developing large and complex web applications is keeping track of the physical location of classes, templates and assets within your project. Symfony helps us out here by providing logical names for controllers, templates and files.

Why logical names?

Logical names provide an abstraction layer over the actual storage location of resources. This means we can use a “shortcut” URL that will point to the right location (provided we adhere to the standard file and folder layout).

For example, say you wanted to specify the name of a template file to use when rendering an action in your web application. Without logical naming, we’d need to provide a hard-coded file path such as:

/src/MyCompany/BlogBundle/Resources/views/Demo/post.html.twig

With logical names, we use a shorthand version of the URL that Symfony understands. Using the logical name instead, this becomes:

MyCompanyBlogBundle:Demo:post.html.twig

This is useful because it provides a standard naming convention for all files within our project. By enforcing this standard project layout, it makes it easier for us to work with other people’s Symfony bundles as we’ll always know the correct location for templates, controllers, and so on. This is also more robust than hard-coded paths, as the Symfony engine will dynamically generate the correct URL at run-time, so we if move our project to another location or folder we don’t need to go back and update any references.

Logical Names for Controllers

Because different kinds of files (controllers, templates, assets) are placed in different locations, the logical name we use to access the resource will depend on the kind of resource being accessed. For controllers, the format we’re going to use will look something like the following:

[BUNDLE NAME]:[CONTROLLER NAME]:[ACTION NAME]

In a real Symfony application, we might use the logical name of a controller to perform a redirect. This is illustrated below:

In this case, the user would be redirected to the “show” action in the “Blog” controller for the “MyCompanyBundle” bundle.

Logical Names for Templates

Templates follow a very similar naming convention to that of the controllers. Because there may be multiple templates for a single action however, there are some slight differences. For templates, we’ll use the format:

[BUNDLE NAME]:[CONTROLLER NAME]:[TEMPLATE NAME].[URL EXTENSION].[TEMPLATE EXTENSION]

… or more generally:

[BUNDLE NAME]:[CONTROLLER NAME]:[TEMPLATE NAME]

For example, see a real-world example below where we’re using the logical name of a template to render a blog post:

As with controllers, the file and folder layout for templates is a convention when using logical naming. The example above will end up in the following template being rendered out:

/src/MyCompany/BlogBundle/Resources/views/Blog/show.html.twig

Logical Names for Files

Less commonly, you may need to directly reference files within a bundle. These will typically not be standard assets like JavaScript, images and CSS, as these are usually stored in the publicly accessible “/web” folder. If we need to access a file within the bundle, we use the following format:

@[BUNDLE NAME]/path/to/file

A possible confusion

An important thing to note when using logical names is that a bundle typical resides inside of a namespace folder, so a bundle path is typically two levels deep – not one. Referring to the examples above, the bundle is called “MyCompanyBlogBundle”, which resides in the folder “/src/MyCompany/BlogBundle”, so a call to the logical name “@MyCompanyBlogBundle” resolves to this folder. This bundle name doesn’t come from concatenating the two folder names, but from the name used when creating the bundle.

For more information on logical naming, check out the Symfony documentation.

Dissecting the Front Controller

Dissection - illustration courtesy of PBF

In this article we’re going to get our hands dirty poking around inside the Symfony 2 front controller. Scalpels ready? What’s that? A question?

What the hell is a front controller?

Oh yeah – there is that minor detail…

If you’ve worked with a few web applications in your time you’ve probably already encountered the front controller pattern. What it does is provide a single entry point into your web application. That means all requests go to the front controller, and all responses emanate from the front controller.

What normally happens with a web server is that a remote host requests a resource from it using a URL, the web server does some computation and then sends back some data. For the sake of illustration, let’s imagine you’ve written some some software that enables creative web hipsters to publish articles for all the world to see, listed in reverse chronological order. You were going to call this ground-breaking application the “web log” before you realised how much creative web hipsters like esoteric jargon, so you put the words together and dropped the first two letters.

The Normal request flow

So let’s say a visitor is checking out the incredible life-changing content you are now able to publish (thanks to your shiny new web app) and they want to read your latest article about the influence of Mongolian Throat Singing on Norwegian death metal. It’s likely they’ll type something like the following:

http://www.awesomeblog.com/articles.php?id=34

Of course if you speak HTTP (as all good web developers do, right?) you understand that this request is asking for a file on the server called “articles.php” and is providing a parameter in the query string, which is “id=34″. So what will normally happen now is that the server will retrieve and run a script saved in a file called “articles.php”, and the response will be sent back to the user. Simple.

The “front controller” request flow

The key difference between the “normal” way of handling requests and the front controller pattern is that all requests are sent to a single script, regardless of what they’re asking for. So if we were to implement a front controller – let’s call it “index.php” – what would happen is that a request for:

http://www.awesomeblog.com/articles.php?id=34

… would result in “index.php” being run. It is then up to the code in “index.php” to work out what to do and return the request, based on the URL and parameters.

… and why do we care?

So… why? Isn’t this confusing? Well, it turns out there are a bunch of good reasons for doing this.

  • Separate the routing of requests within the web application from the filesystem. This means our URL structure doesn’t need to match the file and folder structure of our web application. We can even change the URLs dynamically without having to manipulate the file system.
  • Hide the implementation details of the application. Using the old method, it’s very obvious to the user how the application is structured, as they’re directly interacting with scripts via URLs that mimic the actual file system on the server. The front controller provides a layer of abstraction over the top of this.

Symfony’s front controllers

If you’ve configured Symfony correctly, there should only be one folder in the standard distribution that is accessible from your web server: web. This folder contains assets (images, CSS and JavaScript files) and the front controller files.

Symfony uses different front controllers to define environments. By modifying the existing front controllers or creating new ones, you can customise different configurations of Symfony for different working environments, such as “test”, “development” and “production”.

The production environment

The front controller for the production environment is called “app.php” and contains the following:

These few lines of code are the heart of the Symfony engine. Let’s break it down by line.

require_once __DIR__.'/../app/bootstrap.php.cache';

The first line loads the bootstrap cache. To increase speed, Symfony aggregates a bunch of PHP classes that your application needs for every request into a single file. This means instead of having to open and parse tens or hundreds of PHP files for every request, it can just open a single big one.

require_once __DIR__.'/../app/AppKernel.php';

The next include is for the AppKernel. The Kernel implements the front controller logic, and is responsible for handling Bundle and environment management as well as the flow of control through the app.

Ignore the commented out lines for now – we’ll cover those shortly.

use Symfony\Component\HttpFoundation\Request;

Next we have a namespace declaration so we can use the ‘Request’ class, which (as the name implies) provides an object representation of the current request.

$kernel = new AppKernel('prod', false);

This line creates and sets-up an environment for us the handle the request. The first parameter provides a name for our environment, and will be used when looking up the configuration file (‘prod’ means Symfony will look for the file ‘config_prod.yml’). The second parameter determines whether or not ‘debugging’ is enabled. Obviously this will be set to ‘false’ for in the production environment.

$kernel->loadClassCache();

Is used to regenerate the PHP class cache. We typically won’t need to interact with this line of the front controller, just as long as it’s in there we’re happy.

$kernel->handle(Request::createFromGlobals())->send();

Creates a (singleton) instance of Request and dispatches it to the Kernel. The kernel will be responsible for sending it to the correct location in the app based on the routing rules.

//require_once __DIR__.'/../app/AppCache.php';
...
//$kernel = new AppCache($kernel);

These lines are commented out by default. If we uncomment them, the front controller file creates an instance of the AppCache class which is a wrapper for the kernel which enables reverse proxy caching. By doing this each request to the application will be cached. This provides an obvious performance boost, but can result in unexpected behaviour if not managed correctly. To find out more about caching in Symfony, check out the documentation.

Development environment

Symfony also comes with a “development” front controller, which creates an environment from which we can test and debug our application. It is also located in the web folder, but is named “app_dev.php”. Its contents are:

You’ll notice that the first few lines are significantly different to those in the production front controller. These check to make sure that the user is navigating to the page from localhost, as some sensitive information may be displayed in the “dev” environment that we don’t want publicly accessible if we were to accidentally deploy this front controller in the live environment.

The only other differences you’ll notice here are that the commented-out lines to enable caching are omitted (as we typically don’t want to cache when debugging) and the debug mode is enabled when creating the instance of AppKernel.

Finito

That’s it. The front controllers are small files, but without them nothing would work. After reading this you should be a front controller expert! Why not jump in and try to create your own environment from scratch by writing a custom front controller file?

For more information check out the Symfony documentation on environments.