source/_posts/2013-11-24-dependency-management-in-php-projects.markdown
d7f72071
 ---
 layout: post
 title: "Dependency management in PHP projects #1"
 date: 2013-11-24 18:25
 comments: true
f72673e9
 categories: [webdev, php]
d7f72071
 cover: /images/cover/avatar.png
 keywords: php, composer, bundle, versions, dependencies, packages, libraries
 description: 
 ---
 
 Programmers use many 3rd party libraries in their projects. Problems may occur
 if programmers are developing a project and they don't have same libraries 
 or same versions of libraries. Dependency managers solve this problem in an elegant way. 
 If you don't know about them, I'm sure you'll love them.
 
 # Introduction to Composer
 
 [Composer](http://getcomposer.org/) is a multi-platform and easy to use dependency manager for PHP. 
 It's working on Windows, GNU/Linux, BSD, OS X, whatever. You need PHP 5.3.2+.
 
 Installation is pretty easy, here's the official [howto](http://getcomposer.org/doc/00-intro.md).
 
 First, go to the project's root directory and define project dependencies in 
 ```composer.json``` file (right, it's a file written in JSON :) ).
 
 Here's a real-world example from [Gitlist](http://gitlist.org/) project (licensed under New BSD license):
 
 {% codeblock composer.json https://github.com/klaussilveira/gitlist/blob/master/composer.json lang:json %}
 {
     "require": {
         "silex/silex": "1.0.*@dev",
         "twig/twig": "1.12.*",
         "symfony/twig-bridge": "2.2.*",
         "symfony/filesystem": "2.2.*",
         "klaussilveira/gitter": "dev-master"
     },
     "require-dev": {
         "symfony/browser-kit": "2.2.*",
         "symfony/css-selector": "2.2.*",
         "phpunit/phpunit": "3.7.*",
         "phpmd/phpmd": "1.4.*",
         "phploc/phploc": "1.7.*"
     },
     "minimum-stability": "dev",
     "autoload": {
         "psr-0": {
             "GitList": "src/"
         }
     }
 }
 {% endcodeblock %}
 
 The file defines which dependencies the project requires (in ```require``` object),
 dependencies for development environment are listed in ```require-dev``` object.
 
 Now we can run ```composer install```. When the task finishes all
 dependencies are installed in ```vendor``` directory and we can use them in the project.
 
 # Same versions everywhere
 
 The installing process created ```composer.lock``` file. There's saved a list of 
 installed dependencies along with their versions. This is necessary for keeping
 same versions of dependencies across all computers where the project has been 
 deployed. If you're interested in how the file looks like, check [this](https://github.com/klaussilveira/gitlist/blob/master/composer.lock) out.
 
 For example, there are two programmers (Programmer#1 and Programmer#2).
 Both of them have installed dependencies from ```composer.json``` above. Then, 
 Programmer#1 wants to upgrade ```twig``` from 1.12 to to 1.13 because of new features he desperately needs.
 So he updates ```composer```, after that runs ```composer update``` so dependencies get updated
 and commits changes to <abbr title="Version Control System">[VCS](http://en.wikipedia.org/wiki/Revision_control)</abbr> 
 they use (Git, SVN, ...). What he actually commits? Only ```composer.json``` and ```composer.lock```. 
 In that files is everything what others may need to keep their systems up-to-date. *(Actually, just the lock 
 file is needed. Programmer#1 knows Programmer#2 will may want to change dependencies in future, so 
 he commits ```composer.json```.)* 
 
 **Never commit ```vendor``` directory**.
 
 Next day Programmer#2 pulls changes from VCS and he can see composer files were changed.
 So he fires up ```composer update``` and after few seconds he has exactly same version of dependencies
 as Programmer#1. It was so easy, just one command.
 
 # Summary of what we know so far
 
 1. First, create a ```composer.json``` file in the root directory of a project.
 2. Define project dependencies.
 3. Run ```composer install```.
 4. Commit changes to VCS of your choice. Don't forget you never commit ```vendor``` directory.
 
 If you later change dependencies, edit and save the json file, run ```composer update``` and commit 
 json and lock files.
 
 Maybe you're asking *What's the difference between install and update commands?* It's simple.
 
 * The update command uses ```composer.json``` file, installs dependencies defined in it 
  and in the and it creates/rewrites the lock file.
 * The install command installs dependencies from a lock file. If no lock file exists it 
  behaves like the update command.
 
 In the second part of this article I'll explain dependency versioning and reveal how the installed
 dependencies are integrated into projects.
 
f72673e9
 *This article was also published on my school [blog](http://cinan.blog.matfyz.sk/p104246-dependency-management-in-php-projects-#1).*