Code Bright: Architecture

← Back to Index

This title was written for Laravel version 4. If you're looking for material on the latest version of Laravel, then please check out Code Smart.

I want to make Code Bright a more complete learning experience, and for that reason, I have decided to include this chapter. If you are busting to get started with your coding, feel free to skip it. However, I think it will be really useful down the line to learn how Laravel is constructed.

In Laravel 3, the IoC container was a component that confused a lot of people. In Laravel 4, it is the part of the framework that holds everything together. I can’t begin to express its importance. Well, actually, I need to for this chapter to make sense. Let’s give it a go.

The Container

In Laravel 4, the container gets created early during the bootstrap process. It’s an object called $app. So when we talk about a container, what comes to mind?

Let’s have a look at the dictionary definition. Why? I’m not sure... I’ve seen other authors do it though. I don’t want them to look down on me. Here we go.

Noun - Container. An object used for or capable of holding, esp for transport or storage, such as a carton, box, etc.

I think the description fits the Laravel container component rather well. It’s certainly used to store things. Let’s be honest... if it didn’t store things, then ‘Container’ would be a terrible name. As for transport, it certainly makes it easier to ‘move’ other components around the framework when we need to access them.

It’s not really a carton, or a box. It’s more of a keyed storage system.

Once the $app object has been created, you can access it from anywhere using the app() helper method. In all honesty, you probably won’t need to. This is due to a feature that we will explain later in this chapter.

Let’s get a hold of the app object and take a look at it. We can do this in our app/routes.php file.

<?php

// app/routes.php

var_dump($app);

die();

Note that we don’t need to use the app() helper within the app/routes.php file. It’s available in the global scope, so we can access it directly.

Woah, that’s a huge object! Well I guess it should be... it’s the core of the framework. You will notice that it’s an instance of Illuminate\Foundation\Application. All of the Laravel 4 components live within the Illuminate namespace. It was a codename used during the early stages of the framework’s design, and we just don’t have the heart to remove it. Think of it as Laravel “illuminating” the world of PHP!

If we take a look at the source for the Application class, we will see that it extends Container. Go ahead, you can find the source at:

https://github.com/laravel/framework/blob/master/src/Illuminate/Foundation/Application.php

The Container class is where all the magic happens. It also implements the ArrayAccess interface. This is a special interface that allows the attributes of an object to be accessed as an array in a similar fashion to that of JavaScript object literals. For example, the following two methods of accessing object attributes would both be possible:

<?php

$object->attribute = 'foo';
$object['attribute'] = 'foo';

During the bootstrap of the framework, a number of service provider classes are executed. These classes serve the purpose of registering the framework’s individual components within the application container.

So what do I mean by a component? Well, a framework is made up of many different parts. For example, we have a routing layer, a validation system, an authentication layer, and many more packages of code which handle a specific function. We call these our framework components, and they all fit together within the container to create the complete framework.

If you are a first time user of Laravel, then this next example won’t make a great deal of sense to you. Don’t dwell on it! It’s just something for Laravel 3 users to think about. Take a look at this.

<?php

// app/routes.php

$app['router']->get('/', function()
{
    return 'Thanks for buying Code Bright!';
});

Here we are accessing the routing layer within the container to create a route that responds to a ‘GET’ HTTP request. This will be familiar to Laravel 3 users, although the syntax will look a little strange.

As you can see, we are accessing the routing component using an array syntax on our container. This is the magic provided by the ArrayAccess interface. If we wanted to, we could also access the routing layer like this:

<?php

// app/routes.php

$app->router->get('/', function()
{
    return 'Seriously, thanks for buying Code Bright!';
});

Accessing the component as an attribute of our container works exactly the same as the method we used earlier.

It’s not very pretty though, is it? I mean, if you are new to the framework, you have probably heard about Laravel’s beautiful syntax. If you used Laravel 3 previously, then you have already been enjoying it.

Surely we aren’t going to ruin that reputation? Of course not! Let’s have a look at some more magic in action.

Facades

My buddy Kenny Meyers gave the original book ‘Code Happy’ a lovely review on The Nerdary. I’d love to repay the favor. He told us at the last Laravel conference that he has difficulty with the pronunciation of certain words, and I bet this one is tricky. So for Kenny, and those who don’t speak English as their first language, here’s how you pronounce Facade.

