× Introducing Rollout, An awesome deployment system for your PHP webapps. [More info]
Thu 26 Jul 2018

What is PHP Composer

Composer, the dependency manager for php has many fundas, where its not clear for many folks out there. Couple of things are:

Should I execute composer install or composer update. In other words, When should I run composer install and composer update ? Also, should I commit composer.json to my version control system? Let us try to understand this in a better way.

Why should I use PHP composer ?

First, lets get to know about what is composer ? and should you really use it at all ? During early stages of php web development reusable libraries or classes of PHP are available in individual classes. Lets say, you need to use PHPMailer class for sending emails. To use PHPmailer functionalities we need to download the phpmailer classes and include it. Consider phpmailer class uses some other libraries like formatter class that was developed by a different developer, At times phpmailer libraries might give you the formatter library also bundled with phpmailer in one zip file. Sometimes, they just give reference to the library formatter. We have to download it separately and include it in your project.

Just imagin, if the formatters requires another library called string processor, you need to download the string processor library manually wasting lot of time.

Another problem is that, Lets say, creator of phpmailer bundles formatter library and string processor libraries for you as one single bundle. Developer of formatter library adds a bunch of nice features, security fixes, bug fixes which you may not have a chance to get the updates. You are stuck with the stale version, that came with the phpmailer bundle. Or you don't have an easy way to catchup with the latest version and update security fixes of formatter library. All you need to do is download manually the formatter library again and include it in your project. Thats really a big time killer and unproductive. PHP composer removes all these big troubles for you. The important magic guy is autoload feature of php that autoloads or includes automatically the class files when it does not find it in memory, and another magic thing the composer does is, it generates this autoload function to magically to include all the required libraries.

Summing up ..

To sum up Composer gives you these fabulous mileage.

  • Saves a lot of time.
  • Composer automatically downloads all the dependencies of a given library recursively and keeps inside a folder called Vendor folder.
  • Puts all the includes or requires statements in a file called autoload.php. All you need to do is just include that file (autoload.php) and you are done.
  • Also, composer makes your life easier to download any specific version of a given dependency.
  • Composer makes sure you and your team have consistent, identical version of the libraries / dependencies.

What is composer.lock ?

Composers notes down all the versions of the the libraries that you use and its dependant libraries ( dependencies ) in file called composer.lock. Libraries or packages may require a specific version of PHP, prior to composer era there is no way to specify the version requirement, also there is no way mention the php extension it requires with composer. Now with composer, library developer can mention all the extension requirements, php version requirements if any in composer.json.

Example of composer.json

"require": {
    "php": "^7.1.3",
    "ext-mbstring": "*",
    "ext-openssl": "*",
    ...
}

if you have this requires snippet, composer will automatically check for you if your system, has the php version that is marked in the required section, and checks if the extensions are enabled. So easy right!

Last but not the least, you can easily update your libraries with the latest versions.

Should i use composer install or composer update ?

Lets first get to know, what is composer update and what is composer install ? so that, we know when to use them.

Composer install

When you do a composer install. composer looks for composer.json file in the current directory and starts downloading the libraries or dependencies present in the composer.json recursively. If your library usage is as follows

project uses 
    - phpmailer uses 
        - formatter uses
            -  String processor uses
                -  pattern matching libriaries. 

Composer will download all the libraries phpmailer, formatter, stringprocessor and pattern matching libraries. Once the download is done it creates a file called composer.lock with details of the exact versions of all the libraries it downloaded.

Why should composer creates composer.lock file?

if it does not do that, it doesn't know what is the version it downloaded, so what is the problem if it doesn't knew what version of a library it downloaded. It will download again and again when composer install is accidentally executed.

Composer update

This is one of the other problem that composer solves, getting the recent updates for all the libraries or packages that you have used in your project or in simple terms updating your libraries that you have already downloaded to its latest version just at one command. Wow thats so lovely!

What is php autoload ?

Its perhaps php autoload feature makes composer to work. Autoloading is nothing but, everytime when php can't find the class to include when you try to instantiate the class it executes the autoload function. So this technique is used to give you an opportunity to build the logic of file inclusion in this autoload function. One simple way how you can do it is here.

For example:

File: ./myClass.php

<?php
class myClass {
    public function __construct() {
        echo "myClass init'ed successfuly!!!";
    }
}
?>

File: ./index.php
<?php
// we've writen this code where we need
function __autoload($classname) {
    $filename = "./". $classname .".php";
    include_once($filename);
}

// we've called a class ***
$obj = new myClass();
?>

If you observe the above snippet, we are not including the myclasses file anywhere like include 'myClass.php', This is the magic that __autoload() does it for you.

Note: you should keep the classname and the filename same for this magic to happen.

Should I commit composer.json in git repository ?

Yes, you should commit composer.json and also composer.lock files, which are very important for these glorious reasons.

Every member of the project should be working on the identical versions of the library or package they use. Otherwise, it would introduce a lots of discripencies which are very hard to debug.

Lets say, you are adding a new member to your project, the expectation is to have exactly same versions of your packages or libraries that you are using, otherwise its going to be a nightmare for you and him sorting out the bugs that arises, if the versions are different, things can break, or you may not be having a feature he has, because he recently got the latest version of the package. So how you achieve this ? One simple solution is, just commit the dependencies you have used in your git and do a push to github and let him download from github. The problem with this approach is it takes too much of disk space and consume bandwidth and time to download and upload the code of all the dependencies, libraries or packages from bitbucket or github. So the best way is to commit only composer.json and composer.lock files. You may think commiting composer.json is suffice. I have a reason for composer.lock to be committed.

in Composer.json you mention the minimum expected version say 1.8 and composer always download latest version of 1.8, for example if 1.8.4 is the latest, composer will download 1.8.4. So what is the problem ? Not at all till now. Lets say the package developer have added a feature in 1.8.5 and that has introduced a bug. So when your new team member run composer install it will install 1.8.5 rather than 1.8.4. Again, this is a deviation from the rule that I mentioned every member of the project should be working with the identical version of the library or packages.

Hence, its one of the best practice to commit also the composer.json and composer.lock file in your git repo. add in your .gitignore file add the following line. vendor/ So that git will not worry about the vendor folder. Only your working directory or your computer where you have Project directory will have the full code base.

composer is well designed to check the presence of composer.lock file first. If it is there it gets versions of the packages to download from there, if composer.lock is not there it goes for composer.json and starts the process of downloading. So, when your new team member starts the project. He just need to executes composer install and it picks the exact version from composer.lock file in our case 1.8.4 of the package and downloads.

Hope, I have tried to explain composer in the best possible, let me know in the comment section, if I have missed anything important or give it a thumbs up.