Managing Dependencies with Composer (php[world] 2014)

Managing Dependencies with Composer (php[world] 2014)

Traditionally, managing third-party code in PHP projects has not been a trivial task. Fortunately, the PHP community now has Composer, a top-notch dependency manager. Learn what Composer is and how you can put it to work for fun and profit. You will see how to set up a new project, find packages, as well as how to create and distribute your own packages.

23d971deeb3975a7d28246192fbbe7b7?s=128

Beau Simensen

November 11, 2014
Tweet

Transcript

  1. 2.
  2. 5.

    Apache, nginx, other. PHP 5.4+ internal web server optional if

    you want to actually run the tutorial code (probably not a huge deal if you cannot!)
  3. 7.

    $ composer config home /home/username/.composer config.json: (this file is in

    the tutorial download) ! { "repositories": [ { "type": "composer", "url": "http://toran.composertut.local/repo/packagist/" }, { "packagist": false } ] }
  4. 8.

    $ composer config home /home/username/.composer config.json: (this file is in

    the tutorial download) ! { "repositories": [ { "type": "composer", "url": "http://toran.composertut.local/repo/packagist/" }, { "packagist": false } ] }
  5. 9.

    $ composer config home /home/username/.composer config.json: (this file is in

    the tutorial download) ! { "repositories": [ { "type": "composer", "url": "http://toran.composertut.local/repo/packagist/" }, { "packagist": false } ] }
  6. 12.
  7. 15.

    { “name”: “acme/my-project”, “description”: “Acme’s My Project”, “license”: “MIT”, “require”:

    { “silex/silex”: “1.1.*” }, “autoload”: { “psr-4”: { “Acme\\MyProject\\”: “src” } } }
  8. 16.

    { “name”: “acme/my-project”, “description”: “Acme’s My Project”, “license”: “MIT”, “require”:

    { “silex/silex”: “1.1.*” }, “autoload”: { “psr-4”: { “Acme\\MyProject\\”: “src” } } }
  9. 19.

    { “name”: “acme/my-project”, “description”: “Acme’s My Project”, “license”: “MIT”, “require”:

    { “silex/silex”: “1.1.*” }, “autoload”: { “psr-4”: { “Acme\\MyProject\\”: “src” } } }
  10. 20.

    { “name”: “acme/my-project”, “description”: “Acme’s My Project”, “license”: “MIT”, “require”:

    { “silex/silex”: “1.1.*” }, “autoload”: { “psr-4”: { “Acme\\MyProject\\”: “src” } } }
  11. 21.

    $ composer install Loading composer repositories with package information Installing

    dependencies (including require-dev) - Installing psr/log (1.0.0) - Installing symfony/routing (v2.3.7) - Installing symfony/debug (v2.3.7) - Installing symfony/http-foundation (v2.3.7) - Installing symfony/event-dispatcher (v2.3.7) - Installing symfony/http-kernel (v2.3.7) - Installing pimple/pimple (v1.1.0) - Installing silex/silex (v1.1.2) Writing lock file Generating autoload files $
  12. 23.
  13. 27.

    $ curl -sS https://getcomposer.org/installer | php $ php composer.phar --version

    WARNING Security people think this is bad (but it is all the rage)
  14. 31.

    { “name”: “acme/my-project”, “description”: “Acme’s My Project”, “license”: “MIT”, “require”:

    { “silex/silex”: “1.1.*” }, “autoload”: { “psr-4”: { “Acme\\MyProject\\”: “src” } } }
  15. 33.

    $ composer install Loading composer repositories with package information Installing

    dependencies (including require-dev) - Installing psr/log (1.0.0) - Installing symfony/routing (v2.3.7) - Installing symfony/debug (v2.3.7) - Installing symfony/http-foundation (v2.3.7) - Installing symfony/event-dispatcher (v2.3.7) - Installing symfony/http-kernel (v2.3.7) - Installing pimple/pimple (v1.1.0) - Installing silex/silex (v1.1.2) Writing lock file Generating autoload files $
  16. 36.

    $ composer install If composer.lock exists, install exactly what is

    in the lock file. ! Otherwise, read composer.json to find out what should be installed, install the dependencies, and write out composer.lock.
  17. 37.
  18. 38.
  19. 39.
  20. 40.
  21. 42.
  22. 43.
  23. 44.
  24. 45.
  25. 46.

    $ composer require [pkg] Add a package to composer.json. !

    The [pkg] is the name with a version constraint. ! ! foo/bar or foo/bar:1.0.0 or foo/bar=1.0.0 or "foo/bar 1.0.0"
  26. 47.

    $ composer require [pkg] Recommend way to add Composer packages

    to your project! ! composer require foo/bar
  27. 48.
  28. 49.

    $ composer require --dev [pkg] Add a package as a

    dev requirement ! composer require --dev foo/bar
  29. 50.
  30. 51.
  31. 52.
  32. 53.
  33. 55.
  34. 57.
  35. 58.
  36. 60.
  37. 62.
  38. 65.
  39. 66.
  40. 67.
  41. 68.

    { “name”: “acme/my-project”, “description”: “Acme’s My Project”, “license”: “MIT”, “require”:

    { “silex/silex”: “1.1.*” }, “autoload”: { “psr-4”: { “Acme\\MyProject\\”: “src” } } }
  42. 72.

    function ($class) { if ($class === "Acme\\Account\\User") { // do

    something to cause this class // to become defined require __DIR__."/src/user.inc"; } }
  43. 75.
  44. 84.

    { "autoload": { "psr-0": { "Acme\\Account\\": "src" } } }

    ! new Acme\Account\User(); ! # src/Acme/Account/User.php
  45. 85.

    { "autoload": { "psr-0": { "Acme_Account_": "src" } } }

    ! new Acme_Account_User(); ! # src/Acme/Account/User.php
  46. 86.
  47. 93.

    { "autoload": { "psr-4": { "Acme\\Account\\": "src" } } }

    ! new Acme\Account\User(); ! # src/User.php
  48. 95.

    { "autoload": { "psr-0": { "Acme\\Account\\": "src" } } }

    ! new Acme\Account\User(); ! # src/Acme/Account/User.php
  49. 96.

    { "autoload": { "psr-4": { "Acme\\Account\\": "src/Acme/Account" } } }

    ! new Acme\Account\User(); ! # src/Acme/Account/User.php
  50. 97.
  51. 103.
  52. 109.

    { “name”: “acme/my-project”, “description”: “Acme’s My Project”, “license”: “MIT”, “require”:

    { “silex/silex”: “1.1.*” }, “autoload”: { “psr-4”: { “Acme\\MyProject\\”: “src” } } }
  53. 110.

    { “name”: “acme/my-project”, “description”: “Acme’s My Project”, “license”: “MIT”, “require”:

    { “silex/silex”: “1.1.*” }, “autoload”: { “psr-4”: { “Acme\\MyProject\\”: “src” } } }
  54. 112.
  55. 133.

    –Semantic Versioning “If the dependency specifications are too tight, you

    are in danger of version lock (the inability to upgrade a package without having to release new versions of every dependent package).”
  56. 135.

    –Semantic Versioning “If dependencies are specified too loosely, you will

    inevitably be bitten by version promiscuity (assuming compatibility with more future versions than is reasonable).”
  57. 138.
  58. 139.

    { “name”: “silex/silex”, “require”: { “pimple/pimple”: “1.*” } } {

    “name”: “dflydev/doctrine-orm-service-provider”, “require”: { “pimple/pimple”: “~1.1”, “doctrine/orm”: “~2.3” } } 1.1.0 1.1.0 1.1.1 1.0.2 1.0.1 1.0.0 2.0.0 Silex Pimple 0.0.1 2.3.2 2.4.0 2.3.1 2.3.0 2.2.1 2.5.0 ORM 2.2.0 1.0.0 dflydev
  59. 140.

    { “name”: “acme/myapp”, “require”: { “dflydev/doctrine-orm-service-provider”: “1.0.*”, “silex/silex”: “1.1.*”, !

    “pimple/pimple”: “~1.1.1”, “doctrine/orm”: “2.4.*” } } { “name”: “silex/silex”, “require”: { “pimple/pimple”: “1.*” } } { “name”: “dflydev/doctrine-orm-service-provider”, “require”: { “pimple/pimple”: “~1.1”, “doctrine/orm”: “~2.3” } } 1.1.0 1.1.0 1.1.1 1.0.2 1.0.1 1.0.0 2.0.0 Silex Pimple 0.0.1 2.3.2 2.4.0 2.3.1 2.3.0 2.2.1 2.5.0 ORM 2.2.0 1.0.0 dflydev 1.0.0 myapp
  60. 141.
  61. 143.

    $ composer install Loading composer repositories with package information Installing

    dependencies (including require-dev) Your requirements could not be resolved to an installable set of packages. ! Problem 1 - silex/silex v1.1.0 requires pimple/pimple 1.* -> satisfiable by pimple/pimple[1.0.0, 1.1.x-dev, v1.0.1, v1.0.2, v1.1.0]. - silex/silex v1.1.1 requires pimple/pimple 1.* -> satisfiable by pimple/pimple[1.0.0, 1.1.x-dev, v1.0.1, v1.0.2, v1.1.0]. - silex/silex v1.1.2 requires pimple/pimple ~1.0 -> satisfiable by pimple/pimple[1.0.0, 1.1.x-dev, v1.0.1, v1.0.2, v1.1.0]. - Can only install one of: pimple/pimple[2.0.x-dev, 1.0.0]. - Can only install one of: pimple/pimple[2.0.x-dev, 1.1.x-dev]. - Can only install one of: pimple/pimple[v1.0.1, 2.0.x-dev]. - Can only install one of: pimple/pimple[v1.0.2, 2.0.x-dev]. - Can only install one of: pimple/pimple[v1.1.0, 2.0.x-dev]. - Installation request for pimple/pimple 2.0.*@dev -> satisfiable by pimple/pimple[2.0.x-dev]. - Installation request for silex/silex 1.1.* -> satisfiable by silex/silex[v1.1.0, v1.1.1, v1.1.2]. ! Potential causes: - A typo in the package name - The package is not available in a stable-enough version according to your minimum-stability setting.
  62. 167.
  63. 169.

    { “name”: “acme/myapp”, “require”: { “naughty/id-generator”: “1.0.*” } } !

    ! { “name”: “naughty/id-generator”, “require”: { “ircmaxell/random-lib”: “dev-master” } }
  64. 170.

    { “name”: “acme/myapp”, “require”: { “naughty/id-generator”: “1.0.*”, ! “ircmaxell/random-lib”: “@dev”

    } } ! ! { “name”: “naughty/id-generator”, “require”: { “ircmaxell/random-lib”: “dev-master” } }
  65. 171.

    { “name”: “acme/myapp”, “require”: { “naughty/id-generator”: “1.0.*”, ! “ircmaxell/random-lib”: “dev-master”

    } } ! ! { “name”: “naughty/id-generator”, “require”: { “ircmaxell/random-lib”: “dev-master” } }
  66. 172.

    { “name”: “acme/myapp”, “require”: { “naughty/id-generator”: “1.0.*”, "dflydev/hawk": "1.0.*", !

    "ircmaxell/random-lib": "dev-master" } } ! ! { “name”: “naughty/id-generator”, “require”: { “ircmaxell/random-lib”: “dev-master” } } ! ! { “name”: “dflydev/hawk”, “require”: { “ircmaxell/random-lib”: “~1.0@dev” } }
  67. 173.

    { “name”: “acme/myapp”, “require”: { “naughty/id-generator”: "1.0.*”, "dflydev/hawk": "1.0.*", !

    "ircmaxell/random-lib": "dev-master" } } ! ! { “name”: “naughty/id-generator”, “require”: { “ircmaxell/random-lib”: “dev-master” } } ! ! { “name”: “dflydev/hawk”, “require”: { “ircmaxell/random-lib”: “~1.0@dev” } } 1.0.x-dev != dev-master
  68. 174.

    { “name”: “acme/myapp”, “require”: { “naughty/id-generator”: “1.0.*”, "dflydev/hawk": "1.0.*", !

    "ircmaxell/random-lib": "@dev" } } ! ! { “name”: “naughty/id-generator”, “require”: { “ircmaxell/random-lib”: “~1.0@dev” } } ! ! { “name”: “dflydev/hawk”, “require”: { “ircmaxell/random-lib”: “~1.0@dev” } } Time to send a pull request!
  69. 176.
  70. 177.

    Send pull requests when you find a package that requires

    dev-master when a branch alias exists
  71. 178.

    –Michael Dowling “I'm working on a new version of Guzzle.

    If you're using composer: stop using dev-master. Use a tagged release. Especially in production.” https://twitter.com/mtdowling/status/440901351657054208
  72. 179.
  73. 194.

    $ composer install Loading composer repositories with package information Installing

    dependencies (including require-dev) Your requirements could not be resolved to an installable set of packages. ! Problem 1 - The requested package sculpin/sculpin 2.0.* could not be found. ! Potential causes: - A typo in the package name - The package is not available in a stable-enough version according to your minimum-stability setting
  74. 195.

    $ composer install Loading composer repositories with package information Installing

    dependencies (including require-dev) Your requirements could not be resolved to an installable set of packages. ! Problem 1 - The requested package sculpin/sculpin 2.0.* could not be found. ! Potential causes: - A typo in the package name - The package is not available in a stable-enough version according to your minimum-stability setting
  75. 199.

    Even if your package requires a dependency @dev, users of

    your package won't get it unless they explicitly ask for it.
  76. 201.

    { “name”: “silex/silex”, “require”: { “pimple/pimple”: “1.*@dev” } } {

    “name”: “dflydev/doctrine-orm-service-provider”, “require”: { “pimple/pimple”: “1.*@beta”, “silex/silex”: “1.1.*”, “doctrine/orm”: “~2.3” } } Root Package
  77. 202.

    { “require”: { “dflydev/doctrine-orm-service-provider”: “1.0.*”, ! “pimple/pimple”: “1.*@alpha” } }

    { “name”: “silex/silex”, “require”: { “pimple/pimple”: “1.*@dev” } } { “name”: “dflydev/doctrine-orm-service-provider”, “require”: { “pimple/pimple”: “1.*@beta”, “silex/silex”: “1.1.*”, “doctrine/orm”: “~2.3” } } Root Package
  78. 209.
  79. 213.