Managing your dependencies manually in any programming language is a huge pain. This is why in most programming languages today you will find that they all have some implementation of a dependency management system or sometimes a package manger. Composer is the dependency management system that you will find inside most modern PHP projects.
My goal is to try and show you the basics of using Composer to install packages and libraries into your future projects. We will be using Composer quite often in all of our Laravel lessons as well as some of the more intermediate PHP lessons here at Treehouse.
We will need to understand what Composer is, what it will do for us, and explore the why before we get into the how. Composer manages all of your projects dependencies and keeps them in a clean folder structure and tracks versions as well. For example, if your project needs to have PHPUnit installed for testing, you would tell Composer that you need PHPUnit and the specific version you want. Then you would run an install command. Composer would then go out and search for the package and version you requested and download it for you. Not only will it download your requested package, but also any other packages that your requested project requires to work. PHPUnit, as an example, uses 16~ unique packages to work. It will keep all of these dependencies in a folder named vendor which helps to keep your project nice and neat.
To get started on the how, we will build out the scenario mentioned above.
Step One: Getting Composer
We will be discussing install on a Mac in these examples. If you want to install composer on other platforms feel free to check out the instructions here.
There are two directions you can choose to take when installing composer. Installing it locally to a project is one method, but for us we will be installing it globally so we can use it anywhere on our system. As for installing Composer globally we then have to make another choice. One is to install it to our system using homebrew, a package manager for OSX, or to install it through a curl command. For this example we will be using the curl command and following the instructions here.
inside of your terminal you will want to run the following command:
`curl -sS https://getcomposer.org/installer | php`
The curl command, with the -sS flag for a silent install unless there are errors, takes a url for the composer installer script to be downloaded. Once downloaded the installer is then piped or redirected to your local PHP interpreter, which will run the script.
Once the install is complete you will need to move the composer executable to your local bin directory with the following command
`mv composer.phar /usr/local/bin/composer`
Once the composer file has been relocated you can now use it anywhere on your system. If you happen upon a permissions issue when moving the file, run the same command again with `sudo` in front of the command.
We can check easily if Composer is properly installed by running the composer command with a flag to check the version.
Now we will create a new folder on our system to use for our example, I am calling my folder ‘composer-example’
Once the folder is created we will need to create a blank file within called ‘composer.json
Now lets open our composer.json file in your editor of choice and add the following code.
The only section we have added here is called ‘require’ and as you might have guessed this is where we will list all of our packages that are required by our project.
On the very next line we are saying what package we want followed by the version requirements. Let’s take a closer look of what each of these two parts do in detail.
Package Name Definition
The package name consists of two parts separated by a forward slash. A vendor name and them the project’s name.
In our case the vendor is phpunit and the project is also phpunit. This method allows us to have a different vendors with the same project name. So for instance if I had a project also called phpunit, which I don’t, it would be listed as hamptonpaulk/phpunit and would not conflict with the phpunit’s phpunit project.
Package version is specified with the standard practice of semantic versioning notation. The standard, in brief, is as follows:
- A version number will have three different sections separated by a period or dot (.)
- Those sections are defined as:
- You will increment this number when make changes to the project functionality and those changes will break the existing API
- You will increment this number when make changes to the project functionality and those changes were made in a backwards compatible manner
- You will increment this number when make bug fixes to the project and those changes were made in a backwards compatible manner
In composer we are able to be very flexible or very strict with our version specifications for the dependency. The example give on composer’s website mentions the version requirement for installing monolog. They were requiring version 1.0.* of monolog. Using the * wildcard means any version in the 1.0 branch. It would match 1.0.0, 1.0.2 or 1.0.20 versions of monolog.
If you want you can specify the exact version of a project by giving all three numbers for major.minor.patch. You can also request a range, multiple ranges.
Say you would like a project version that is greater than or equal to version 1.2.* but you do not want to ever download any version past 1.*, or no 2.0 and up. You can do just that by specifying “>=1.2,<2.0”
Which is saying that you are expecting versions to follow semantic versioning and you know that 2.0 might break your project. It turns out that there is also a short cut for this exact need in Composer. You can simply use a tilde (~) mark. So for the above example of “>=1.2,<2.0” we can just use “~1.2” instead! This has even more power if you use it as a way to stop updating before the ‘next significant’ release. For instance if we say we want “phpunit/phpunit”: “~4.3.0”, this will be the equivalent of “>=4.3.0,<4.4”
Now that we have readied our composer.json file with our project and version dependency needs, let’s get them installed to our project by using the composer install command in our terminal.
Now that phpunit and all of its dependences are installed in the vendor folder, we will need to create a file of our own to use PHPUnit in our example project.
Now create a new file and call it ‘example.php’ in the root of your composer-example folder. This will allow us to add the final step for getting our required dependencies into our project through autoloading. After opening up a php tag in our example.php file we will need to add a single line of code.
This autoload.php file in the vendor folder was generated for us by Composer when we installed our dependancies earlier with the composer install command. Now we need only to include the autoload file and all of our current dependencies and any further updates or additions will be available that file.
I will add a bit of code to the example file to include a couple of test cases.
Since PHPUnit is also a command line tool, it installs that command in the vendor/bin folder for us to use, so that the package does not have to be installed system wide.
To run our test we will execute the following terminal command, assuming you are in the root folder of your project:
If everything went according to plan you get two passing test cases!
Hopefully this has given you a good overview of how to use composer to install and manage project dependencies within your PHP projects!
If you haven’t already, start learning PHP today and join our PHP track.