📜 ⬆️ ⬇️

Composer - dependency manager for PHP

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:
  1. You have a project that depends on several libraries.
  2. Some of these libraries are dependent on other libraries.
  3. You describe in your project those libraries that your code directly depends on.
  4. 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?




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:
  1. microfile Silex (available as Composer package on packagist.org),
  2. Twig template engine (available as a Composer package on packagist.org)
  3. our own logger of visits SuperLogger , which I designed as a Composer-package and published on github
  4. 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:

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:

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!
  1. Download Composer ( getcomposer.org/download/ )
  2. Download superhelloworld (git clone git: //github.com/pqr/superhelloworld.git)
  3. Install dependencies (cd superhelloworld && php composer.phar install)
  4. Examine the vendor folder and generated autoload.php
  5. Use Composer in your projects
    ...
  6. PROFIT !!!


Add a couple of links on the topic:
Composer: Part 1 - What & Why
Composer: Part 2 - Impact

PS


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/superhelloworld

Warning : 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.

Source: https://habr.com/ru/post/145946/


All Articles