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
|