Composer (
getcomposer.org ) is a relatively new and already quite popular dependency manager for PHP. You can describe from which libraries your project depends and Composer installs the necessary libraries for you! Moreover, Composer is not a package manager in the classical sense. Yes, it operates with entities that we will call “packages” or libraries, but they are installed inside each project separately, and not globally (this is one of the main differences from the good old PEAR).
Briefly, how it works:
- You have a project that depends on several libraries.
- Some of these libraries are dependent on other libraries.
- You describe in your project those libraries that your code directly depends on.
- Composer finds the required versions of the required libraries for the entire project, downloads them and installs them in your project folder.
When creating Composer, authors took insights and inspiration from similar projects: npm for Node.js and Bundler for Ruby.
It was originally designed and developed by two people
Nils Adermann and
Jordi Boggiano , now more than twenty contributors participate in the project. The project is written in PHP 5.3, distributed under the MIT license and is available on
github .
')
The first commits were made in April 2011 and today Composer is in the alpha3 stage. However, it is already quite stable and is used by many popular PHP projects (for example,
Symfony 2 ). A list of projects using Composer can be viewed on the site
packagist.org - this is the official Composer repository of packages. By the way, at the recent Devconf 2012 conference, the developer of the Yii framework in his report mentioned that
Yii2 is also likely to use Composer.
In this article I will briefly describe the main features of Composer and we will try to create a demo project using Composer to load the necessary libraries. All examples will be available on github.com and bitbucket.org.
What can Composer?
- Download packages and their dependencies;
- by default, packages are downloaded from the official repository of packagist.org. Anyone can freely add their package there to make its installation as easy and convenient for the whole world as possible;
- packages can be downloaded not only from packagist.org, but also from any git, mercurial or svn repository;
- when downloading packages from github.com or bitbucket.org, no installed version control system (git or hg) is required, Composer works through the API of these sites;
- The git / hg / svn repository with the package can be located not only on one of the sites listed above, but in any other place, for example, in the local network of an enterprise or in general on a local hard disk;
- besides, the installed library does not have to be in the form of a Composer package, you can install from any git / hg / svn repository of an arbitrary structure;
- Finally, the package to be installed does not have to be a git / hg / svn repository, it can be an arbitrary zip file available on any uri!
- all packages are installed in the current directory (from where the install command was executed), this allows you to have several different versions of libraries when working on different projects in parallel;
- The update command updates all installed (or reinstalls accidentally deleted) packages to newer versions. Or it may not update the versions to the freshest if you create a special composer.lock file - this allows you to fix a combination of stable versions of all the libraries used in the project;
- After the packages are installed, autoload.php is automatically generated, with which you can connect the installed libraries in the code of your project. When preparing a Composer package, it is recommended to use PSR-0 , a standard for locating and naming php files, so that autoload can easily find them. In any case, the author of the package can describe the rules by which autoload will look for files of various classes or neimspaces. If you install a library that is not framed as a Composer package (for example, an arbitrary git repository with github), then the task of describing autoload rules falls on your shoulders. So there is no magic with the generated autoload.php - he can download everything (even libraries with a set of functions outside the classes), as long as the rules are described (by the library or by you).
Working example: use Composer in your project
To figure out how to use Composer, let's write a small PHP project: “Super Hello World”. Since we do not want to reinvent the wheel and write code from scratch, take ready-made libraries and frameworks.
We will use the following libraries:
- microfile Silex (available as Composer package on packagist.org),
- Twig template engine (available as a Composer package on packagist.org)
- our own logger of visits SuperLogger , which I designed as a Composer-package and published on github
- our old, but beloved superlib Legacy library, which consists of a mix of classes without namespaces and functions without classes; The library is published on github, but is not a composer package.
As we did before: we downloaded the necessary frameworks and libraries, thought where to unpack them, wrote a bunch of require (or require_once for reliability) in the project.
How we will do it now: use Composer - it will download all the libraries and generate autoload.php for us. In addition, if we want to show “Super Hello World” to our colleagues, it will suffice to publish the code of our project on github (or elsewhere), not including all the required libraries in the repository and not preparing long installation instructions. It will be enough for our colleagues to download (clone) “Super Hello World” and execute the command
php composer.phar install
Composer is distributed as a single file
composer.phar (
phar is a php-archive) - in fact, it is a PHP script that can accept several commands (install, update, ...) and can download and unpack libraries.
By the way, a little about the syntax of the launch.
If you work under Windows, then most likely you will write something like
php C:\path\to\composer.phar install
You can simplify your life by creating composer.bat and putting it in% PATH%.
On Linux and OS X, you can configure the command type
composer install
composer.json
So, we are ready to write our Super Hello World project. And I just wrote it:
http://github.com/pqr/superhelloworld . The code consists of a single index.php file in the web directory and a layout.twig template in the views directory.
Head to everything is the file
composer.json . It should be at the root of the project, in our case, next to the web and view directories. In this file, you must specify from which libraries our project depends. In addition, if these libraries are not decorated Composer packages, then you need to specify some additional information about the library being installed (for example, describe the autoload.php class autoload rules and functions).
composer.json, you guessed it, has a JSON data format. To the question "
why JSON? ", The Composer developers answer "
Because. Just accept it. ".
We need to describe one js-object in which all instructions will be located. The first and most important instruction:
require .
We connect packages from the site packagist.org
{ "require": { "php":">=5.3.0", "silex/silex":"dev-master", "twig/twig":">=1.8,<2.0-dev" } }
Here I described the dependence of the project on PHP version 5.3.0 and higher, on silex (microform) and on twig (template maker). Silex and Twig are available as Composer packages on packagist.org, so no additional configuration is required. I note that Silex, in turn, depends on several more packages - they will all be downloaded and installed automatically.
The package name consists of two parts separated by a slash:
the supplier name (vendor name) and
the library name . The name of the supplier is often the author's nickname or company name. Sometimes, the name of the supplier coincides with the name of the library itself or framework.
For each package, you must specify the version number. It can be a branch in the repository, for example, “dev-master” - the dev prefix signals that this is the name of the branch, and the branch itself is called “master”. For the mercurial repository, a similar entry would look like “dev-default”. As a version number, you can specify more complex rules using comparison operators. By the way, if you download code from a remote repository, Composer scans tags and branch names in this repository for something similar to version numbers, for example, the “v1.2.3” tag will be used as a pointer to version 1.2.3.
We connect to our own Compsoer-package
Next, let's connect our own SuperLogger package, which is properly designed, but published not on packagist.org, but on github:
{ "require": { "php":">=5.3.0", "silex/silex":"dev-master", "twig/twig":">=1.8,<2.0-dev", "mycompany/superlogger":"dev-master" }, "repositories":[ { "type":"git", "url":"http://github.com/pqr/superlogger" } ] }
To let Composer know where to look for the “mycompany / superlogger” package, we added an array of
repositories with a link to the corresponding github repository. Note that the entries in the repositories array are not directly related to the require block — there is no correspondence between the packages and the repositories. As far as I understand, Composer searches for all the required packages in all the specified repositories (including on packagist.org) and downloads the matches found for some internal priorities. More deeply, I still did not understand this moment, correct me if someone knows the details.
We connect arbitrary git repository
Now, let's connect our superlib legacy library, which lies on github, but is not a composer package that is designed, because she is very old.
{ "require":{ "php":">=5.3.0", "silex/silex":"dev-master", "twig/twig":">=1.8,<2.0-dev", "mycompany/superlogger":"dev-master", "pqr/superlib":"1.2.3" }, "repositories":[ { "type":"git", "url":"http://github.com/pqr/superlogger" }, { "type":"package", "package":{ "name":"pqr/superlib", "version":"1.2.3", "source":{ "type":"git", "url":"http://github.com/pqr/superlib", "reference":"master" }, "autoload":{ "classmap":["timer.php"], "files":["lib_functions.php"] } } } ] }
An object has been added to the repositories array that fully describes the pqr / superlib package. In fact, this is the description that the author of the library should have made and put it inside his repository. But under the terms of the problem, superlib is not a Composer package, so we had to create its description as part of the Super Hello World project. Similarly, you can connect any other library, incl. simple zip file.
We connect a simple zip file
For example, this is how the description of the dependency on the Smarty template engine, distributed as a zip file with source code in svn, might look like:
{ "repositories":[ { "type":"package", "package":{ "name":"smarty/smarty", "version":"3.1.7", "dist":{ "url":"http://www.smarty.net/files/Smarty-3.1.7.zip", "type":"zip" }, "source":{ "url":"http://smarty-php.googlecode.com/svn/", "type":"svn", "reference":"tags/Smarty_3_1_7/distribution/" } } } ], "require":{ "smarty/smarty":"3.1.*" } }
Autoload instuction
Let's return to our project.
Describing “pqr / superlib”, we added the
autoload instruction. It contains the file timer.php, in which the future autoloader will look for classes and specify the file with the functions lib_functions.php - it will be forced to connect at the beginning of autoload.php.
So, our project consists of:
- the composer.json file is in the root;
- At the root are the web and views directories;
- Inside the web directory there is a file with the “business logic” of our application: index.php;
- inside the views directory is the layout.twig template file;
- Additionally, in the web folder I put .htaccess (for apache) and web.config (for IIS 7.5) with mod_rewrite / url rewriter rules — they have no direct relationship to the Composer setting.
Everything is ready to launch.
Run composer install
php composer.phar install
Composer clones the repositories and unpacks them in the correct version in the
vendor directory, which he himself creates at the root of the project. After unpacking, in the vendor directory we will find:
- autoload.php file
- service directories .composer and composer
- pimple - a package that pulled along with the Silex microframe
- silex - microform itself, we explicitly requested it when describing dependencies
- symfony - some components from symfony 2 that are required for Silex to work
- twig - template engine that we also explicitly requested
- mycompany - inside this directory will be the superlogger repository downloaded from github
- pqr - inside this directory will be the superlib repository, also downloaded from github
It remains only to connect autoload.php at the beginning of the web / index.php file (require "../vendor/autoload.php") and all the libraries and functions will be available!
How to create your own Composer package?
In this project, we used Composer from the point of view of the library consumer. How do you create a Composer package yourself so that any other person can use it?
In fact, I created one of these packages when I prepared examples for this article. At the root of the superlogger repository there is a file
composer.json of a similar structure, which describes the package itself and its dependencies (in the case of the superlogger, there are no dependencies). Other examples: the silex and twig repositories that have been downloaded to the vendor folder - they all have the composer.json file in the root - see, learn!
And, of course, do not forget about the documentation on the official site
getcomposer.org/doc/ .
I will leave this topic to you for self-study.
Let's sum up
In this article, I explained what Composer is, its history, and described the main features. We have tried to create a project that uses Composer to install packages from packagist.org and from our own repositories.
It's time to try!- Download Composer ( getcomposer.org/download/ )
- Download superhelloworld (git clone git: //github.com/pqr/superhelloworld.git)
- Install dependencies (cd superhelloworld && php composer.phar install)
- Examine the vendor folder and generated autoload.php
- Use Composer in your projects
... - PROFIT !!!
Add a couple of links on the topic:
Composer: Part 1 - What & WhyComposer: Part 2 - ImpactPS
In my work projects, I use the Mercurial version control system. This example can also be downloaded and installed via Composer from bitbucket.org:
http://bitbucket.org/pqr/superhelloworldWarning : unfortunately, when using Composer with Mercurial repositories on a Windows machine, I found one bug. If you install dependencies in a project that is on a disk other than the system disk, you will get an error. For example, the system disk C :, and you deploy the project somewhere in the D: \ someproject folder and your project depends on the libraries published as Mercurial repositories — Composer will not be able to read them correctly. I am going to fix this bug in the near future and send a pull request to the Composer official repository.