| 1 | 1 | new file mode 100644 | 
                    
                | ... | ... | @@ -0,0 +1,103 @@ | 
                    
                |  | 0 | +--- | 
                    
                |  | 1 | +layout: post | 
                    
                |  | 2 | +title: "Dependency management in PHP projects #1" | 
                    
                |  | 3 | +date: 2013-11-24 18:25 | 
                    
                |  | 4 | +comments: true | 
                    
                |  | 5 | +categories: [webdev] | 
                    
                |  | 6 | +cover: /images/cover/avatar.png | 
                    
                |  | 7 | +keywords: php, composer, bundle, versions, dependencies, packages, libraries | 
                    
                |  | 8 | +description:  | 
                    
                |  | 9 | +--- | 
                    
                |  | 10 | + | 
                    
                |  | 11 | +Programmers use many 3rd party libraries in their projects. Problems may occur | 
                    
                |  | 12 | +if programmers are developing a project and they don't have same libraries  | 
                    
                |  | 13 | +or same versions of libraries. Dependency managers solve this problem in an elegant way.  | 
                    
                |  | 14 | +If you don't know about them, I'm sure you'll love them. | 
                    
                |  | 15 | + | 
                    
                |  | 16 | +# Introduction to Composer | 
                    
                |  | 17 | + | 
                    
                |  | 18 | +[Composer](http://getcomposer.org/) is a multi-platform and easy to use dependency manager for PHP.  | 
                    
                |  | 19 | +It's working on Windows, GNU/Linux, BSD, OS X, whatever. You need PHP 5.3.2+. | 
                    
                |  | 20 | + | 
                    
                |  | 21 | +Installation is pretty easy, here's the official [howto](http://getcomposer.org/doc/00-intro.md). | 
                    
                |  | 22 | + | 
                    
                |  | 23 | +First, go to the project's root directory and define project dependencies in  | 
                    
                |  | 24 | +```composer.json``` file (right, it's a file written in JSON :) ). | 
                    
                |  | 25 | + | 
                    
                |  | 26 | +Here's a real-world example from [Gitlist](http://gitlist.org/) project (licensed under New BSD license): | 
                    
                |  | 27 | + | 
                    
                |  | 28 | +{% codeblock composer.json https://github.com/klaussilveira/gitlist/blob/master/composer.json lang:json %} | 
                    
                |  | 29 | +{ | 
                    
                |  | 30 | +    "require": { | 
                    
                |  | 31 | +        "silex/silex": "1.0.*@dev", | 
                    
                |  | 32 | +        "twig/twig": "1.12.*", | 
                    
                |  | 33 | +        "symfony/twig-bridge": "2.2.*", | 
                    
                |  | 34 | +        "symfony/filesystem": "2.2.*", | 
                    
                |  | 35 | +        "klaussilveira/gitter": "dev-master" | 
                    
                |  | 36 | +    }, | 
                    
                |  | 37 | +    "require-dev": { | 
                    
                |  | 38 | +        "symfony/browser-kit": "2.2.*", | 
                    
                |  | 39 | +        "symfony/css-selector": "2.2.*", | 
                    
                |  | 40 | +        "phpunit/phpunit": "3.7.*", | 
                    
                |  | 41 | +        "phpmd/phpmd": "1.4.*", | 
                    
                |  | 42 | +        "phploc/phploc": "1.7.*" | 
                    
                |  | 43 | +    }, | 
                    
                |  | 44 | +    "minimum-stability": "dev", | 
                    
                |  | 45 | +    "autoload": { | 
                    
                |  | 46 | +        "psr-0": { | 
                    
                |  | 47 | +            "GitList": "src/" | 
                    
                |  | 48 | +        } | 
                    
                |  | 49 | +    } | 
                    
                |  | 50 | +} | 
                    
                |  | 51 | +{% endcodeblock %} | 
                    
                |  | 52 | + | 
                    
                |  | 53 | +The file defines which dependencies the project requires (in ```require``` object), | 
                    
                |  | 54 | +dependencies for development environment are listed in ```require-dev``` object. | 
                    
                |  | 55 | + | 
                    
                |  | 56 | +Now we can run ```composer install```. When the task finishes all | 
                    
                |  | 57 | +dependencies are installed in ```vendor``` directory and we can use them in the project. | 
                    
                |  | 58 | + | 
                    
                |  | 59 | +# Same versions everywhere | 
                    
                |  | 60 | + | 
                    
                |  | 61 | +The installing process created ```composer.lock``` file. There's saved a list of  | 
                    
                |  | 62 | +installed dependencies along with their versions. This is necessary for keeping | 
                    
                |  | 63 | +same versions of dependencies across all computers where the project has been  | 
                    
                |  | 64 | +deployed. If you're interested in how the file looks like, check [this](https://github.com/klaussilveira/gitlist/blob/master/composer.lock) out. | 
                    
                |  | 65 | + | 
                    
                |  | 66 | +For example, there are two programmers (Programmer#1 and Programmer#2). | 
                    
                |  | 67 | +Both of them have installed dependencies from ```composer.json``` above. Then,  | 
                    
                |  | 68 | +Programmer#1 wants to upgrade ```twig``` from 1.12 to to 1.13 because of new features he desperately needs. | 
                    
                |  | 69 | +So he updates ```composer```, after that runs ```composer update``` so dependencies get updated | 
                    
                |  | 70 | +and commits changes to <abbr title="Version Control System">[VCS](http://en.wikipedia.org/wiki/Revision_control)</abbr>  | 
                    
                |  | 71 | +they use (Git, SVN, ...). What he actually commits? Only ```composer.json``` and ```composer.lock```.  | 
                    
                |  | 72 | +In that files is everything what others may need to keep their systems up-to-date. *(Actually, just the lock  | 
                    
                |  | 73 | +file is needed. Programmer#1 knows Programmer#2 will may want to change dependencies in future, so  | 
                    
                |  | 74 | +he commits ```composer.json```.)*  | 
                    
                |  | 75 | + | 
                    
                |  | 76 | +**Never commit ```vendor``` directory**. | 
                    
                |  | 77 | + | 
                    
                |  | 78 | +Next day Programmer#2 pulls changes from VCS and he can see composer files were changed. | 
                    
                |  | 79 | +So he fires up ```composer update``` and after few seconds he has exactly same version of dependencies | 
                    
                |  | 80 | +as Programmer#1. It was so easy, just one command. | 
                    
                |  | 81 | + | 
                    
                |  | 82 | +# Summary of what we know so far | 
                    
                |  | 83 | + | 
                    
                |  | 84 | +1. First, create a ```composer.json``` file in the root directory of a project. | 
                    
                |  | 85 | +2. Define project dependencies. | 
                    
                |  | 86 | +3. Run ```composer install```. | 
                    
                |  | 87 | +4. Commit changes to VCS of your choice. Don't forget you never commit ```vendor``` directory. | 
                    
                |  | 88 | + | 
                    
                |  | 89 | +If you later change dependencies, edit and save the json file, run ```composer update``` and commit  | 
                    
                |  | 90 | +json and lock files. | 
                    
                |  | 91 | + | 
                    
                |  | 92 | +Maybe you're asking *What's the difference between install and update commands?* It's simple. | 
                    
                |  | 93 | + | 
                    
                |  | 94 | +* The update command uses ```composer.json``` file, installs dependencies defined in it  | 
                    
                |  | 95 | + and in the and it creates/rewrites the lock file. | 
                    
                |  | 96 | +* The install command installs dependencies from a lock file. If no lock file exists it  | 
                    
                |  | 97 | + behaves like the update command. | 
                    
                |  | 98 | + | 
                    
                |  | 99 | +In the second part of this article I'll explain dependency versioning and reveal how the installed | 
                    
                |  | 100 | +dependencies are integrated into projects. | 
                    
                |  | 101 | + | 
                    
                |  | 102 | +*This article was also published on my school [blog](http://cinan.blog.matfyz.sk/p104246-dependency-management-in-php-projects-#1).* | 
                    
                | 0 | 103 | \ No newline at end of file |