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.
Hey this chapter wasn’t in Code Happy!?
As a true fan of Code Happy I just can’t put anything past you! Well done loyal reader!
You see, Laravel 4 uses a number of new technologies regularly. These technologies can easily be taught on their own and parallel to the framework. With this in mind, I thought it might be best to open with a chapter about this new tech to ‘prime’ you for your learning experience.
Experienced web developers may have already come across these technologies, or have already been using them. You are welcome to skip any of the primer chapters if you want to. I won’t be upset. No really... go on. You don’t need me anymore..
If you are still reading I’m going to assume you are my friend. Not like those traitors who skipped straight to the routing chapter!
Let’s jump right in to our first primer to talk about PHP namespaces.
Namespaces
In PHP version 5.3 a new feature known as namespacing was added to the language. Many modern languages already had this feature for some time, but PHP was a little late to the scene. None the less, every new feature has a purpose. Let’s find out why PHP namespaces can benefit our application.
In PHP you can’t have two classes that share the same name. They have to be unique. The issue with this restriction is that if you are using a third party library which has a class named User
, then you can’t create your own class also called User
. This is a real shame, because that’s a pretty convenient class name right?
PHP namespaces allow us to circumvent this issue, in fact we can have as many User
classes as we like. Not only that, but we can use namespaces to contain our similar code into neat little packages, or even to show ownership.
Let’s take a look at a normal class. Yes... I know you have used them before. Just trust me on this one okay?
Global Namespace
Here’s a really simple class.
<?php
// app/models/Eddard.php
class Eddard
{
}
There’s nothing special to it, if we want to use it then we can do this.
<?php
// app/routes.php
$eddard = new Eddard();
Dayle, I know some PHP...
Okay, okay sorry. Basically, we can think of this class as being in the ‘global’ namespace. I don’t know if that’s the right term for it, but it sounds quite fitting to me. It essentially means that the class exists without a namespace. It’s just a normal class.
Simple Namespacing
Let’s create another class alongside the original, global Eddard.
<?php
namespace Stark;
// app/models/another.php
class Eddard
{
}
Here we have another Eddard class, with one minor change. The addition of the namespace
directive. The line namespace Stark;
informs PHP that everything we do is relative to the Stark
namespace. It also means that any classes created within this file will live inside the ‘Stark’ namespace.
Now, when we try to use the ‘Eddard’ class once again.
<?php
// app/routes.php
$eddard = new Eddard();
Once again, we get an instance of the first class we created in the last section. Not the one within the ‘Stark’ namespace. Let’s try to create an instance of the ‘Eddard’ within the ‘Stark’ namespace.
<?php
// app/routes.php
$eddard = new Stark\Eddard();
We can instantiate a class within a namespace, by prefixing it with the name of the namespace, and separating the two with a backward (\
) slash. Now we have an instance of the ‘Eddard’ class within the ‘Stark’ namespace. Aren’t we magical?!
You should know that namespaces can have as many levels of hierarchy as they need to. For example:
This\Namespace\And\Class\Combination\Is\Silly\But\Works
The Theory of Relativity
Remember how I told you that PHP always reacts relative to the current namespace. Well let’s take a look at this in action.
<?php
namespace Stark;
// app/routes.php
$eddard = new Eddard();
By adding the namespace directive to the instantiation example, we have moved the execution of the PHP script into the ‘Stark’ namespace. Now because we are inside the same namespace as the one we put ‘Eddard’ into, this time we receive the namespaced ‘Eddard’ class. See how it’s all relative?
Now that we have changed namespace, we have created a little problem. Can you guess what it is? How do we instantiate the original ‘Eddard’ class? The one not in the namespace.
Fortunately, PHP has a trick for referring to classes that are located within the global namespace, we simply prefix them with a backward (\
) slash.
<?php
// app/routes.php
$eddard = new \Eddard();
With the leading backward (\
) slash, PHP knows that we are referring to the ‘Eddard’ in the global namespace, and instantiates that one.
Use your imagination a little, like how Barney showed you. Imagine that we have another namespaced class called Tully\Edmure
. Now we want to use this class from within the ‘Stark’ framework. How do we do that?
<?php
namespace Stark;
// app/routes.php
$edmure = new \Tully\Edmure();
Again, we need the prefixing backward slash to bring us back to the global namespace, before instantiating a class from the ‘Tully’ namespace.
It could get tiring, referring to classes within other namespaces by their full hierarchy each time. Luckily, there’s a nice little shortcut we can use
. Let’s see it in action.
<?php
namespace Stark;
use Tully\Edmure;
// app/routes.php
$edmure = new Edmure();
Using the use
statement, we can bring one class from another namespace, into the current namespace. Allowing us to instantiate it by name only. Now don’t ask me why it doesn’t need the backward slash prefix, because I just don’t know. This is the only exception that I know of. Sorry about that! You can prefix it with a slash if you want to though, you just don’t need to.
To make up for that horrible inconsistency, let me show you another neat trick. We can give our imported classes little nicknames, like we used to in the PHP playground. Let me show you.
<?php
namespace Stark;
use Tully\Brynden as Blackfish;
// app/routes.php
$edmure = new Blackfish();
By using the ‘as` keyword, we have given our ‘Tully/Brynden’ class the ‘Blackfish’ nickname, allowing us to use the new nickname to identify it within the current namespace. Neat trick right? It’s also really handy if you need to use two similarly named classes within the same namespace, for example:
<?php
namespace Targaryen;
use Dothraki\Daenerys as Khaleesi;
// app/routes.php
class Daenerys
{
}
// Targaryen\Daenerys
$daenerys = new Daenerys();
// Dothraki\Daenerys
$khaleesi = new Khaleesi();
By giving the ‘Daenerys’ within the ‘Dothraki’ namespace a nickname of ‘Khaleesi’, we are able to use two ‘Daenerys’ classes by name only. Handy right? The game is all about avoiding conflicts, and grouping things by purpose or faction.
You can use
as many classes as you need to.
<?php
namespace Targaryen;
use Dothraki\Daenerys;
use Stark\Eddard;
use Lannister\Tyrion;
use Snow\Jon as Bastard;
Structure
Namespaces aren’t just about avoiding conflicts, we can also use them for organisation, and for ownership. Let me explain with another example.
Let’s say I want to create an open source library. I’d love for others to use my code, it would be great! The trouble is, I don’t want to cause any problematic class name conflicts for the person using my code. That would be terribly inconvenient. Here’s how I can avoid causing hassle for the wonderful, open source embracing, individual.
Dayle\Blog\Content\Post
Dayle\Blog\Content\Page
Dayle\Blog\Tag
Here we have used my name, to show that I created the original code, and to separate my code from that of the person using my library. Inside the base namespace, I have created a number of sub-namespaces to organise my application by its internal structure.
In the composer section, you will learn how to use namespaces to simplify the act of loading class definitions. I strongly suggest you take a look at this useful mechanism.
Limitations
In truth, I feel a little guilty for calling this sub-heading ‘Limitations’. What I’m about to talk about isn’t really a bug.
You see, in other languages, namespaces are implemented in a similar way, and those other languages provide an additional feature when interacting with namespaces.
In Java for example, you are able to import a number of classes into the current namespace by using the import statement with a wildcard. In Java, ‘import’ is equivalent to ‘use’, and it uses dots to separate the nested namespaces (or packages). Here’s an example.
import dayle.blog.*;
This would import all of the classes that are located within the ‘dayle.blog’ package.
In PHP you can’t do that. You have to import each class individually. Sorry. Actually, why am I saying sorry? Go and complain to the PHP internals team instead, only, go gentle. They have given us a lot of cool stuff recently.
Here’s a neat trick you can use however. Imagine that we have this namespace and class structure, as in the previous example.
Dayle\Blog\Content\Post
Dayle\Blog\Content\Page
Dayle\Blog\Tag
We can give a sub-namespace a nickname, to use it’s child classes. Here’s an example:
<?php
namespace Baratheon;
use Dayle\Blog as Cms;
// app/routes.php
$post = new Cms\Content\Post;
$page = new Cms\Content\Page;
$tag = new Cms\Tag;
This should prove useful if you need to use many classes within the same namespace. Enjoy!
Next we will learn about Jason. No, not Jason Lewis the aussie, but JSON strings. Just turn the page and you’ll see what I mean!
JSON
What is JSON?
JSON stands for JavaScript Object Notation. It was named this way because JavaScript was the first language to take advantage of the format.
Essentially, JSON is a human readable method of storing arrays and objects with values as strings. It is used primarily for data transfer, and is a lot less verbose than some of the other options such as XML.
Commonly it is used when the front-end part of your application requires some data from the back-end without a page reload. This is normally achieved using JavaScript with an AJAX request.
Many software APIs also serve content using this file format. Twitter’s own is a fine example of such an API.
Since version 5.2.0, PHP has been able to serialize objects and arrays to JSON. This is something I have personally abused a billion or so times and was a great addition to the language.
If you have been working with PHP for a while, you may have already used its serialize()
method. to represent a PHP object as a string. You are then able to use the unserialize() to transform the string into a new instance containing the original value.
It’s roughly what we will be using JSON for. However, the advantage is that JSON can be parsed by a variety of different languages, where as serialize()
d strings can only be parsed by PHP. The additional advantage is that we (as humans, and pandas) can read JSON strings, but PHP serialized strings will look like garbage.
Enough back story, let’s dive right in and have a look at some JSON.
JSON Syntax
{"name":"Lushui","species":"Panda","diet":"Green Things","age":7,"colours":["red","brown","white"]}
Yay JSON! Okay, so when I said it was readable to humans I may have forgotten to mention something. By default JSON is stored without any white space between its values which might make it a little more difficult to read.
This is normally to save on bandwidth when transferring the data. Without all the extra whitespace, the JSON string will be much shorter and thus be less bytes to transfer.
The good news is that JSON doesn’t care about whitespace or line breaks between its keys and values. Go wild! Throw all the white space you want in there to make it readable.
Sure, we could do this by hand (let’s not), but there are plenty of tools out there on the web to beautify JSON. I won’t choose one for you. Go hunting! You might even find extensions for your web browser to allow you to read JSON responses from web servers more easily. I highly recommend finding one of these!
Let’s add some whitespace to the JSON from before to make it easier to read. (Honestly, I did do this by hand. Don’t try this at home folks.)
{
"name": "Lushui",
"species": "Panda",
"diet": "Green Things",
"age": 7,
"colours": ["red", "brown", "white"]
}
Aha! There we go. We now have a JSON string representing the red panda that lives on the cover of my books. Lushui safely guards your Laravel knowledge from prying eyes.
As you can see from the example, we have a number of key-value pairs. Within one of the key-value pairs we have an array. In honesty, if you have used some JavaScript before you may wonder what’s changed here? In fact, let’s have a look at how this would be represented in JavaScript.
var lushui = {
name: 'Lushui',
species: 'Panda',
diet: 'Green Things',
age: 7,
colours: ['red', 'brown', 'white']
};
Hopefully, you will have spotted some similarities between the JavaScript and JSON snippets.
The JavaScript snippet is assigning an object literal to a variable, like this:
var lushui = { .. };
Well, JSON is a data transfer format, and not a language. It has no concept of variables. This is why you don’t need the assignment within the JSON snippet.
The method of representing an object literal is very similar. This is no coincidence! As I said before, JSON was originally invented for use with JavaScript.
In both JSON and JavaScript, objects are contained within {
two curly braces }
and consist of key-value pairs of data. In the JavaScript variant the keys didn’t require quotes because they represent variables, but we just heard that JSON doesn’t have variables. This is fine since we can use strings as keys, and that’s exactly what JSON does to work around this problem.
You may also have noticed that I used single quotes around the JavaScript values. This is a trap! That behaviour is perfectly acceptable with JavaScript, but JSON strings must be contained within double quotes. You must remember this, young padawan!
In both JavaScript and JSON, key-value pairs must be separated with a colon (:
), and sets of key-value pairs must be separated with a comma (,
).
JSON will support strings and numerical types. You can see that the value for Lushui’s age is set to an integer value of seven.
age: 7,
JSON will allow the following value types.
- Double
- Float
- String
- Boolean
- Array
- Object
- Null
Numeric values are represented without quotes. Be careful when choosing whether to quote a value or not. For example, US zip codes consist of five numbers. However, if you were to omit the quotes from a zip code, then 07702
would act as an integer and be truncated to 7702
. This has been a mistake that has taken many a life of a web-faring adventurer.
Booleans are represented by the words true
and false
, both without quotes much like PHP itself. As I said before, string values are contained within double quotes and not single quotes.
The null value works in a similar way to PHP, and is represented by the word null
without quotes. This should be easy to remember!
We have seen objects. Much like the main JSON object itself, they are wrapped with curly braces and can contain all sorts of value types.
Arrays once again look very similar to their JavaScript counterpart.
// JavaScript
['red', 'brown', 'white']
["red", "brown", "white"]
*Note You will notice that I didn’t add an inline comment for the JSON snippet in the above example. That’s because JSON doesn’t support commenting since it’s used for data transfer. Keep that in mind!
As you can see the arrays for both are wrapped within [
square braces ]
, and contain a list of comma (,
) separated values with no indexes. Once again the only difference is that double quotes must be used for strings within JSON. Are you getting bored of me saying that yet?
As I mentioned above, the values that can be contained within JSON include both objects and arrays. The clever chaps amongst my readers (aka all of you) may have realised that JSON can support nested objects and arrays. Let’s have a look at that in action!
{
"an_object": {
"an_array_of_objects": [
{ "The": "secret" },
{ "is": "that" },
{ "I": "still" },
{ "love": "shoes!" }
]
}
}
Okay. Take a deep breath. Here we have a JSON object containing an object containing an array of objects. This is perfectly fine, and will allow JSON to represent some complex data collections.
JSON and PHP
As I mentioned earlier, since version 5.2.0 PHP has provided support for serializing and unserializing data to and from the JSON format. Let’s go ahead and have a look at that in action.
Serialize a PHP array to JSON
To serialize a PHP value we need only use the json_encode()
method. Like this:
<?php
$truth = array('panda' => 'Awesome!');
echo json_encode($truth);
The result of this snippet of code would be a JSON string containing the following value.
{"panda":"Awesome!"}
Great! That’s more like it. Let’s make sure that we can convert this data back into a format that can be understood by PHP.
Unserialize a PHP array from a JSON string
For this we will use the json_decode()
method. I bet you didn’t see that one coming?
<?php
$truth = json_decode('{"panda":"Awesome!"}');
echo $truth['panda'];
Awesome! We go... wait, what?
Fatal error: Cannot use object of type stdClass as array in ...
You see, the json_decode()
method doesn’t return our JSON as a PHP array; it uses a stdClass
object to represent our data. Let’s instead access our object key as an object attribute.
<?php
$truth = json_decode('{"panda":"Awesome!"}');
echo $truth->panda;
// Awesome!
Great! That’s what we wanted. If we wanted an array then PHP provides a number of ways to convert this object into one, but fortunately json_decode()
has another trick up its sleeve!
If you provide true
as the second parameter to the function we will receive our PHP array exactly as expected. Thanks json_decode()
!
<?php
$truth = json_decode('{"panda":"Awesome!”}', true);
echo $truth['panda'];
// Awesome!
Huzzah!
So you might be wondering why I just wrote a gigantic chapter on JSON within a Laravel book. Furthermore, you are probably asking why I’m choosing to answer this question at the end of the chapter!?
It’s just more fun that way.
In the next section we will be taking a look at a new package manager for PHP. When we start looking at Composer you will understand why a knowledge of JSON is so important.
Composer
Composer is something special in the world of PHP. It has changed the way we handle application dependencies, and quelled the tears of many PHP developers.
You see, in the olden days, when you wanted to build an application that relied on third party dependencies you would have to install them with PEAR or PECL. These two dependency managers both have a very limited set of outdated dependencies and have been a thorn in the side of PHP developers for a long time.
When a package is finally available you could download a specific version and it would be installed on your system. However, the dependency is linked to PHP rather than your application itself. This means that if you had two applications that required different versions of the same dependencies... well, you’re gonna have a bad time.
Enter Composer, king of the package managers. First let’s think about packages, what are they?
First of all, let’s forget the concept of ‘applications’ and ‘projects’ for now. The tool that you are building is called a package. Imagine a little box containing everything needed to run your application, and describe it.
This box requires only one piece of paper (file) inside for it to be registered as a package.
Configuration
You learned JSON in the last chapter, right? So you are ready for this now! Remember that I told you JSON was used for data transfer between web applications? Well I lied. It’s not that I’m nasty, it just made it easier to teach the topic with a smaller scope of its ability. I do this a lot, expect many lies!
Do you remember how JSON represents a complex piece of data? Well, for that reason, why can’t we use it within flat files to provide configuration? That’s exactly what the Composer guys thought. Who are we to argue with them?
JSON files use the .json
extension. Composer expects its configuration to live at the root of your package along with the filename composer.json
. Remember this! Laravel will use this file often.
Let’s open it up and start entering some information about our package.
{
"name": "marvel/xmen",
"description": "Mutants saving the world for people who hate them.",
"keywords": ["mutant", "superhero", "bald", "guy"],
"homepage": "http://marvel.com/xmen",
"time": "1963-09-01",
"license": "MIT",
"authors": [
{
"name": "Stan Lee",
"email": "stan@marvel.com",
"homepage": "http://marvel.com",
"role": "Genius"
}
]
}
Right, here we have a composer.json
file at the root of a package for the X-Men. Why the X-Men? They are awesome, that’s why.
Truth be told, all of the options (keys) in this file are optional. Normally you would provide the above information if you intended to redistribute the package or release it into the wild.
To be quite honest with you, I normally go ahead and fill in this information anyway. It doesn’t do any harm. The configuration above is used to identify the package. I have omitted a few keys that I felt were reserved for special circumstances. If you are curious about any additional config I would recommend checking out the Composer website which contains a wealth of information and documentation.
I also found this handy cheat sheet online, which may be useful for newcomers to Composer when creating new packages. Mouse over each line to discover more about the configuration items.
Anyway, let’s have a closer look at the configuration we have created for the X-Men package.
"name": "marvel/xmen",
This is the package name. If you have used Github then the name format will be familiar to you, but I’m going to explain it anyway.
The package name consists of two words separated by a forward slash (/
). The part before the forward slash represents the owner of the package. In most circumstances developers tend to use their Github username as the owner, and I fully agree with this notion. You can, however, use whatever name you like. Be sure to keep it consistent across all packages that belong to you.
The second part of the name string is the package name. Keep it simple and descriptive. Once again, many developers choose to use the repository name for the package when hosted on Github, and once again I fully agree with this system.
"description": "Mutants saving the world for people who hate them.",
Provide a brief description of the functionality of the package. Remember, keep it simple. If the package is intended for open source then you can go into detail within the README
file for your repository. If you want to keep some personal documentation then this isn’t the place for it. Maybe get it tattooed on your back, and keep a mirror handy? That makes the most sense to me. Sticky notes will also work well though.
"keywords": ["mutant", "superhero", "bald", "guy"],
These keywords are an array of strings used to represent your package. They are similar to tags within a blogging platform, and essentially serve the same purpose. The tags will provide useful search metadata for when your package is listed within a repository.
"homepage": "http://marvel.com/xmen",
The homepage configuration is useful for packages due to be open sourced. You could use the homepage for the project, or maybe the Github repository URL? Whatever you feel is more informative.
Once again I must remind you that all of these configuration options are optional. Feel free to omit them if they don’t make sense for your package.
"time": "1963-09-01",
This is one of those options that I don’t see very often. According to the cheat sheet, it represents the release date of your application or library. I’d imagine that it’s not required in most circumstances because of the fact that most packages are hosted on Github, or some other version control site. These sites normally date each commit, each tag, and other useful events.
Formats accepted for the time configuration are YYYY-MM-DD
and YYYY-MM-DD HH:MM:SS
. Go ahead and provide these values if you feel like it!
"license": "MIT",
If your package is due to be redistributed then you will want to provide a license with it. Without a license, many developers will not be able to use the package at all due to legal restrictions. Choose a license that suits your requirements, but isn’t too restrictive to those hoping to use your code. The Laravel project uses the MIT license which offers a great deal of freedom.
Most licenses require you to keep a copy of the license within the source repository, but if you also provide this configuration entry within the composer.json
file, then the package repository will be able to list the package by its license.
The authors section of the configuration provides information about the package authors, and can be useful for package users wishing to make contact.
Note that the authors section will allow an array of authors for collaborative packages. Let’s have a look at the options given.
"authors": [
{
"name": "Stan Lee",
"email": "stan@marvel.com",
"homepage": "http://marvel.com",
"role": "Genius"
}
]
Use an object to represent each individual author. Our example only has one author. Let’s take a look at Stan Lee. Not only does he have a cameo in every Marvel movie, but he’s also managed to make it into my book. What a cheeky old sausage!
"name": "Stan Lee",
I don’t really know how to simplify this line. If you are having trouble understanding it then you might want to consider closing this book, and instead pursue a career in sock puppetry.
"email": "stan@marvel.com",
Be sure to provide a valid email address so that you can be contacted if the package is broken.
"homepage": "http://marvel.com",
This time a personal homepage can be provided, go ahead and leech some hits!
"role": "Genius"
The role option defines the author’s role within the project. For example, developer, designer, or even sock puppetry artist. If you can’t think of something accurate then put something funny.
That’s all you need to describe your package, now let’s look at something more interesting. Dependency management!
Dependency Management
You have a box that will contain the X-Men. Only there aren’t a lot of mutants in that box yet. To build a great superhero team (application) you will need to enlist the support of other mutants (3rd party dependencies). Let’s have a look at how Composer will help us accomplish this.
{
"name": "marvel/xmen",
"description": "Mutants saving the world for people who hate them."
"keywords": ["mutant", "superhero", "bald", "guy"],
"homepage": "http://marvel.com/xmen",
"time": "1963-09-01",
"license": "MIT",
"authors": [
{
"name": "Stan Lee",
"email": "stan@marvel.com",
"homepage": "http://marvel.com",
"role": "Genius"
}
],
"require": {
}
}
We now have a new section within our composer.json
called require. This will be used to list our dependenc... mutants. From now on I’ll be omitting the rest of the configuration, and just showing the require block to shorten the examples. Make sure you know where it really lives though!
We know that the X-Men will depend on:
- Wolverine
- Cyclops
- Storm
- Gambit
There are loads of others, but these guys are pretty cool. We will stick with them for now. You see, we could copy the source files for these guys into our application directly, but then we would have to update them ourselves with any changes. That could get really boring. Let’s add them to the require
section so that Composer will manage them for us.
"require": {
"xmen/wolverine": "1.0.0",
"xmen/cyclops": "1.0.1",
"xmen/storm": "1.2.0",
"xmen/gambit": "1.0.0"
}
Here we are listing the packages for our mutant dependencies, and the versions that we would like to use. In this example, they all belong to the same owner as the X-Men package, but they could just as easily belong to another person.
Most redistributable packages are hosted on a version control website such as Github or Bitbucket. Version control repositories often have a tagging system where we can define stable versions of our application. For example with git we can use the command:
git tag -a 1.0.0 -m 'First version.'
With this we have created version 1.0.0
of our application. This is a stable release which people can depend on.
Let’s have a closer look at the Gambit dependency.
"xmen/gambit": "1.0.0"
You should know by now that Composer package names consist of an owner and a package nickname separated by a forward slash (/
) character. With this information we know that this is the gambit
package written by the xmen
user.
Within the require
section, the key for each item is the package name, and the value represents the required version.
In the case of Gambit, the version number matches up to the tag available on Github where the code is versioned. Do you see how the versions of dependencies are now specific to our application, and not the whole system?
You can add as many dependencies as you like to your project. Go ahead, add a billion! Prove me wrong.
Listen, do you want to know a secret? Do you promise not to tell? Woah, oh oh. Closer, let me whisper in your ear. Say the words you long to hear...
Your dependencies can have their own dependencies.
That’s right! Your dependencies are also Composer packages. They have their own composer.json
files. This means that they have their own require
section with a list of dependencies, and those dependencies might even have more dependencies.
Even better news, is that Composer will manage and install these nested dependencies for you. How fantastic is that? Wolverine might need tools/claws
, tools/yellow-mask
, and power/regeneration
but you don’t have to worry about that. As long as you require
the xmen/wolverine
package then Composer will take care of the rest.
As for dependency versions, they can assume a number of different forms. For example, you might not care about minor updates to a component. In which case, you could use a wildcard within the version, like this:
"xmen/gambit": "1.0.*"
Now Composer will install the latest version that starts with 1.0
. For example, if Gambit had versions 1.0.0
and 1.0.1
, then 1.0.1
would be installed.
Your package might also have a minimum or maximum boundary for package versions. This can be defined using the greater-than
and less-than
operators.
"xmen/gambit": ">1.0.0"
The above example would be satisfied by any versions of the xmen/gambit
package that have a greater version number than 1.0.0
.
"xmen/gambit": "<1.0.0"
Similarly, the less-than
operator is satisfiable by packages less than the version 1.0.0
. Allowing your package to specify a maximum version dependency.
"xmen/gambit": "=>1.0.0"
"xmen/gambit": "=<1.0.0"
Including an equals sign =
along with a comparison operator will result in the comparative version being added to the list of versions which satisfy the version constraint.
Occasionally, you may wish to enter more than one version, or provide a range value for a package version. More than one version constraint can be added by separating each constraint with a comma (,
). For example:
"xmen/gambit": ">1.0.0,<1.0.2"
The above example would be satisfied by the 1.0.1
version.
If you don’t want to install stable dependencies, for example, you might be the type that enjoys bungee jumping or sky diving, then you might want to use bleeding edge versions. Composer is able to target branches
of a repository using the following syntax.
"xmen/gambit": "dev-branchname"
For example, if you wanted to use the current codebase from the develop branch of the Gambit project on Github, then you would use the dev-develop
version constraint.
"xmen/gambit": "dev-develop"
These development version constraints will not work unless you have a correct minimum stability setting for your package. By default Composer uses the stable
minimum compatibility flag, which will restrict its dependency versions to stable, tagged releases.
If you would like to override this option, simply change the minumum-stability
configuration option within your composer.json
file.
"require": {
"xmen/gambit": "dev-master"
},
"minimum-stability": "dev"
There are other values available for the minimum stability setting, but explaining those would involve delving into the depths of version stability tags. I don’t want to overcomplicate this chapter by looking at those. I might come back to this chapter later and tackle that topic, but for now I’d suggest looking at the Composer documentation for package versions to find additional information on the topic.
Sometimes, you may find yourself needing to use dependencies that only relate to the development of your application. These dependencies might not be required for the day-to-day use of your application in a production environment.
Composer has got your back covered in this sithation thanks to its require-dev
section. Let’s imagine for a moment that our application will require the Codeception testing framework to provide acceptance tests. These tests won’t be any use in our production environment, so let’s add them to the require-dev
section of our composer.json
.
"require": {
"xmen/gambit": "dev-master"
},
"require-dev": {
"codeception/codeception": "1.6.0.3"
}
The codeception/codeception
package will now only be installed if we use the --dev
switch with Composer. There will be more on this topic in the installation and usage section.
As you can see above, the require-dev
section uses exactly the same format as the require
section. In fact, there are other sections which use the same format. Let’s have a quick look at what’s available.
"conflict": {
"marvel/spiderman": "1.0.0"
}
The conflict
section contains a list of packages that would not work happily alongside our package. Composer will not let you install these packages side by side.
"replace": {
"xmen/gambit": "1.0.0"
}
The replace section informs you that this package can be used as a replacement for another package. This is useful for packages that have been forked from another, but provide the same functionality.
"provide": {
"xmen/gambit": "1.0.0"
}
This section indicates packages that have been provided within the codebase of your package. If the Gambit packages source was included within our main package then it would be of little use to install it again. Use this section to let Composer know which packages have been embedded within your primary package. Remember, you need not list your package dependencies here. Anything found in require
doesn’t count.
"suggest": {
"xmen/gambit": "1.0.0"
}
Your package might have a number of extra packages that enhance its functionality, but aren’t strictly required. Why not add them to the suggest
section? Composer will mention any packages in this section as suggestions to install when running the Composer install command.
Well that’s all I have on dependencies. Let’s take a look at the next piece of Composer magic. Autoloading!
Auto Loading
By now we have the knowledge to enable Composer to retrieve our package dependencies for us, but how do we go about using them? We could require()
the source files ourselves within PHP, but that requires knowing exactly where they live.
Ain’t nobody got time for dat. Composer will handle this for us. If we tell Composer where our classes are located, and what method can be used to load them then it will generate its own autoload, which can be used by your application to load class definitions.
Actions speak louder than words, so let’s dive right in with an example.
"autoload": {
}
This is the section in which all of our autoloading configurations will be contained. Simple, right? Great! No sock puppetry for you.
Let’s have a look at the simplest of loading mechanisms, the files
method.
"autoload": {
"files": [
"path/to/my/firstfile.php",
"path/to/my/secondfile.php"
]
}
The files
loading mechanism provides an array of files which will be loaded when the Composer autoloader component is loaded within your application. The file paths are considered relative to your project’s root folder. This loading method is effective, but not very convenient. You won’t want to add every single file manually for a large project. Let’s take a look at some better methods of loading larger amounts of files.
"autoload": {
"classmap": [
"src/Models",
"src/Controllers"
]
}
The classmap
is another loading mechanism which accepts an array. This time the array consists of a number of directories which are relative to the root of the project.
When generating its autoloader code, Composer will iterate through the directories looking for files which contain PHP classes. These files will be added to a collection which maps a file path to a class name. When an application is using the Composer autoloader and attempts to instantiate a class that doesn’t exist, Composer will step in and load the required class definition using the information stored in its map.
There is, however, a downside to using this loading mechanism. You will need to use the composer dump-autoload
command to rebuild the class map every time you add a new file. Fortunately there is a final loading mechanism, and the best of all, which is intelligent enough to not require a map. Let’s first learn about PSR-0 class loading.
PSR-0 class loading was first described in the PSR-0 PHP standard, and provides a simple way of mapping PHP name-spaced classes to the files that they are contained in.
Know that if you add a namespace
declaration to a file containing your class, like this:
<?php
namespace Xmen;
class Wolverine
{
// ...
}
Then the class becomes Xmen\Wolverine
and as far as PHP is concerned it is an entirely different animal to the Wolverine
class.
Using PSR-0
autoloading, the Xmen\Wolverine
class would be located in the file Xmen/Wolverine.php
.
See how the namespace matches up with the directory that the class is contained within? The Xmen
namespaced Wolverine
class is located within the Xmen
directory.
You should also note that the filename matches the class name, including the uppercase character. Having the filename match the class name is essential for PSR-0
autoloading to function correctly.
Namespaces may have several levels, for example, consider the following class.
<?php
namespace Super\Happy\Fun;
class Time
{
// ...
}
The Time
class is located within the Super\Happy\Fun
namespace. So PHP will recognise it as Super\Happy\Fun\Time
and not Time
.
This class would be located at the following file path.
Super/Happy/Fun/Time.php
Once again, see how the directory structure matches the namespace? Also, you will notice that the file is named exactly the same as the class.
That’s all there is to PSR-0
autoloading. It’s quite simple really! Let’s have a look at how it can be used with Composer to simplify our class loading.
"autoload": {
"psr-0": {
"Super\\Happy\\Fun\\Time": "src/"
}
}
This time, our psr-0
autoloading block is an object rather than an array. This is because it requires both a key and a value.
The key for each value in the object represents a namespace. Don’t worry about the double backward slashes. They are used because a single slash would represent an escape character within JSON. Remember this when mapping namespaces in JSON files!
The second value is the directory in which the namespace is mapped. I have found that you don’t actually need the trailing slash, but many examples like to use it to denote a directory.
This next bit is very important, and is a serious ‘Gotcha’ for a lot of people. Please read it carefully.
The second parameter is not the directory in which classes for that namespace are located. Instead, it is the directory which begins the namespace to directory mapping. Let’s take a look at the previous example to illustrate this.
Remember the super happy fun time class? Let’s have another look at it.
<?php
namespace Super\Happy\Fun;
class Time
{
// ...
}
Well, we now know that this class would be located in the Super/Happy/Fun/Time.php
file. With that in mind, consider the following autoload snippet.
"autoload": {
"psr-0": {
"Super\\Happy\\Fun\\Time": "src/"
}
}
You might expect Composer to look in src/Time.php
for the class. This would be incorrect, and the class would not be found.
Instead, the directory structure should exist in the following format.
src/Super/Happy/Fun/Time.php
This is something that catches so many people out when first using Composer. I can’t stress enough how important this fact is to remember.
If we were to run an installation of Composer now, and later add a new class Life.php
to the same namespace, then we would not have to regenerate the autoloader. Composer knows exactly where classes with that namespace exist, and how to load them. Great!
You might wonder why I put my namespaces files in a src
folder? This is a common convention when writing Composer based libraries. In fact, here is a common directory/file structure for a Composer package.
src/ (Classes.)
tests/ (Unit/Acceptance tests.)
docs/ (Documentation.)
composer.json
Feel free to keep to this standard, or do whatever makes you happy. Laravel provides its own locations for classes which we will describe in a later chapter.
Now that you have learned how to define your autoload mechanisms, it’s time that we looked at how to install and use Composer, so that you can start taking advantage of its autoloader.
Installation
Now you might be wondering why I chose to cover installation and usage at the end of this chapter? I feel that having a good knowledge of the configuration will help you understand what Composer is doing behind the scenes as we are using it. Let me know!
The following installation methods will be specifically for unix based development environments such as Linux or Mac OSX. I’m hoping that Taylor might be able to edit this chapter and provide information on installing Composer in a Windows environment, since I avoid that particular operating system like the plague.
Composer is a PHP based application, so you should have the CLI client for PHP installed before attempting to use it. Double check this by running the following command.
php -v
If PHP has been installed correctly, you will see something similar to..
$ php -v
PHP 5.4.4 (cli) (built: Jul 4 2012 17:28:56)
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2012 Zend Technologies
with XCache v2.0.0, Copyright (c) 2005-2012, by mOo
If the output states that you are using anything less than PHP version 5.3.2, then you aren’t going to be able to use Composer until you upgrade your PHP version. In fact, if you are using anything less than PHP 5.3.7 then you won’t be able to use Laravel at all.
You can use CURL
to download Composer. Mac OSX comes with it by default. Many Linux distributions will have CURL within their software repositories, if it has not already been installed as standard. Let’s use CURL to download Composer’s executable.
curl -sS https://getcomposer.org/installer | php
Experienced linux users may be concerned that CURL is piping the installation script into PHP. This is a fair concern, but the Composer installation has been used by thousands of developers and has been proven to be secure. Don’t let it put you off using this lovely piece of software!
Assuming the installation process was completed successfully (it will tell you), you will now have a composer.phar
file in your application directory. This is the executable that can be used to launch Composer, for example..
php composer.phar
..will show you a list of commands that are available to you.
Now, you could continue to use Composer this way, but I would suggest installing it globally. That way it can be used across all of your Composer projects, and will have a shorter command to execute it.
To install Composer globally, simply move it to a location within your PATH
environmental variable. You can see these locations by using the following command.
echo $PATH
However, /usr/local/bin
is an acceptable location for most systems. When we move the file, we will also rename it to composer
to make it much easier to launch. Here is the command we need:
sudo mv composer.phar /usr/local/bin/composer
Having installed Composer globally, we can now use the following shorter syntax to see the same list of commands. This command is also executable from any location on the system.
composer
Hey, that’s a lot cleaner isn’t it? Let’s start using this thing.
Usage
Let’s assume that we have created the following composer.json
file in our package directory.
{
"name": "marvel/xmen",
"description": "Mutants saving the world for people who hate them."
"keywords": ["mutant", "superhero", "bald", "guy"],
"homepage": "http://marvel.com/xmen",
"time": "1963-09-01",
"license": "MIT",
"authors": [
{
"name": "Stan Lee",
"email": "stan@marvel.com",
"homepage": "http://marvel.com",
"role": "Genius"
}
],
"require": {
"xmen/wolverine": "1.0.0",
"xmen/cyclops": "1.0.1",
"xmen/storm": "1.2.0",
"xmen/gambit": "1.0.0"
},
"autoload": {
"classmap": [
"src/Xmen"
]
}
}
Let’s go ahead and use the install
command to install all of our package dependencies, and setup our autoloader.
composer install
The output we get from Composer will be similar to:
Loading composer repositories with package information
Installing dependencies
- Installing tools/claws (1.1.0)
Cloning bc0e1f0cc285127a38c232132132121a2fd53e94
- Installing tools/yellow-mask (1.1.0)
Cloning bc0e1f0cc285127a38c6c12312325dba2fd53e95
- Installing power/regeneration (1.0.0)
Cloning bc0e1f0cc2851213313128ea88bc5dba2fd53e94
- Installing xmen/wolverine (1.0.0)
Cloning bc0e1f0cc285127a38c6c8ea88bc523523523535
- Installing xmen/cyclops (1.0.1)
Cloning bc0e1f0cc2851272343248ea88bc5dba2fd54353
- Installing xmen/storm (1.2.0)
Cloning bc0e1f0cc285127a38c6c8ea88bc5dba2fd53343
- Installing xmen/gambit (1.0.0)
Cloning bc0e1f0cc285127a38c6c8ea88bc5dba2fd56642
Writing lock file
Generating autoload files
Remember that these are fake packages used as an example. Downloading them won’t work! They are however more fun, since they are X-men! Yay!
So why are there seven packages installed when I only listed four? Well you are forgetting that Composer automatically manages the dependencies of dependencies. The three extra packages are dependencies of the xmen/wolverine
package.
I’d imagine you are probably wondering where these packages have been installed to? Composer creates a vendor
directory in the root of your project to contain your package’s source files.
The package xmen/wolverine
can be found at vendor/xmen/wolverine
, where you will find its source files along with its own composer.json
.
Composer also stores some of its own files relating to the autoload system in the vendor/composer
directory. Don’t worry about it. You will never have to edit it directly.
So how do we take advantage of the awesome autoloading abilities? Well the answer to that is even simpler than setting up the autoloading itself. Simply require()
or include()
the vendor/autoload.php
file within your application. For example:
<?php
require 'vendor/autoload.php';
// Your awesome application bootstrap here!
Great! Now you can instantiate a class belonging to one of your dependencies, for example..
<?php
$gambit = new \Xmen\Gambit;
Composer will do all the magic and autoload the class definition for you. How fantastic is that? No more littering your source files with thousands of include()
statements.
If you have added a file in a class-mapped directory, you will need to run a command before Composer is able to load it.
composer dump-autoload
The above command will rebuild all mappings and create a new autoload.php
for you.
What if we want to add another dependency to our project? Let’s add xmen/beast
to our composer.json
file.
{
"name": "marvel/xmen",
"description": "Mutants saving the world for people who hate them.",
"keywords": ["mutant", "superhero", "bald", "guy"],
"homepage": "http://marvel.com/xmen",
"time": "1963-09-01",
"license": "MIT",
"authors": [
{
"name": "Stan Lee",
"email": "stan@marvel.com",
"homepage": "http://marvel.com",
"role": "Genius"
}
],
"require": {
"xmen/wolverine": "1.0.0",
"xmen/cyclops": "1.0.1",
"xmen/storm": "1.2.0",
"xmen/gambit": "1.0.0",
"xmen/beast": "1.0.0"
},
"autoload": {
"classmap": [
"src/Xmen"
]
}
}
Now we need to run composer install
again so that Composer can install our newly added package.
Loading composer repositories with package information
Installing dependencies
- Installing xmen/beast (1.1.0)
Cloning bc0e1f0c34343347a38c232132132121a2fd53e94
Writing lock file
Generating autoload files
Now xmen/beast
has been installed and we can use it right away. Smashing!
You may have noticed the following line in the output from the composer install
command.
Writing lock file
You might also have noticed that Composer has created a file called composer.lock
at the root of your application. What’s that for I hear you cry?
The composer.lock
file contains the information about your package at the time that the last composer install
or composer update
was performed. It also contains a list of the *exact version of each dependency that has been installed.
Why is that? It’s simple. Whenever you use composer install
when a composer.lock
file is present in the directory, it will use the versions contained within the file instead of pulling down fresh versions of each dependency.
This means that if you version your composer.lock
file along with your application source (and I highly recommend this), when you deploy to your production environment it will be using the exact same versions of dependencies that have been tried and tested in your local development environment. This means you can be sure that Composer won’t install any dependency versions that might break your application.
Note that you should never edit the composer.lock
file manually.
While we are on the topic of dependency versions, why not find out about updating them? For example if we had the following requirement in our composer.json
file.
"xmen/gambit": "1.0.*"
Composer might install version 1.0.0
for us. However, what if the package was updated to 1.0.1
a few days later?
Well, we can use the composer update
command to update all of our dependencies to their latest versions. Let’s have a look at the output.
$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
- Installing xmen/gambit (1.0.1)
Cloning bc0e1f0cc285127a38c6c8ea88bc5dba2fd56642
Generating autoload files
Great! The xmen/gambit
package has been updated to its latest version, and our composer.lock
file has been updated.
If we wanted to update only that one dependency rather than all of them, we could specify the package name when using the update
command. For example:
composer update xmen/gambit
Wait, what’s that (including require-dev)
bit mean? Well you must remember the require-dev
section in the composer.json
file where we list our development only dependencies? Well, Composer expects the update command to be only executed within a safe development or testing environment. For this reason, it assumes that you will want your development dependencies, and downloads them for you.
If you don’t want it to install development dependencies then you can use the following switch.
composer update --no-dev
Also, if you would like to install dependencies when using the install
command, simply use the following switch.
composer install --dev
The last thing you should know, is that you can use the composer self-update
command to update the Composer binary itself. Be sure to use sudo
if you have installed it globally.
sudo composer self-update
Well, that just about covers all the Composer knowledge we will need when working with Laravel. It has been a lot of information to take in, and a long chapter for these weary fingers, but I hope you have gained something from it.
If you feel that a particular topic needs expanding, be sure to let me know!
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!