Using Composer Dependency Manager

Using Composer Dependency Manager

In days gone by when you wrote a project in PHP you would often write all parts of the project yourself, or you probably had code components from previous projects that you copy and pasted into your new project. You may even have gotten a third party library from the web. Of course in these days gone by you also had to figure out how to load the code into your new project.

Composer Dependency Manager came along and changed the way we work. Together with Packagist you can often find the components your project needs and load them using composer. Composer takes care of the auto loading of these components because it implements the PSR-4 autoloading standard. Its also a dependency manager so it find the components dependencies and loads them for you too.

In this post we’re going to create a small mock project which gets the current USD /ZAR exchange rate. We’re going to log debug info and we’re getting the exchange rate from a remote server so we’ll use https requests.

In the past, for a project like this I would have written (or reused) a log class which I wrote and I would use something like Curl to get the remote data.

In the modern PHP world we train our minds to first go to packagist to see if we have components we can use. In our case we find that there is already a very popular and versatile logger component called Monolog. There’s also an http request / response component called guzzle. Our project is practically done already!

Installing Composer

You can install Composer in your working directory by using Curl to download it and PHP to install it. This is done on the command line with the following command:

curl -sS https://getcomposer.org/installer | php

This will download and execute composer and create a composer.phar file which is the composer binary which you use on the command line with various options.

This composer.phar file is local to the directory you installed it in. You can move the composer.phar file to your bin directory and make it executable and add it to your environment PATH to enable you to use composer from anywhere.

sudo mv composer.phar /usr/local/bin/composer

sudo chmod +x /usr/local/bin/composer

echo "PATH=/usr/local/bin:$PATH" >> ~/.bash_profile

Install PHP components with composer

Components in Packagist are named by vendor/package. If we do a search in Packagist for monolog we see that its full name is monolog/monolog. If we do a search for guzzle we see its full name is guzzlehttp/guzzle.

To install our two components simply run composer with the require argument followed by the package name.

composer require monolog/monolog

    ./composer.json has been created
    Loading composer repositories with package information
    Updating dependencies (including require-dev)
    Package operations: 2 installs, 0 updates, 0 removals
      - Installing psr/log (1.0.2): Loading from cache
      - Installing monolog/monolog (1.23.0): Loading from cache
    monolog/monolog suggests installing aws/aws-sdk-php (Allow sending log messages to AWS services like DynamoDB)
    monolog/monolog suggests installing doctrine/couchdb (Allow sending log messages to a CouchDB server)
    monolog/monolog suggests installing ext-amqp (Allow sending log messages to an AMQP server (1.0+ required))
    monolog/monolog suggests installing ext-mongo (Allow sending log messages to a MongoDB server)
    monolog/monolog suggests installing graylog2/gelf-php (Allow sending log messages to a GrayLog2 server)
    monolog/monolog suggests installing mongodb/mongodb (Allow sending log messages to a MongoDB server via PHP Driver)
    monolog/monolog suggests installing php-amqplib/php-amqplib (Allow sending log messages to an AMQP server using php-amqplib)
    monolog/monolog suggests installing php-console/php-console (Allow sending log messages to Google Chrome)
    monolog/monolog suggests installing rollbar/rollbar (Allow sending log messages to Rollbar)
    monolog/monolog suggests installing ruflin/elastica (Allow sending log messages to an Elastic Search server)
    monolog/monolog suggests installing sentry/sentry (Allow sending log messages to a Sentry server)
    Writing lock file
    Generating autoload files

composer require guzzlehttp/guzzle

    Using version ^6.3 for guzzlehttp/guzzle
    ./composer.json has been updated
    Loading composer repositories with package information
    Updating dependencies (including require-dev)
    Package operations: 4 installs, 0 updates, 0 removals
      - Installing guzzlehttp/promises (v1.3.1): Downloading (100%)         
      - Installing psr/http-message (1.0.1): Downloading (100%)         
      - Installing guzzlehttp/psr7 (1.4.2): Downloading (100%)         
      - Installing guzzlehttp/guzzle (6.3.3): Downloading (100%)         
    Writing lock file
    Generating autoload files

This creates a composer.json file and a composer.lock file. It also creates a vendor folder which contains the components. Because packages use semantic versioning composer is able to also keep your components up to date up to the but excluding the next major release. In other words if you install a component with version 1.0.4, then composer will update the component if a version 1.1.4 is released, but it will stop when the component’s major version changes, eg, it will not be updated to 2.0.0.

Use PHP Components

So far we’ve installed PHP’s Composer and then used that to require (install) the http guzzle and monolog components. We now need to use this in our project. We’re going to get the current USD / ZAR exchange rate from http://api.softsmart.co.za/exchange/. This gives us a json string with the rate:

{"from":"usd","to":"zar","rate":13.436604}

Take a look at the linked packagist pages above for monolog and guzzle. Each package shows a basic usage example which is what we’re going to use for this very basic example.

If you look in the vendor folder that composer created when you installed the components you will see an autoload.php file. This is what will autoload the components. You need to include just this one file and allow composer to autoload the components.

Once the components are used in your project, Composer will autoload them for you. Our project looks like this:

<?php
include __DIR__."/vendor/autoload.php";

use Monolog\Logger;
use Monolog\Handler\StreamHandler;

// create a log channel
$log = new Logger('usdToZar');
$log->pushHandler(new StreamHandler('/var/www/html/test/log', Logger::DEBUG));

// add records to the log
$log->info("About to get exchange rate");

$client = new \GuzzleHttp\Client();

try {
    $res = $client->request('GET', 'http://api.softsmart.co.za/exchange/');
}
catch (Exception $e) {
    print "An error occurred and has been logged. Please check the log file for info!";
    $log->error("http request error resulted in an error", array("error"=>$e));
    exit();
}

$log->info("http result: ".$res->getStatusCode());

if ($res->getStatusCode() != 200) {
    $log->error("http request failed", array("result"=>$res->getStatusCode()));
    exit();
}

if ( ! strstr($res->getHeaderLine('content-type'), "application/json")) {
    $log->error("Invalid http response content type", array("content-type"=>$res->getHeaderLine('content-type')));
    exit();
}

$exchange = json_decode($res->getBody());

print "1 usd = ".$exchange->rate." zar";

If we run through this code, on line 2 we include the composer autoload.php file.

We then use the use keyword to include our monolog files. I am not going into the streamhandler etc, that documentation is well written on the packagist page.

We include guzzle with: $client = new \GuzzleHttp\Client();

Notice that we use the full namespace in this newing up of the component.

We then call the methods on our log and guzzle objects to log events and the read the http stream. Once we have our data we convert the json string to an object and print out our data.

Conclusion

This is a very basic example of using composer and packagist to get and use PHP components. I hope this makes you think with each project that there may composer packages available for your use, rather than writing every line of code yourself.

Share

One thought on “Using Composer Dependency Manager

Leave a Reply

Your email address will not be published. Required fields are marked *