“fah-sahd”

In Laravel 3, most components were accessed using a static method. For example, the routing example in the last chapter would look like this:

<?php

// app/routes.php

Route::get('/', function()
{
    return 'Thanks Kenny, we love you!';
});

It looks beautiful... we have a descriptive name for the component, and often a verb describing the action performed on that component.

Unfortunately, experienced developers will cringe at the sight of a static method. You see, static methods can be rather difficult to test. I don’t want complicate things so early in the book by explaining why that is, so you will have to trust me.

This created a big problem during the design of Laravel 4. We love our beautifully simple syntax, but we also want to embrace coding best practice, and this includes writing many, many, tests to ensure that our code is robust.

Fortunately, Taylor came up with the wonderful idea of Facade classes, named after the ‘Facade’ design pattern. Using Facades can have the best of both worlds. Pretty static methods, yet instantiated components with public methods. This means that our code is beautiful, and highly testable. Let’s see how it works.

In Laravel 4, there are a number of classes that are aliased to the root namespace. These are our Facade classes, and they all extend the Illuminate\Support\Facades\Facade class. This class is very clever. I’m going to explain its cleverness with some code samples. You see, we can use a static routing method, just like in good old Laravel 3, like this:

<?php

// app/routes.php

Route::get('/', function()
{
    return 'Thanks for Facades, Taylor!';
});

The Facade in this example is the ‘Route’ class. Each Facade is linked to an instance of a component in the container. The static methods of a Facade are shortcuts, and when called, they call the appropriate public method of the object that they represent within the container. This means that the Route::get() method will actually call the following method:

<?php

// app/routes.php

$app['router']->get('/', function()
{
    return 'Thanks for Facades, Taylor!';
});

Why is this important? Well, you see, it offers a great deal of flexibility.

Flexibility

What does flexibility mean? I’m not going to refer to the dictionary this time. I know that it means the ability to change. That’s a rather good explanation of the benefit of the container. You see, we can change, or rather, replace objects and components that have been registered within the container. This offers us a great deal of power.

Let’s imagine for a moment that we don’t really like how the routing layer works (don’t worry, you will love it, just imagine that you don’t).

Since we are all epic coders, we’ll go ahead and write our own routing layer, with the primary class being called SuperRouter. Due to the flexibility of the container, we can replace the routing layer with our own. It’s honestly as easy as you might imagine. We just assign our router to the existing router index. Let’s see this in action. Oh, please note that I don’t recommend doing this right now, especially if you are a beginner. It just makes for a great example.

<?php

// app/routes.php

$app['router'] = new SuperRouter();

Now, not only can we use our router by accessing it directly within the container, but our Route Facade will continue to access this component.

In fact, it gets even more impressive. When you replace Laravel’s components, the framework will attempt to use your replacement component for its tasks, just as if it was its own.

Allowing access to core framework components in this way offers a great deal of power to you the user. You sure are spoiled aren’t you!

Robustness

As I mentioned a few times earlier, Laravel is made from a set of individual components. Each component is responsible for its own little bit of functionality. This means that they are very respectful of the single responsibility principle.

In fact, many of the Laravel components can act alone, completely decoupled from the framework. For this reason, copies of the components can be found under the Illuminate organisation on github. This set of components is also available on Packagist so that you can take advantage of them in your own projects that leverage Composer.

So why is the chapter called Robustness? Well you see, every component used by the Laravel framework is well tested. The entire framework contains a suite of over 900 tests and 1700 assertions.

Thanks to the tests, we can accept contributions and make changes that will provide a fruitful future for the framework, without worrying about whether a change has broken something, or removed existing functionality.

Well, that’s enough about architecture. I bet you’re ready to get stuck into some development right? Let’s get started.

My books are available online for free to encourage learning. However, if you'd like for me to keep writing, then please consider buying a digital copy over at Leanpub.com.

It's available in PDF, ePub, and Kindle format, and contains a bunch of extras that you won't find on the site. I have a full-time job, and I write my books in my spare time. Please consider buying a copy so that I can continue to write new books from the comfort of my sofa!