Composer PHP
Composer PHP
Dayle Rees
This book is for sale at http://leanpub.com/composer-php
This is a Leanpub book. Leanpub empowers authors and publishers with the Lean
Publishing process. Lean Publishing is the act of publishing an in-progress ebook
using lightweight tools and many iterations to get reader feedback, pivot until you
have the right book and build traction once you do.
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i
Errata . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ii
Feedback . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iii
Translations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . iv
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
2. Concept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Dependency Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Class Autoloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Team Collaboration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
3. Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Application Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Dependency Packages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
4. Installation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Unix based OS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Updating . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
5. Inclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Initialization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Bootstrapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
6. JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
What is JSON? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
JSON Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
JSON and PHP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
7. Require . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Packagist . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
General . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
CONTENTS
Development . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
8. Version Numbers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Exact . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Comparison Operators . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Wildcard . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Tilde . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Caret . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
9. Autoloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Classmap . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
PSR-0 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
PSR-4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
10. Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Self Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Init . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Create Project . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
Install . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Update . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Info . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
i
Errata
While this may be my fifth book, and my writing is steadily improving, but I assure
you that there will be many, many errors. I don’t have a publisher, a review team, or
an English degree. I do the best that I can to help others learn about Laravel and PHP. I
ask that you, please be patient with my mistakes. You can support the title by sending
an email with any errors you might have found to [email protected] along with the
section title.
Errors will be fixed as they are discovered. Fixes will be released in future editions of
the book.
1
mailto:[email protected]
ii
Feedback
Likewise, you can send any feedback you may have about the content of the book or
otherwise by sending an email to [email protected] . You can also send a tweet to
@daylerees3 . I will endeavour to reply to all mail that I receive.
2
mailto:[email protected]
3
https://twitter.com/daylerees
iii
Translations
If you would like to translate this book into your language, please send an email to
[email protected] with your intentions. I will offer a 50/50 split of the profits from
the translated copy, which will be priced at the same as the English copy.
Please note that the book is written in markdown format, and is versioned on Github5 .
4
mailto:[email protected]
5
http://github.com
iv
1. Introduction
Hi there! Nice to meet you!
My name’s Dayle, and I’m a thirty-one-year-old web developer from Cardiff, the
capital of Wales in the UK. I’ve been writing PHP based applications for close to a
decade, been heavily involved with the Laravel PHP framework, have written four self-
published programming books, and given conference talks worldwide. I promise that
you’re in good hands as we venture into a new topic with this book.
I’m hoping that the lack of a red panda on the cover, this time, hasn’t scared you away.
Hopefully, everyone will love the angry looking bird! I’m not even sure what it is. My
girlfriend snapped a shot of it one day at the Zoo, and I found it in her photo album.
Some kind of puffin, maybe? I should probably check, but not right now!
As you’ve already gathered. I don’t write books like a normal person. In fact, I’m at
least 90% sure that I’m not a normal person. The other 10% of my opinion belongs to
my split personality.
I write my books with humor and simplicity. It’s like we’re sitting in the pub together,
sharing a drink and learning about programming. I consider my readers to be friends,
and I hope that you’ll feel the same. The simple language in my books is not just
refreshing to new readers, but it’s very important to my many foreign-language
readers. They find it much more simple to understand my books, than a complex
technical book with long unnecessary words. I’m not looking to win any awards with
my control of the English language, but I’m sure you’re going to learn a bunch of new
skills along the way.
I discovered Composer during the development of Laravel four. You see, the frame-
work uses it to piece its components together. Back then, Composer wasn’t as
widespread as it is now, and I hope that the framework adoptions were partly
responsible for its success.
Composer is the most exciting project in the PHP world. It has changed the landscape
of the language, and it makes building PHP applications an enjoyable experience.
Right then, I bet you’re eager to get started? All that’s left to do is thank Jordi Boggiano
for creating Composer, and flip that page!
1
2. Concept
Let’s start our journey by examining the concept behind Composer. What is this
software? What does it do?
I expect that you’ve all had some experience with building PHP applications. You don’t
have to have used a framework, but you’ll at least need to understand the language. If
not, I would suggest starting with my book PHP Pandas1 .
When you’re creating an application in PHP, you don’t want to write all of it yourself.
Certain problems have already been solved, and it doesn’t make any sense to re-invent
the wheel.
Fortunately, we live in a world where open source rules. Software and libraries that
are free of charge, and often have shortcuts or utilities to make our jobs as developers
that little bit easier. In writing classic PHP applications, you’ve likely included a bunch
of files and classes with your applications. These are your application dependencies.
Here are some examples:
And of course, many, many more. In fact, there are probably millions of pieces of re-
usable code out there in the PHP ecosystem. Previously, you’d find some of the more
significant libraries on repositories such as PECL, but they weren’t easy to install, and
would have to be installed for all PHP applications on your system, not just the one
you’re working on. That’s really inconvenient, isn’t it?
Luckily, this is where Composer comes to the rescue. In fact, I believe that there are
three big reasons to use Composer to power your PHP applications. Let’s take a look
at them now.
Dependency Management
If we decide to include all of our dependencies ourselves. We’ll need to put them in a
directory inside our application. We’ll need to load their classes or files using include
or require. We might need to bootstrap them with configuration variables, and then,
1
http://leanpub.com/php-pandas
2
Concept 3
three years from now they’ll be completely out of date, and will explode when you
update your version of PHP. In fact, how do we know that our dependencies won’t
conflict with each other? We have no way of knowing.
You’re completely right, reader. We don’t want to have to deal with all these issues.
We’d prefer to focus on building our applications, and not worrying so much about
our dependencies.
This is where Composer arrives, wearing it’s spandex and cape, to save the day.
Composer will take care of your dependencies for you. It will help you install them;
they will automatically be available within your applications, and you won’t have to
include them yourself. It will even install version updates of your dependencies for
you so that you never go out of date.
Simply put, it’s going to make it much easier to install, use, and keep your dependen-
cies up to date. Let’s take a look at the next reason to use Composer.
Class Autoloading
As mentioned in the previous section, Composer will automatically provide the classes
and functions available in your dependencies, so that you won’t have to use include
everywhere.
If only we could do that in our applications. Having to include every file before we can
use a class is a little repetitive, and can litter our code with a bunch of unnecessary
include and require_once statements. We don’t want to be messing with that.
I can’t trick you, can I reader? You’re right. Composer can take care of this for us. It
ships with a variety of methods of matching up class names to the files that contain
them. So you’ll never have to include a class again. Isn’t that great?
Let’s take a look at my third most important reason for adopting composer.
Team Collaboration
Our final reason for using Composer applies mainly to those working in teams. How-
ever, it’s a feature that can also be useful to maintainers of libraries and frameworks.
Concept 4
Composer ships with a file that defines the packages in use by your application. In
fact, you version it alongside your code. It will detail packages and the exact versions
of installed dependencies.
This means that with a quick composer install (don’t worry; this will arrive in a later
chapter) you’re running the exact same version of all of your dependencies as the rest
of your team. No more cases of “Dude, what do I need to run this?” or “Maybe I need
to update my dependencies?”. Composer will handle this for you.
Hopefully, you’re sold on the benefits of Composer, and I assure you that while these
three are the important ones for me, there are much, much more.
In the next chapter, we’ll learn about packages. They are super important to Com-
poser. Flip the page; I dare you!
3. Packages
Composer lives and breathes packages. Packages are small containers of code that
have been created to serve a particular package.
For example, a ‘PayPal’ Composer package might provide code that will make it more
simple to interact with the PayPal payment gateway. A ‘Math’ package might provide
some useful classes and/or functions for performing mathematical calculations and
interacting with numbers.
Composer packages are limited only by the author’s creativity. We’ll soon discover this
when we take a closer look at the ‘Packagist’ Composer package repository.
Before we take a closer look at a package; I think it would be useful to learn about the
different types of Composer packages available. I like to separate Composer packages
into two distinct categories by their usage. Let me explain.
Application Packages
Some developers might argue that this shouldn’t be called a package at all. In some
ways, it may be better to describe these packages as a ‘Composer-driven project’. I
like to consider any project directory that contains a composer.json configuration file
(more on this later) a package.
Application packages contain a composer.json only to list other packages as depen-
dencies, or take advantage of Composer’s fantastic class autoloading capabilities.
They aren’t intended to be re-distributable. It’s your project. Your baby. It might be a
confidential codebase, or something experimental, but it’s not meant for sharing.
Just because your package isn’t shared, it doesn’t mean that you can’t use the other
packages as dependencies.
In the good ol’ days of PHP, if you wanted to take advantage of an open source
calculation class then you would have copied it into your project, or implemented this
functionality yourself. You wouldn’t receive updates from the original author unless
you update the files by hand. You were missing out on hotfixes and new features.
These were sad times.
By listing another package as a dependency of your Composer driven application you
can use all that great code without any drawbacks. If the author decides to update
his or her package, then you can update your local version by running composer
update. If you are worried about hidden updates or changes making their way into
5
Packages 6
the dependency package, then you can fix it to a specific version. This way you will
always receive the same codebase as a dependency.
You can even ensure that a dependency version exists within a certain range of version
numbers, is stable, is a development version and many, many more options! We’ll learn
more about this later.
You can list as many packages as you like as dependencies. A typical Composer
configuration file may contain the following code snippet.
1 "require": {
2 "laravel/framework": "4.1.*",
3 "solarium/solarium": "3.2.0",
4 "omnipay/omnipay": "~2.0",
5 "mockery/mockery": "0.8.0"
6 },
Don’t worry too much about the implementation, but it should be clear that in the
above example we are defining four dependencies for our application. These packages
contain code and classes that we wish to use.
The first package laravel/framework is an entire PHP framework, and has many
dependencies of its own. This doesn’t phase Composer at all. It will quite happily
retrieve the entire dependency tree for us.
Retrieving dependencies is the most important Composer feature within an applica-
tion package contest, but it’s not the only one! Composer is also able to manage the
mapping of file paths to class definitions, and will load PHP classes within your own
application or dependency packages whenever you need them.
You no longer have to make a thousand calls to include() the files containing the
classes that you wish to use. Let Composer do the hard work! We’ll take a closer look
at this feature within the ‘autoloading’ chapter of the book.
One other interesting feature of Composer is the ability to move binary or executable
files to a specific location. This makes it possible to include useful tools such as
PHPUnit or PHP Mess Detector as a development dependency of your application
and then execute them right within your project directory. You no longer need to
install these applications globally! (Actually, composer makes it easier to install them
globally too, if that’s what you prefer!)
I don’t want to cover every feature here. We have a whole book for that! Why don’t we
take a look at the other type of package available for use with Composer?
Packages 7
Dependency Packages
A dependency or ‘redistributable’ packages are packages of code which are intended
for use as a dependency of another package. They aren’t our website, blog or CSS
showcase. They are libraries and components. Perhaps even frameworks built of
multiple components.
The format of a dependency package is no different to that of an application package.
The configuration is nearly identical. It can list dependencies, autoloading mecha-
nisms and all of that fun stuff!
Dependency packages are likely to be software development kits for a particular
service. Libraries or classes that provide specific and re-usable functionality. I’ve even
seen some dependency packages that don’t provide any PHP code at all! I’ve seen
some that are used to include CSS frameworks, but I don’t wish to overcomplicate
this chapter by explaining how that works.
To summarize, a Composer package may simply be a consumer of other Composer
packages and tools to empower an application, or it may be a container for redis-
tributable open source code that is intended to make the lives of other developers
easier!
In the next chapter, we’ll learn how to install Composer. Don’t worry; in most
situations you’ll only have to do it once, and it’s quite a simple process.
4. Installation
Before we can begin to use Composer, we must first install it. That’s right; it doesn’t
ship with your computer. Shame on Apple or some other makes I guess!
Composer exists as a PHP script wrapped in a .phar file. This phar is a sort of archive,
much like a .zip file, except that it is executable. The method of installing Composer
is simply retrieving this binary.
Before we attempt to retrieve the Composer phar file. Let’s check to make sure we
meet the requirements to use the application. You will need all of the following.
Unix based OS
First, we need to retrieve the Composer installer. We can use the CURL application
to achieve this goal. On a recent Mac, you will find that CURL is already installed,
however, on certain Linux distributions, including Ubuntu, you will need to install
CURL using your package manager. For example:
Once CURL is installed, we can continue to install the software. We will use CURL to
retrieve the installation script; then we will use the pipe | modifier to execute the
script with PHP. Let’s give it a go.
8
Installation 9
As we can see, all our settings are correct. This is Composer’s way of saying that we
meet all of the requirements for using Composer. It then procedes to download the
.phar file, and lets us know where it has been downloaded to.
Let’s execute Composer to see if it’s working. We can use the php CLI interface to
execute the .phar file and see the result.
1 $ php composer.phar
2 ______
3 / ____/___ ____ ___ ____ ____ ________ _____
4 / / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
5 / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ /
6 \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
7 /_/
8 Composer version fb72d26def99d08ee32e5be7b553817f585f164e 2013-12-20 10:53:52
9
10 Usage:
11 [options] command [arguments]
12
13 Options:
14 --help -h Display this help message.
15 --quiet -q Do not output any message.
16 --verbose -v|vv|vvv Increase the verbosity of messages: 1 for normal ou\
17 tput, 2 for more verbose output and 3 for debug
18 --version -V Display this application version.
19 --ansi Force ANSI output.
20 --no-ansi Disable ANSI output.
21 --no-interaction -n Do not ask any interactive question.
22 --profile Display timing and memory usage information
23 --working-dir -d If specified, use the given directory as working directory.
24
Installation 10
25 Available commands:
26 about Short information about Composer
27 archive Create an archive of this composer package
28 config Set config options
29 create-project Create new project from a package into given directory.
30 depends Shows which packages depend on the given package
31 diagnose Diagnoses the system to identify common errors.
32 dump-autoload Dumps the autoloader
33 dumpautoload Dumps the autoloader
34 global Allows running commands in the global composer dir ($COMPOSER\
35 _HOME).
36 help Displays help for a command
37 init Creates a basic composer.json file in current directory.
38 install Installs the project dependencies from the composer.lock file\
39 if present, or falls back on the composer.json.
40 licenses Show information about licenses of dependencies
41 list Lists commands
42 require Adds required packages to your composer.json and installs them
43 run-script Run the scripts defined in composer.json.
44 search Search for packages
45 self-update Updates composer.phar to the latest version.
46 selfupdate Updates composer.phar to the latest version.
47 show Show information about packages
48 status Show a list of locally modified packages
49 update Updates your dependencies to the latest version according to \
50 composer.json, and updates the composer.lock file.
51 validate Validates a composer.json
Well, that sure is a lot of commands! In fact, it will be a useful reference for when you
begin using Composer within your own applications.
It’s clear that Composer is functioning correctly, and we could continue to use it in
this fashion. We will have to install Composer for all of our projects, though, won’t
we? Why don’t we install it globally? Now that’s DRY (Don’t Repeat Yourself) thinking!
To install Composer globally, we need only move it to a location within our PATH
environmental variable. This will allow us to execute the command from anywhere
within our system. Normally the /usr/local/bin directory is part of everyone’s path,
but feel free to substitute it for another location within the command below.
Installation 11
1 $ mv composer.phar /usr/local/bin/composer
You will notice that we strapped ‘composer’ onto the end of the target destination.
This is because we don’t want to be typing composer.phar to execute it all the time.
Let’s just use composer instead by renaming the file.
Let’s test to make sure that the relocated command functions as expected.
1 $ composer
2 ______
3 / ____/___ ____ ___ ____ ____ ________ _____
4 / / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
5 / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ /
6 \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
7 /_/
8 Composer version fb72d26def99d08ee32e5be7b553817f585f164e 2013-12-20 10:53:52
9
10 Usage:
11 [options] command [arguments]
Brilliant! I hid a few of the commands to save some space, but as we can see, Composer
is executing as expected. It is now installed!
Unix folk, feel free to skip to the updating section. It’s time for the Windows folk to be
educated.
Windows
Bear with me Windows folk. It has been some time since I last developed on Windows.
Still, let’s give this a go.
Before installing Composer, you must first find a directory that exists within your PATH
environment variable, as shown within the Windows Environmental Variables system
settings dialog. Let’s imagine that the directory c:\bin\ exists within your PATH.
First, let’s open a command prompt, by running cmd after clicking the Start button,
and the Run.... We will first move to the directory located within our PATH.
Installation 12
1 C:\>cd bin
2 C:\bin>
Next, we will use PHP to retrieve the file, and to evaluate it. It’s a complicated
command so, please make note of all the special characters.
1 C:\bin>php -r "eval('?>'.file_get_contents('https://getcomposer.org/installer'))\
2 ;"
The Composer .phar file will be downloaded to the current directory, but isn’t
conveniently executable in its current form. Let’s use the Windows echo command
to output an execution script into a new composer.bat file. Here is the command
required.
1 C:\>composer
2 ______
3 / ____/___ ____ ___ ____ ____ ________ _____
4 / / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
5 / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ /
6 \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
7 /_/
8 Composer version fb72d26def99d08ee32e5be7b553817f585f164e 2013-12-20 10:53:52
9
10 Usage:
11 [options] command [arguments]
12
13 Options:
14 --help -h Display this help message.
Installation 13
Updating
Every now and again you will want to update Composer to take advantage of the latest
bug fixes and features. In fact, Composer will let you know when your current version
is 30 days out of date.
1 $ composer install
2 Warning: This development build of composer is over 30 days old. It is recommend\
3 ed to update it by running "/usr/local/bin/composer self-update" to get the late\
4 st version.
As the comment suggests, we can use the self-update command to instruct Com-
poser that it should update itself. For example:
1 $ composer self-update
On unix based systems you may need to use the sudo command to allow Composer to
execute with administrative privileges in order to update itself. Just like this:
Be sure to keep your Composer installation up to date. You never know what new
features you might be missing out on. Also, if you happen to encounter a bug with
Composer, it’s always worth updating to see if it has been fixed in a later release.
In the next chapter, we’ll learn how to initialise a Composer powered project, so that
we can begin orchestrating!
5. Inclusion
To use Composer in your project, you’re going to need to have Composer installed,
and at least one additional file. This file is called composer.json and typically sits in
the root of your project. It’s the file that informs Composer about the needs of your
project.
Initialization
Don’t worry. We don’t have to write that file ourselves. Let’s cheat, shall we? First,
navigate to the root of your project, and check whether a composer.json already exists.
If it’s already there, then you’re done. Really! It means that your project is already using
Composer. There are plenty of frameworks, like Laravel, for example, that will ship
with a default composer.json file included.
If your project is a new one, or doesn’t have an existing composer.json file, then we
can create it with a simple command. Here’s an example.
1 $ composer init
The init command will ask you a few questions, and use this information to construct
your initial composer.json file. Let’s run through the questions, shall we? Don’t worry
too much about your answers. You’ll be able to change them later; it’s no problem!
Composer is asking for our package name. As you can see, a typical package name
uses a vendor name, and a name, separated by a forward slack. Normally, the vendor
and name are written in lowercase, and spaces are represented by a - dash character.
You can change this format if you like, but we won’t be best friends anymore. I do have
a certain level of OCD, you see!
Composer has recommended that we use the name dayle/composer-example. This
because our current unix username is dayle and the current directory is called
composer-example. You’re welcome to specify a different name, but I’m feeling good
about this one. We’ll hit Enter to continue to the next question.
15
Inclusion 16
1 Description []:
The next prompt asks for an optional description for your application or package. I’d
keep this to one to three sentences at most. This is an example package, and we don’t
intend to distribute it. We’ll skip the description by pressing enter.
Next, Composer is asking for the name of the author, and their email address. The
default options that are provided here are taken from the configuration of my Git
client. At least, that’s what I think. I’ll try to confirm this for you and update the title
when I find an answer. If you’d like to provide a different author and email, simply
provide the new information using the format shown above.
However, an author is an optional field, and if we’d rather not provide one, then just
hit the n key to skip. Composer won’t judge you, I promise.
Here we can specify the minimum stability for our dependencies. We haven’t learned
about package stability yet, so let’s press enter to use the default. Don’t worry; you’ll
learn about this feature in a later chapter.
If you intend to redistribute the package, then you can specify the type of content to
make it easier to understand what’s inside. For example, many redistributable libraries
will list library as their package type. Here, we’re only using Composer to power our
application, so we’ll hit enter and use the default.
Inclusion 17
1 License []:
As you might imagine, the license field is crucial to redistributable libraries and
frameworks. You’ll find that many open-source frameworks use the MIT License1 and
will specify MIT within this field.
Us, however, we’ll hit enter to continue.
Here, we’re given an opportunity to list any dependencies that we know of. We’re not
aware of any yet, and there’s plenty of opportunities to add them later. Therefore, we’ll
simply type no and skip this section entirely.
1 Would you like to define your dev dependencies (require-dev) interactively [yes]?
1 {
2 "name": "dayle/composer-example",
3 "authors": [
4 {
5 "name": "Dayle Rees",
6 "email": "[email protected]"
7 }
8 ],
9 "require": {}
10 }
11
12 Do you confirm generation [yes]?
1
Inclusion 18
And there we have it. That’s the proposed format for our initial composer.json. If you
don’t understand the syntax, that’s perfectly fine! We’ll cover it in depth in the next
chapter. Let’s hit enter, and we’ll see that our composer.json file is now there at the
root of our project.
Now let’s discover how we can tie Composer into our PHP application, and take
advantage of its autoloading features.
Bootstrapping
Before we can begin using classes and libraries provided by Composer, or taking
advantage of its autoloading capabilities, we’ll need to make our project aware of it.
Don’t worry; this is a simple process.
This is our first Composer driven application, so before we start, we’ll need to run the
following command.
1 $ composer install
2 Loading composer repositories with package information
3 Updating dependencies (including require-dev)
4 Nothing to install or update
5 Generating autoload files
If we had defined our required packages, then this command will have instructed
Composer to download and install them, however, since we’ve no dependencies
currently, it will simply create the files required to support autoloading.
If we look at our project directory, where our composer.json sits, we’ll discover a new
file and a new directory.
• composer.json
• composer.lock
• vendor (directory)
The composer.lock file contains information about the exact versions (right down to
the commit) of dependencies that are used by our application. Don’t worry too much
about this file for now. We’ll cover it in depth in a later chapter.
The vendor directory is where Composer keeps all of its files. It will keep our
dependencies in here, and also the php files that are necessary for bootstrapping.
Right now we’re interested in one file in particular.
Inclusion 19
1 vendor/autoload.php
This file is all that we need to make our application aware of Composer, and to take
advantage of it’s wide feature set. All we need to do is require_once the file within
our application. I’d suggest doing this right at the top of your application, where it
begins. For example, if you have a web application that uses a file called index.php as
its front-controller, then you’d include vendor/autoload.php right at the top of this
file. Let’s take a look at an example.
1 <?php
2
3 require_once __DIR__ . 'vendor/autoload.php';
4
5 // Here we can use classes and functions loaded by Composer.
What is JSON?
For the next chapter on Composer, we’re going to need a basic understanding of
JSON. Trust me; it doesn’t hurt to learn this stuff. JSON is used by a bunch of different
technologies.
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 commonly achieved using JavaScript
with an AJAX or ‘XHR’ request.
Many software APIs also serve content using this file format. Twitter’s own is an
excellent 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() method to transform the string into a new instance containing the
original value.
20
JSON 21
It’s what we will be using JSON for. However, the advantage is that JSON can be parsed
by a variety of different languages, where 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
1 {"name":"Lushui","species":"Panda","diet":"Green Things","age":7,"colours":["red\
2 ","brown","white"]}
Yay! JSON! Okay. 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. This might make it a little more difficult to read.
This is normally used to save on bandwidth when transferring the data. Without all
the extra whitespace, the JSON string will be much shorter and thus be fewer 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 efficiently. 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.)
1 {
2 "name": "Lushui",
3 "species": "Panda",
4 "diet": "Green Things",
5 "age": 7,
6 "colours": ["red", "brown", "white"]
7 }
JSON 22
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 against prying
eyes.
As you can see from the example, we have some key-value pairs. Within one of the key-
value pairs, we have an array. If you have used some JavaScript before you may wonder
what has changed here? In fact, let’s have a look at how this would be represented in
JavaScript.
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:
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 know that JSON doesn’t have
variables. This is fine since we can use strings as keys, and that’s 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 behavior 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 by 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.
JSON 23
1 age: 7,
• 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 previously, 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 look very similar to their JavaScript counterpart.
1 // JavaScript
2 ['red', 'brown', 'white']
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. 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
realized that JSON can support nested objects and arrays. Let’s have a look at that in
action!
1 {
2 "an_object": {
3 "an_array_of_objects": [
4 { "The": "secret" },
5 { "is": "that" },
6 { "I": "still" },
7 { "love": "shoes!" }
8 ]
9 }
10 }
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.
1 <?php
2
3 $truth = ['panda' => 'Awesome!'];
4 echo json_encode($truth);
The result of this snippet of code would be a JSON string containing the following
value.
1 {"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.
1 <?php
2
3 $truth = json_decode('{"panda":"Awesome!"}');
4 echo $truth['panda'];
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.
JSON 26
1 <?php
2
3 $truth = json_decode('{"panda":"Awesome!"}');
4 echo $truth->panda;
5
6 // Awesome!
Great! That’s what we wanted. If we wanted an array instead, then PHP provides some
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()!
1 <?php
2
3 $truth = json_decode('{"panda":"Awesome!”}', true);
4 echo $truth['panda'];
5
6 // Awesome!
Huzzah!
In the next section, we’ll discover how to list and install our application dependencies.
We’re getting to the exciting stuff now. I bet you can’t wait to get started. Good news,
you don’t have to! Just turn the page.
7. Require
It’s time for us to get serious. It’s time to start finally using some packages. But first,
we’re going to need to find some packages to use, aren’t we? Let’s search around the
internet, using Google like we’ve been possessed by a demon. Oh, wait. Why don’t we
use Packagist instead?
Packagist
Packagist is a central repository for PHP libraries, tools, and frameworks. Essentially,
it’s a big list of Composer packages that you can use in your application (or indeed,
other packages). At the time of writing, Composer has 94, 733 packages, with 498,�561
versions. Of which, 1,�997,�603,�458 packages have been installed during the lifetime
of the application. That’s a lot of packages! I think we need to get access to them, don’t
we?
Hmm, that’s a little pessimistic, but painfully truthful about the internet. Fortunately,
we’re not going to suffer any of this indignities with Packagist. We don’t even need to
sign up for an account. We can begin using it right away.
You’ll find Packagist at the following URL: https://packagist.org1
Go ahead and browse the available packages. You might find something truly interest-
ing on there! Each package offers statistics about its popularity using the number of
installs, and a star rating. You can use these pieces of information to decide whether
or not a package is reliable and worth depending upon.
In this chapter, we’re going to be working with three libraries. They are well-known
to the PHP community and extremely reliable.
• PHPUnit
• Carbon
• Illuminate Container
1
https://packagist.org
27
Require 28
PHPUnit is a unit testing framework created by Sebastian Bergmann. It’s easily the
most popular testing framework available for PHP and is a great candidate for our
examples in this chapter. You’ll find a bunch more information about PHPUnit on its
Packagist page2 .
Carbon is a drop-in replacement for the PHP DateTime class. It extends DateTime,
and provides a bunch of useful methods for interacting with dates and times. It was
created by Brian Nesbitt, and you’ll find additional information on the Packagist page
for this project3 .
The Illuminate Container is an inversion of control container used by the Laravel
framework. It has very few dependencies itself, so we’re able to take advantage of
it within our own application. The container was written by my good friend Taylor
Otwell, and you’ll find more information about it on Packagist4 .
PHPUnit will only be used in development. So let’s venture into the next section, where
we’ll learn how to make use of Carbon and Container within our application.
General
It’s time to learn how to install a dependency package. Don’t worry! It’s an easy
process. We’ll assume for now, that we wish to use the latest version of each package.
Let’s not complicate this chapter by adding version numbers into the mix.
First, take a look at the Packagist page for Carbon5 . You’ll see that the name of the
package is nesbot/carbon. This means that nesbot is the vendor name that Brian uses
for his package, and that carbon is its name. Near the top of the page, you’ll see the
command composer require nesbot/carbon.
Packagist is extremely helpful. That’s the command that we need to run to install our
package. Let’s go ahead and run that command now.
2
https://packagist.org/packages/phpunit/phpunit
3
https://packagist.org/packages/nesbot/carbon
4
https://packagist.org/packages/illuminate/container
5
https://packagist.org/packages/nesbot/carbon
Require 29
When we take a look at the output, we can see that Composer has indeed installed
the latest version of nesbot/carbon which happens to be version 1.21.0.
You’re quite right! We didn’t ask for those packages, but I promise that they are
needed. You see, Carbon has its own list of dependencies. Composer has found them,
and knows that they are essential for it to function. For that reason, it has installed
them before installing Carbon itself. Composer is clever like that! It will normally
resolve the entire dependency tree (including dependencies of dependencies of
dependencies..) to ensure that our package is installed.
You’ll also notice that Composer has listed three suggested packages. These
are defined in Carbon’s composer.json file. Normally, suggested packages
allow for additional functionality, but aren’t strictly required for the package
to function.
Require 30
Our dependency is now installed, and as you can see from the line Generating
autoload files, all of its classes are now available for use in our application. Let’s
give this a go, shall we?
1 <?php
2
3 // Register our Composer autoloader.
4 require_once __DIR__ . 'vendor/autoload.php';
5
6 // Create a new Carbon instance to represent right now.
7 $now = Carbon::now();
Notice how we didn’t need to include any of Carbon’s files? The Carbon class is loaded
by Composer’s registered autoloader when we try to use it. We simply install a package
and start using it right away. There’s no messing about, just great code!
Let’s try again, shall we? What’s the package name used for the Illuminate container?
Why don’t you try to find it on Packagist?
That’s right! You see, reader, that’s why I keep you around. We’re going to go far, you
and I.
Let’s go ahead and install it using the install command. Here’s the output we receive.
Using the output, we can see that Composer has installed version 5.3.31 of the
Illuminate container. We can also see that it has only a single dependency, which
is the illuminate/contracts package.
Now we can use our Container, alongside the Carbon dependency that we had
previously installed.
1 <?php
2
3 // Register our Composer autoloader.
4 require_once __DIR__ . 'vendor/autoload.php';
5
6 // Create a new Carbon instance to represent right now.
7 $now = Carbon::now();
8
9 // Bind the instance within the Illuminate Container.
10 $container = new Illuminate\Container;
11 $container->instance('now', $now);
You’re free to use as many dependencies as you like. The limit is your own
imagination. Well, wait. The limit might be your memory, disk space, perhaps
thread execution time, but those things are huge. Let’s just say it’s your
imagination.
1 {
2 "name": "dayle/composer-example",
3 "authors": [
4 {
5 "name": "Dayle Rees",
6 "email": "[email protected]"
7 }
8 ],
9 "require": {
10 "nesbot/carbon": "^1.21",
11 "illuminate/container": "^5.2"
12 }
13 }
Require 32
Woah, those are our new packages! You’ll see that they’ve been listed, along with their
version numbers. The ˆ means that we don’t care about the patch version, as long as it
begins with 5.2. You’ll notice that our dependencies’ dependencies aren’t listed. This
is because they are indicated within their own packages.
We’ll version composer.json along with the rest of our application, this way, our fellow
developers can use composer install to install required packages along with all of
their dependencies.
Development
In development environments, we have different requirements. Sometimes there are
tools that you need, but you don’t want to install them in production. That would waste
valuable resources, and could expose vulnerabilities in our software. These packages
could contain debugging software, testing frameworks, and other useful tools.
We still want to use them, don’t we? Why don’t we add them to the require-dev
section? This way, they will only be installed in our development environment. This
means that our production environment remains safe.
It’s simple to add packages to this environment. Simply use the --dev switch when
installing a package. Let’s install PHPUnit this way, since it’s very unlikely that we’ll
want to run our tests in production. We’ll give it a go, shall we?
19 Downloading: 100%
20
21 - Installing sebastian/global-state (1.1.1)
22 Downloading: 100%
23
24 - Installing sebastian/exporter (1.2.1)
25 Downloading: 100%
26
27 - Installing sebastian/environment (1.3.5)
28 Downloading: 100%
29
30 - Installing sebastian/diff (1.4.1)
31 Downloading: 100%
32
33 - Installing sebastian/comparator (1.2.0)
34 Downloading: 100%
35
36 - Installing symfony/yaml (v3.0.4)
37 Downloading: 100%
38
39 - Installing doctrine/instantiator (1.0.5)
40 Downloading: 100%
41
42 - Installing phpdocumentor/reflection-docblock (2.0.4)
43 Downloading: 100%
44
45 - Installing phpspec/prophecy (v1.6.0)
46 Downloading: 100%
47
48 - Installing phpunit/php-text-template (1.2.1)
49 Downloading: 100%
50
51 - Installing phpunit/phpunit-mock-objects (3.1.3)
52 Downloading: 100%
53
54 - Installing phpunit/php-timer (1.0.7)
55 Downloading: 100%
56
57 - Installing sebastian/code-unit-reverse-lookup (1.0.0)
58 Downloading: 100%
59
60 - Installing phpunit/php-token-stream (1.4.8)
Require 34
61 Downloading: 100%
62
63 - Installing phpunit/php-file-iterator (1.4.1)
64 Downloading: 100%
65
66 - Installing phpunit/php-code-coverage (3.3.1)
67 Downloading: 100%
68
69 - Installing phpunit/phpunit (5.3.2)
70 Downloading: 100%
71
72 sebastian/global-state suggests installing ext-uopz (*)
73 phpdocumentor/reflection-docblock suggests installing dflydev/markdown (~1.0)
74 phpdocumentor/reflection-docblock suggests installing erusev/parsedown (~1.0)
75 phpunit/php-code-coverage suggests installing ext-xdebug (>=2.4.0)
76 phpunit/phpunit suggests installing phpunit/php-invoker (~1.1)
77 Writing lock file
78 Generating autoload files
Well… it’s clear that PHPUnit has a lot of dependencies, but that’s not always a bad
thing, and besides, we’re only going to need them in our development environment.
Let’s double check that by looking at our composer.json. What do we have here?
1 {
2 "name": "dayle/composer-example",
3 "authors": [
4 {
5 "name": "Dayle Rees",
6 "email": "[email protected]"
7 }
8 ],
9 "require": {
10 "nesbot/carbon": "^1.21",
11 "illuminate/container": "^5.2"
12 },
13 "require-dev": {
14 "phpunit/phpunit": "^5.3"
15 }
16 }
Require 35
Ah, there we go! You can see that our package is tucked away safely in the require-dev
section. That’s just what we wanted!
In the next chapter, we’ll be taking a look at version numbers of packages.
8. Version Numbers
Up until now, we’ve been installing only the latest version of our dependency pack-
ages. This is usually the best option since it’s good to keep up to date. However, what
if a new version of a package exceeds your version of PHP? What if the library changes
completely between major versions? We may not have time to update our code. We’ll
need to use the older version for a while, won’t we?
In this chapter, we’ll list the different ways that we can enforce version restrictions
upon our dependencies. First, we’ll need to take a look at our composer.json file.
1 {
2 "require": {
3 "nesbot/carbon": "^1.21"
4 }
5 }
We’ve simplified our configuration file to only the require block to simplify the
examples in this chapter. Here, we’ve installed the latest version of the Carbon library.
We’ll use this to play with different version numbers.
In all of the examples below, Composer will attempt to install the latest version of the
package, within the version constraints provided.
Exact
Specifying an exact version number is easy. If we take a look at the packagist page for
Carbon1 , we’ll see the available versions displayed on the right-hand side. We’ll set our
version to 1.19.0 by editing our composer.json to reflect the following.
1
https://packagist.org/packages/nesbot/carbon
36
Version Numbers 37
1 {
2 "require": {
3 "nesbot/carbon": "1.19.0"
4 }
5 }
We’ve updated the version for nesbot/carbon to the intended version number. How-
ever, before we can take advantage of the new version, we’ll need to instruct composer
to check our new composer.json and update our dependencies accordingly. We can
do this by using the update command. Let’s try that now.
1 $ composer update
2 Loading composer repositories with package information
3 Updating dependencies (including require-dev)
4 - Removing symfony/translation (v3.0.4)
5 - Installing symfony/translation (v2.8.4)
6 Loading from cache
7
8 - Removing nesbot/carbon (1.21.0)
9 - Installing nesbot/carbon (1.19.0)
10 Loading from cache
11
12 Writing lock file
13 Generating autoload files
Composer will uninstall the previous version of Carbon, and install the version that
we’ve requested. You’ll also notice that it has updated Carbon’s dependencies to the
appropriate versions. You’ll need to use composer update whenever you want Com-
poser to read the changes in your composer.json file, and update your dependencies.
For this reason, and to simplify the examples, I won’t mention the command in the
next sections.
Comparison Operators
Composer can understand comparison operators within its version strings. You’ll no
doubt be familiar with some of these operators from your time with the PHP language.
Here are the ones we can use.
Version Numbers 38
For example, we can use any combination of operators in the following fashion.
Install a version which is greater than, or equal to 1.19.0 OR the exact version 1.18.0.
You can string together as many comparison operators as you like. You probably won’t
need something so complicated, though!
Ranges
Ranges can be used to enforce that an installed version of a package exists between
two values. Here’s an example.
Install a version of Carbon that falls between 1.12.0 and 1.19.0. Simply use a hyphen
to separate the versions that you’d like your package to fall between.
Wildcard
You can place a * asterisk character into a version string, to allow for wildcard version
segments. Let’s take a look at an example.
1 "nesbot/carbon": "1.12.*"
Here we have places the wildcard on the final segment of the version number. This
means that Composer can install any version that starts with 1.12. For example,
versions 1.12.0, 1.12.5 and 1.12.250 are all compatible.
Version Numbers 39
Tilde
Right, so this one can get a little complicated, but I’ve found an easy way to explain it.
Consider the following:
Whenever you use a version that is prefixed by a tilde, you should be thinking about
the last part of the version number. The tilde allows that number to go to its maximum
value. For example, in the version above, 1.456 would be valid, but 2.0.0 would not.
Let’s try another example.
Once again, Composer will only increment the last part of the version number. For
example, 1.12.67 is fine, but 1.13.0 is not!
See? Simple!
Caret
The caret version number format is the preferred method of ensuring compatibility
with other packages. This should be your go-to method of locking version numbers.
Don’t worry; it’s super easy to understand!
Caret values start with… a caret! Here’s an example.
The caret will only install versions of the library without breaking changes. Using se-
mantic versioning, updating the first part of the version number indicates a breaking
change. This means that the example above will install any package up to, but not
including 2.0.0.
There’s one catch. Well… not catch. It’s just how it functions! For version numbers that
are less than 1.0, the caret version format will install the latest version of a package,
up to its max ‘minor’ version segment.
For example, consider the following package:
Version Numbers 40
1 "nesbot/carbon": "^0.7"
This will install the latest version up to, but not including 1.0.0. Simple, right?
In the next chapter, we’ll be taking a look at autoloading.
9. Autoloading
In an earlier chapter, I told you that you won’t have to worry about including your
files anymore. That was true, but first we have to configure Composer to support it.
There are a few different methods of autoloading our files. You can use one of them
or a combination of them. Let’s take a look at each of them, starting with the most
simple one.
Files
First, we’ll need to create an autoloading section within our composer.json file. We
should make it a JSON object. Here’s an example.
There, we’ve added a new object called autoload. Now we can take advantage of
Composers file-loading functionality. We can define a list of files that should be
includeed by default. This way, we won’t have to place a bunch of include calls within
our code.
Here’s an example:
41
Autoloading 42
1 {
2 "name": "dayle/composer-example",
3 "authors": [
4 {
5 "name": "Dayle Rees",
6 "email": "[email protected]"
7 }
8 ],
9 "require": {
10 "nesbot/carbon": "^1.21",
11 "illuminate/container": "^5.2"
12 },
13 "require-dev": {
14 "phpunit/phpunit": "^5.3"
15 },
16 "autoload": {
17 "files": [
18 "path/to/first.php",
19 "path/to/second.php",
20 "path/to/third.php"
21 ]
22 }
23 }
It’s as simple as that! We create an array called files inside our autoload object,
and within, we specify a bunch of PHP files that are relative to the composer.json
file. When our application bootstraps, these files will be included automatically by
Composer.
That’s a simple method, isn’t it? Let’s try something more interesting.
Classmap
Next, we have the classmap loading mechanism. As the name implies, this one should
only be used for loading classes. Here’s an example.
Autoloading 43
1 {
2 "name": "dayle/composer-example",
3 "authors": [
4 {
5 "name": "Dayle Rees",
6 "email": "[email protected]"
7 }
8 ],
9 "require": {
10 "nesbot/carbon": "^1.21",
11 "illuminate/container": "^5.2"
12 },
13 "require-dev": {
14 "phpunit/phpunit": "^5.3"
15 },
16 "autoload": {
17 "classmap": [
18 "classes"
19 ]
20 }
21 }
We’ve created a classmap array within our autoload object. In here, we specify a list of
locations where our application classes exist. Next, we need to run a new command.
Let’s try it now.
1 $ composer dump
2 Generating autoload files
When we use the dump command, Composer will examine all of the folders that we’ve
specified (and their subfolders) looking for PHP classes within files. For each class it
finds, it will add it to a map, associating it with the class that it’s contained within.
When you try to use the class in your application, then Composer will look at the map,
and automatically include the file in which the class is held. That’s pretty handy, isn’t
it?
The only problem is that you have to run dump whenever you create a new class. That’s
a little inconvenient, isn’t it? Let’s see if there’s a better way.
Autoloading 44
PSR-0
The PSR-0 loading method requires organising and naming your classes in a specific
way, according to the PSR-0 standard set out by the PHP-FIG1 (Framework Interop
Group). First, we’ll need to decide on a namespace for our application. Let’s use
Dayle\Awesome, shall we?
First, we’ll create a class. We’ll call it Blog. This means that the fully qualified class
name will be Dayle\Awesome\Blog. The next part is really important. We need to get
this right. We’ll place the class in the following file.
1 src/Dayle/Awesome/Blog.php
We’ve put our class inside a folder structure that consists of a folder called src,
then subfolders for each segment of the namespace. This is the structure for PSR-
0 autoloading and is a convention that must be followed for this loading mechanism
to work. The src part is customisable, but I prefer to use src in most situations.
Next, we’ll need to tell Composer where to find our class. Only, we’re not going to be
using a class map this time. Let’s lead with an example.
1 {
2 "name": "dayle/composer-example",
3 "authors": [
4 {
5 "name": "Dayle Rees",
6 "email": "[email protected]"
7 }
8 ],
9 "require": {
10 "nesbot/carbon": "^1.21",
11 "illuminate/container": "^5.2"
12 },
13 "require-dev": {
14 "phpunit/phpunit": "^5.3"
15 },
16 "autoload": {
17 "psr-0": {
1
http://www.php-fig.org/
Autoloading 45
18 "Dayle\\Awesome\\": "src"
19 }
20 }
21 }
Here we’ve created a psr-0 object within autoload. Inside, we’ve listed our namespace,
along with the directory that it can be found within. If we run composer dump,
Composer will record that all classes for the namespace Dayle\\Awesome can be found
in the src directory.
Once we’ve run dump once, we never have to run it again. Should we create a new class
within the above namespace, as long as it uses the correct file path, then Composer
will know how to find it. Using this method, you can add as many namespace prefixes
as you like.
Here are a few examples of class to location maps when using PSR-4 autoloading.
• DayleAwesomePanda - /src/Dayle/Awesome/Panda.php
• DayleAwesomeBookCover - /src/Dayle/Awesome/Book/Cover.php
• DayleAwesomeGeniusMegaPlan - /src/Dayle/Awesome/Genius/Mega/Plan.php
Well actually, there’s a further improvement we can make. Let’s take a look at the next
section.
PSR-4
PSR-4 autoloading follows a similar format to PSR-0, only that you don’t have to
provide a full directory structure for the entire namespace. This is certainly my
preferred autoloading method. I don’t like large extended treeviews in my editor, and
this method helps to prevent that situation.
First, let’s look at the loading definition:
Autoloading 46
As you can see, we’ve not changed much. Just fiddled that pesky little zero and made
it a four. Let’s say we have the class Dayle\Awesome\Super\Blog. Using PSR-0, where
would you expect it to live on disk?
Perhaps in /src/Dayle/Awesome/Super/Blog.php?
Quite correct! I can tell you’re taking this in. That’s right; we need to define the
structure for the fully qualified class name within our source directory. Let’s take a
look at what the location will be when using PSR-4 autoloading, shall we?
You see, Composer knows that the Dayle\Awesome namespace lives in the source
directory, and using PSR-4 we need not create those namespace sub-directories.
Instead, we’ll simply create directories and classes that are relative to the defined
namespace.
Here are a few examples of class to location maps when using PSR-4 autoloading.
Autoloading 47
• DayleAwesomePanda - /src/Panda.php
• DayleAwesomeBookCover - /src/Book/Cover.php
• DayleAwesomeGeniusMegaPlan - /src/Genius/Mega/Plan.php
Whenever possible, I’d recommend using a PSR-4 class layout and autoloading mech-
anism. It’s certainly the preferred method of our time.
In the next chapter, we’ll be taking a look at some important commands that can be
used with the Composer binary.
10. Commands
The Composer CLI client has a vast number of commands that we can use to support
our PHP development. If we provide no arguments to the composer executable, then
we’ll receive a list of all possible commands.
Here’s the output.
1 ~ composer
2 ______
3 / ____/___ ____ ___ ____ ____ ________ _____
4 / / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
5 / /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ /
6 \____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
7 /_/
8 Composer version 1.2-dev (d11eff27d07dcbbbfe3a6ae2fa4fd5e24f7ed807) 2016-05-09 2\
9 0:45:46
10
11 Usage:
12 command [options] [arguments]
13
14 Options:
15 -h, --help Display this help message
16 -q, --quiet Do not output any message
17 -V, --version Display this application version
18 --ansi Force ANSI output
19 --no-ansi Disable ANSI output
20 -n, --no-interaction Do not ask any interactive question
21 --profile Display timing and memory usage information
22 --no-plugins Whether to disable plugins.
23 -d, --working-dir=WORKING-DIR If specified, use the given directory as workin\
24 g directory.
25 -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for norma\
26 l output, 2 for more verbose output and 3 for debug
27
28 Available commands:
29 about Short information about Composer
30 archive Create an archive of this composer package
48
Commands 49
As you can see, there are too many commands for one chapter to cover. At least in the
first release of this book! In this chapter, we’ll take a look at some of the more useful
Commands 50
commands, and if you feel that something is missing, just send me a message and I’ll
be sure to add it!
Self Update
Composer is in active development. This means that there are new versions of
Composer being released at a regular interval.
To take advantage of all the bug fixes and new features that can be found in each
release, we’ll want to make sure that we’re using the latest version. Fortunately,
Composer is able to update itself. Simply run the self-update command, and we can
be sure that we’re running the latest version of composer.
Here’s an example.
1 ~ composer self-update
2 Updating to version d11eff27d07dcbbbfe3a6ae2fa4fd5e24f7ed807.
3 Downloading: 100%
4 Use composer self-update --rollback to return to version 64b0d721838cdceef679761\
5 c5cf69a0d070d14c9
As the output states, if we’re unhappy with the newly installed version of Composer,
we can use the --rollback switch to the self-update command to return to the
previous version. I’ve never needed to use this myself, but it’s good to know that it’s
available, isn’t it?
Init
The composer init command will allow us to create a new composer.json file by
answering a few questions about our project. Many default values have been provided
to make the process much easier. Here’s an example.
Commands 51
1 ~ composer init
2 Welcome to the Composer config generator
3
4 This command will guide you through creating your composer.json config.
5
6 Package name (<vendor>/<name>) [daylerees/daylerees]: daylerees/demo
7 Description []: My demo package!
8 Author [Dayle Rees <[email protected]>, n to skip]:
9 Minimum Stability []:
10 Package Type []: library
11 License []: MIT
12
13 Define your dependencies.
14
15 Would you like to define your dependencies (require) interactively [yes]? no
16 Would you like to define your dev dependencies (require-dev) interactively [yes]\
17 ? no
18
19 {
20 "name": "daylerees/demo",
21 "description": "My demo package!",
22 "type": "library",
23 "license": "MIT",
24 "authors": [
25 {
26 "name": "Dayle Rees",
27 "email": "[email protected]"
28 }
29 ],
30 "require": {}
31 }
32
33 Do you confirm generation [yes]? yes
If you prefer to construct your composer.json file by hand, then you’re more than
welcome to skip this command!
Commands 52
Create Project
The create-project command can be used to download a Composer project, and
install all of its dependencies. For example, I frequently download and setup the
Laravel framework by running the following command.
I’ve gone ahead and cut out a bunch of the dependencies to simplify the example,
but it’s clear to see that the Laravel project package has been downloaded, and it’s
dependencies installed. Not only that, but Composer has run a number of scripts that
are defined in laravel/laravel’s configuration file that are used to configure our new
Laravel application. One command, and we’re ready to start working on our new blog.
The first parameter to the command is the name of the package that we wish to
download. The second parameter is the location that we wish to install the project.
It’s that simple!
Install
We can use the install command to install our dependencies. If a composer.lock file
exists, then Composer will install the dependency versions from there, otherwise, it
will install the dependencies listed in the composer.json file.
Commands 54
You’ll find more about this process in the next chapter on the Composer lock file.
Update
The update command will attempt to update our dependencies to the latest version
of each package that is compatible with it’s defined version. We’ll want to use this
command from time to time to ensure that we’re running the latest versions of our
dependencies, so that we can take advantage of bug fixes and new features.
You can optionally provide a parameter to the update command. The name
of a single package to update. This can be useful when versioning the
composer.lock file, since updating every package would be more likely to
cause Git conflicts!
Search
The search command can be used to search for packages available on Packagist using
keywords. Personally, I prefer to browse the Packagist website to find my packages,
but if you happen to be a command-line wizard, then this might be the right option
for you.
Here’s an example.
Info
The info command is great for sharing an overview of our application dependencies.
We’ll find the package name, the installed version, and the package description for
each installed package. Reading the descriptions is a great way of understanding the
purpose of each dependency.
Let’s take a look.
1 ~ composer info
2 sebastian/environment 1.3.6 Provides functionality to handle H\
3 HVM/PHP environments
4 sebastian/exporter 1.2.1 Provides the functionality to expo\
5 rt PHP variables for visualization
6 sebastian/global-state 1.1.1 Snapshotting of global state
7 sebastian/recursion-context 1.0.2 Provides functionality to recursiv\
8 ely process PHP variables
9 sebastian/version 1.0.6 Library that helps with managing t\
10 he version number of Git-hosted PHP projects
11 swiftmailer/swiftmailer v5.4.2 Swiftmailer, free feature-rich PHP\
12 mailer
13 symfony/console v3.0.5 Symfony Console Component
14 symfony/css-selector v3.0.5 Symfony CssSelector Component
15 symfony/debug v3.0.5 Symfony Debug Component
16 symfony/dom-crawler v3.0.5 Symfony DomCrawler Component
17 symfony/event-dispatcher v3.0.5 Symfony EventDispatcher Component
18 symfony/finder v3.0.5 Symfony Finder Component
19 symfony/http-foundation v3.0.5 Symfony HttpFoundation Component
20 symfony/http-kernel v3.0.5 Symfony HttpKernel Component
21 symfony/polyfill-mbstring v1.1.1 Symfony polyfill for the Mbstring \
22 extension
23 symfony/polyfill-php56 v1.1.1 Symfony polyfill backporting some \
24 PHP 5.6+ features to lower PHP versions
25 symfony/polyfill-util v1.1.1 Symfony utilities for portability \
26 of PHP codes
27 symfony/process v3.0.5 Symfony Process Component
28 symfony/routing v3.0.5 Symfony Routing Component
29 symfony/translation v3.0.5 Symfony Translation Component
30 symfony/var-dumper v3.0.5 Symfony mechanism for exploring an\
31 d dumping PHP variables
32 symfony/yaml v3.0.5 Symfony Yaml Component
Commands 56
If you specify a package name as the first parameter to the same command, you’ll
receive a load of useful information about that package. Let’s take a look at this.
1 {
2 "require": {
3 "assassins/ezio": "1.1.0",
4 "assassins/edward": "1.1.2",
5 "templars/shay": "1.1.*",
6 }
7 }
We’ve clearly defined the version of two of our packages, but with our third tem-
plates/shay is a little more flexible, and we don’t care about the patch version
parameter. Anything beginning with 1.1 will do just fine.
Now it’s worth noting that these are fake packages. Don’t go and try to install them.
I promise you; they won’t work. I’ve just been playing way too much Assassin’s Creed
lately.
You could say that the composer.json is a very ‘rough’ guide to the versions that should
be installed. It’s not precise because we have these wildcard versions available to us.
It’s a ballpark blueprint for our application dependency hierarchy.
We don’t have a composer.lock file at the moment, but the second that we run the
composer install command.
Behold, we’ve executed composer install and the mysterious composer.lock file has
appeared. If you take a look inside, you’ll notice that it’s pretty big!
57
The Lock File 58
Now it’s time for the big reveal. You see, while your composer.json file is a rough guide
to the dependency versions that Composer should install, the composer.lock file is an
exact record of the dependency versions that have been installed.
That’s right; it’s recording what Composer has installed for you, right down to the
commit hash. Here’s a little example:
1 "source": {
2 "type": "git",
3 "url": "https://github.com/templars/shay.git",
4 "reference": "98c313c831e5d99bb393ba1844df91bab2bb5b8b"
5 },
You see that big long string? That’s the exact commit version that was installed
when Composer followed the directions in your composer.json file. It also keeps track
of all the versions of your dependencies’ dependencies. Even your dependencies’
dependencies’ dependencies. Even… Well, you get the idea. Your entire application
dependency hierarchy will have their versions ‘locked’ in your composer.lock file.
Why is this useful? Well, it’s simple. Go ahead and delete your vendor directory.
That will remove all of the installed Composer packages that are your applications
dependencies.
It’s time to run composer install again. This time, Composer will see that you have
a composer.lock file in the directory. Instead of finding compatible versions of your
dependencies to fulfill the composer.json file, it will install the exact version of your
dependencies as defined in your composer.lock file.
This means that we’ve got the exact version of our dependencies that we had installed
before we deleted the vendor directory. That’s pretty nifty, right?
Time and time again I hear the question…
The answer to that question should now be apparent. If you want to record the exact
versions of your dependencies that have been used for your application, then yes you
should version your lock file. In most situations, this will be true.
If you’re working with a team, versioning the lock file will ensure that you’re all
working using exactly the same versions of your dependency packages. This can be
useful when debugging errors that happen for only one developer.
The Lock File 59
If you’re deploying your application using git, and you version your lock file, you can
be sure that the exact version of your dependencies that you tested locally with, will
be used in production.
Why is it so important to be using the exact versions of your dependencies?
Let’s consider that you don’t version your lock file. You composer install and because
of the 1.1.* version of the templars/shay package, Composer installs version 1.1.4.
Between this install, and the time that you deploy to your production environment,
the templars/shay team have released version 1.1.5. Ouch! Unfortunately, the 1.1.5
version of the package has a serious bug in it.
When you deploy your application to production, Composer installs 1.1.5 of the pack-
age, and your application explodes, destroying the whole universe, as per Abstergo’s
master plans.
You see, if you’d have versioned your lock file, the composer install on production
would have respected the lock file, and used version 1.1.4 of templars/shay that you
had tested in production. The world would be safe for the time being.
In a sentence, the Composer lock file is a guarantee of the dependency versions that
will be installed, right down to an individual commit level.
Finally, what would cause the composer.lock file to change? All the time, I see people
using composer update whenever they update their composer.json file to get the new
packages. This is a bad move! You should be using ‘composer install’, because it will
install your new package without updating the versions of your other packages. This
would be much safer.
Here’s a list of some actions that will update your composer.lock file.
• You run composer install for the first time, and the composer.lock file is
updated to the installed versions of the dependencies.
• You run composer install after adding a new package, and the exact version of
the new package is added to the composer.lock file.
• You run composer update, and all of your packages are updated to their latest
versions according to the composer.json. This will update the exact version
records in the composer.lock file.
• You run composer update package/name and the version of the specified package
is updated to it’s latest version observing the package version hint in com-
poser.json. The exact version in the composer.lock file is updated to respect
this.
This means that composer install is a “safe” command, and will only add packages to
your composer.lock file.
The Lock File 60
The command composer update is a “risky” command, because it will directly manip-
ulate the version numbers held within your composer.lock file.
Hopefully, you’ve now deciphered the mystery of the composer.lock file, and also have
a craving to play the Assassin’s Creed games. (You should. They are fantastic!)
In the next chapter, you’ll find information about updates to the book. Thanks for
reading!