Getting started with Composer

Composer is a dependency manager for PHP and is used in all modern PHP frameworks like Symfony, Laravel, CakePHP, etc. It is one of the most recommended tools that solves fundamental issues in the majority of web projects.

This article will show you how to create a simple images resizing tool using composer packages and how to automatically load them into your project.

Getting started guide with Composer

Composer solves the following issues:

  • dependency resolution for PHP packages
  • autoloading solution for PHP packages
  • keeping all packages updated and make updating process simple and fast

Create the project

This tutorial was created on a UNIX environment (Mac OS X / Linux). If you are using Windows, please install Ubuntu or any other linux distribution inside VirtualBox and you can follow the steps from this tutorial.

Configuration used to create this tutorial:

  • Mac OS X (Any Linux distribution can be used. For Windows I suggest to install an UNIX OS under Virtual Box)
  • curl (Mac OS X: brew install curl or for Ubuntu: sudo apt-get install curl)
  • PHP 5.5.9
  • PHP Storm (or any other editor like: Aptana, Zend Studio, Sublime, Vim, etc)
  • optionally you may use GIT to save your progress

First thing to do would be to create the project directory and go in:

# create directory
mkdir composer_tutorial

# and then go in newly created directory
cd composer_tutorial
If you're using PhpStorm, please install composer plugin. It will help you with valuable tooltips when you edit composer.json file

Next step to our little project is to create composer.json file where you define required PHP packages that we will need.

# create composer.json
touch composer.json

Then open the composer.json file in your editor and add kisphp/thumbnails as a required dependency:

{
  "require": {
    "kisphp/thumbnails": "~1.1"
  }
}

Before going further and installing the required package, we'll need to create a directory where we'll add our own custom classes. For this we'll create the src directory and we'll tell composer to autoload libraries from this directory too.

mkdir src

And now update composer.json file to look like this:

{
  "require": {
    "kisphp/thumbnails": "~1.1"
  },
  "autoload": {
    "psr-0": {
      "": "src/"
    }
  }
}

As you can see, we define src directory to use PSR-0 autoload standard. You can read here more about it. In src directory we'll create our library classes with our own namespaces. If you don't know what PHP Namespaces are or you don't fully understand them, then please watch this KnpUniversity Tutorial which lasts 2 minutes.

For next step, we'll have to install composer if you don't have it already. For this, run the following commands which can be found on Composer download page

php -r "readfile('https://getcomposer.org/installer');" > composer-setup.php
php -r "if (hash_file('SHA384', 'composer-setup.php') === '7228c001f88bee97506740ef0888240bd8a760b046ee16db8f4095c0d8d525f2367663f22a46b48d072c816e7fe19959') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

After downloading composer, run the following command to install all necessary packages:

php composer.phar install
You will notice that composer.lock file will be created. The role of this file is to record the exact versions of the repositories that are installed so they can be reinstalled. This means that if you have a version spec of 1.* and your co-worker runs composer update which install 1.2.4 and then commits the composer.lock file, when you run composer install you'll get the same version, 1.2.4 even if version 1.3.0 has been released. This ensures that everybody who's working on the same project has the same exact version.

For next step we'll create the index.php file that will be accessed by the browser. For this, we'll use the same structure as Symfony framework does and we'll have web directory which will be used as public document root. Create web directory by running the following command:

# create web directory
mkdir web

Inside web directory we'll create index.php file which will be used to serve our application to the public.

# create index.php file inside web directory
touch web/index.php

Now open index.php file in your editor (PhpStorm for example). When we run the command php composer.phar install, composer automatically created an autoload file which knows where our classes and third party classes are located and will load them for us, without using require or include.

Add the following code inside index.php file.

<?php

require_once __DIR__ . '/../vendor/autoload.php';

Note that vendor directory is not in the same directory with index.php file and because of this we need to use /../ to find vendor in parent directory.

Now, if you run in terminal (console):

# start PHP Built-in Server
php -S localhost:8000 -t web

and open http://localhost:8000 you should see a blank white page.

To close the build-in PHP server, press CTRL + C

Next, let's create the original sizes images directory:

mkdir images

Now let's download an image into our images directory by typing this command in the terminal:

curl https://upload.wikimedia.org/wikipedia/commons/c/c1/PHP_Logo.png > images/php-logo.png

At this point, you should see the image in your images directory.

Let's move forward and create our helper class.

# create Project directory in src
mkdir src/Project

# create Thumbnail.php class
touch src/Project/Thumbnail.php
Please note that on Linux directories and files are case sensitive, while on Windows and MAC they are not. On Linux, image.jpg, Image.jpg, ImaGe.jPg are three different files, while on Windows and Mac OS you'll have only one file instead of three files.

Open src/Project/Thumbnail.php file and paste the following code inside:

<?php

namespace Project;

use Kisphp\ImageResizer;

class Thumbnail
{
    /**
     * @var ImageResizer
     */
    protected $imageResizer;

    public function __construct()
    {
        $this->imageResizer = new ImageResizer();
    }

    /**
     * @param string $filename
     * @param int $width
     * @param int $height
     *
     * @return string
     */
    public function create($filename, $width, $height = 0)
    {
        $this->imageResizer->load(__DIR__ . '/../../images/' . $filename);
        $this->imageResizer->resize($width, $height);

        return base64_encode($this->imageResizer->display());
    }
}

Thumbnail class, will create an object of type ImageResizer and will take care of resizing process and encoding the image hash.

Next, open again file web/index.php and paste this code:

<?php

// initialize repositories autoloader
require_once __DIR__ . '/../vendor/autoload.php';

// create thumbnail helper class
$thumbnail = new \Project\Thumbnail();

// generate small thumbnail image
$image = $thumbnail->create('php-logo.png', 300, 200);

// display image in the browser
echo '<img src="' . $image . '" alt="my image">';

Now, if you start again built-in php server:

# start PHP Built-in Server
php -S localhost:8000 -t web

and open http://localhost:8000 you should see the image resized to specified dimensions.

Other use cases for thumbnail resize dimensions:

Resize by width

$thumbnail->create('php-logo.png', 300, 0);
// or
$thumbnail->create('php-logo.png', 300);

Will resize the image to have 300px width and height will be calculated conform to image ratio

Resize by height

$thumbnail->create('php-logo.png', 0, 250);

Will resize the image to have 250px height and width will be calculated conform to image ratio

Display original image dimensions

$thumbnail->create('php-logo.png', 0, 0);

Image will be displayed at original dimensions, without resize.

You may download project files from Github