Composer primer

Posted on the 14th of April 2013.

Please note that this article acts as an introduction to Composer to be included with my upcoming title 'Code Bright' for Laravel. However, it could just as easily represent a guide to composer for newcomers without the intention of using the Laravel framework. Enjoy!

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 to 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 where 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. However, 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, 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 authors 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 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 the minimum-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 situation thanks to it’s 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 projects 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.

Now this isn’t a PHP book so I won’t describe namespaces in detail, but 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 name-spaced 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 forward 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 you PHP version. In fact, if you are using anything less than PHP 5.3 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), then 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! Yey!

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..

$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 ran in 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 using 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!

← Back to index.