Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHP Dependency Management with Composer - ZendCon 2015

PHP Dependency Management with Composer - ZendCon 2015

A practical introduction to Composer, the Dependency Manager for PHP. We'll look at PHP source code dependency management, compare Composer to PEAR, and show how Composer helps you obtain the components your applications depend upon, install them into your project, and control their update to newer versions. We'll demystify the keys in the composer.json file, and get you confidently using Composer, with practical examples all the way. You will understand:
what PHP source code dependency management looks like, what problem Composer solves,
how to install Composer (even on an IBM i system),
how to use Composer to install, update, and lock code dependencies to appropriate versions,
the difference between composer.json and composer.lock,
what Semantic Versioning means, and what those version numbers communicate to you as developer,
Packagist, the public clearing house for Composer-managed packages,
setting up and using private repositories,
considerations when using Composer in development vs. production environments,
and important do's and don'ts when using Composer.


Clark Everetts

October 19, 2015

More Decks by Clark Everetts

Other Decks in Programming


  1. PHP Dependency Management with Composer Clark Everetts, Zend Technologies/Rogue Wave

    19 October 2015
  2. 2 Clark Everetts, ZCE • Zend Technologies, Inc. – The

    PHP Company / Rogue Wave • PHP since 2005 • Professional Services Consultant  Architecture and Performance Audits  PHP and Zend Framework Training  Application Development, Best Practices, etc. • clark.e@zend.com +ClarkEverettsAtZend @clarkphp • Slides for this talk at https://slideshare/ • Tweets: #zendcon • Rate & comment this session https://joind.in/15504 Welcome!

  4. 4 •(1st Half)  What is it?  What problem

    does it solve?  What does it actually do?  Composer.json & composer.lock  Packages, Repositories and Packagist  Semantic Versioning  Do’s and Don’ts / Best Practices •(2nd Half)  How to install it  How to use it Why are we here? Our Agenda. Might use it just for the cool logo …
  5. 5 Composer is … … a per-project PHP dependency manager

    That’s all. Any questions?
  6. 6 Composer is … … a per-project PHP dependency manager

    Let’s break it down.
  7. 7 … a per-project PHP dependency manager •PHP project-related files

    only •Can include assets like Javascript, images, XML, CSS, etc. •But not for managing Javascript or CSS libraries •Primarily a development - not production – tool (“can” be prod*) PHP Package Dependencies *but I’m not a fan
  8. 8 … a per-project PHP dependency manager What’s a “dependency”?

    You wrote these to reuse across apps. 3rd-Party ZF2, Laravel, OAuth2, Symfony Your Project DEPENDENCIES, PACKAGES, LIBRARIES “Project” == Application
  9. 9 … a per-project PHP dependency manager Dependencies can have

    dependencies Your Project DEPENDENCIES, PACKAGES, LIBRARIES “Project” == Application == Library == Package Composer obtains all specified dependencies. “I need A, B, C, D” “I need E” A B C E D F G H “I need E” “I need G, H”
  10. 10 Want to manage that yourself? “I need these” “I

    need this” A B C E D F G H “I need that” “I need the other” You’d need to: • Identify the direct dependencies of your project • Identify their dependencies, and all sub-dependencies • Locate the source code (PEAR, Git, Subversion, zip/gzip/bz2) • Download and install all of the source code • Make sure all the versions are compatible • Check for updates to any of the dependencies • Do it all again when updates are available With your guidance, Composer does all this for you.
  11. 11 … a per-project PHP dependency manager Different versions of

    the same package Application A Application B Lib Y 1.0.1 Lib X 2.4.1 Lib Y 1.0.1 Lib X 1.2.0 Two projects, each using a different version of the same dependency. Composer is not a global “package manager” (PEAR, APT, YUM) Why do this? • Working with development version: Dev, Alpha, Beta, RC • Update cycle for App A !== App B
  12. 12 … a per-project PHP dependency manager To Reiterate: per-project;

    not global Application A Application B Lib Y 1.0.1 Lib X 2.4.1 Lib Y 1.0.1 Lib X 2.4.1 Two projects, each using same version of the same dependency. Each project has it’s own copy. Pros • Like a PHAR (PHP Archive) file, all dependencies are available in the application directory tree. • Updates to the dependencies of one application do not affect another. Con • Potentially many copies of the exact same library source code on disk.
  13. 13 Composer is… … a per-project PHP dependency manager Knows

    what packages your application or library depends upon Obtains those packages, and all of their dependencies, and installs appropriate versions of them into your project When requested, checks for updates compatible with your project, and downloads into it any updated packages Allows you to pin multiple applications/libraries to the same or different versions of the packages they use. Composer makes it easier to manage application dependencies.

  15. 15 Now What? Answered questions, raised others: How do we

    inform Composer what dependencies a project has? Where does it put the dependencies in the project? Where does Composer obtain dependencies? How does the project refer to those dependencies (access them when it needs them)? How do we install Composer and actually use it? A closer look…
  16. 16 composer.json file tells Composer about your project’s needs Describing

    Project Dependencies Composer-Intro zendframework/ zend-log >=2.3.5 { "name" : "Composer-Intro", "require" : { "zendframework/zend-log" : “>=2.3.5" }, "repositories" : [ { "type" : "composer", "url" : "https://packagist.org/" } ] } Light text - Optional Bold text - Required composer.json composer.json ? ? ? Note: >=2.3.5 is an Unbounded Version Constraint Eventual BC breaks (semantic versioning). Done here for illustration, for when we discuss dependency updates.
  17. 17 composer install Installing Project Dependencies – First Level/Direct Composer-Intro

    zendframework/ zend-log >=2.3.5 New: •Vendor Directory •composer.lock file After Before { "require" : { "zendframework/zend-log" : “>=2.3.5" } }
  18. 18 zend-servicemanager and zend-stdlib composer.json files each contained this: {

    … "require": { "php": ">=5.3.23", }, … } Installing Project Dependencies – Further Levels zend-log composer.json file contained this: { … "require": { "php": ">=5.3.23", "zendframework/zend-servicemanager": "self.version", "zendframework/zend-stdlib": "self.version" }, … } zend-log needs two more packages, use same version as zend-log No further code dependencies Note PHP version requirement (platform package in Composer)
  19. 19 Where dependencies are stored (by default) Composer-Intro vendor zend-stdlib

    zend-log Dependency Relationship zend-servicemanager Composer-Intro Directory Structure zend-log zend-servicemanager zend-stdlib
  20. 20 .json vs. .lock – Think: “Design-To” vs. “As-Built” Composer-Intro

    zendframework/ zend-log >=2.3.5 composer.json tells Composer what you want composer.lock tells you what you got Composer-Intro zend-stdlib 2.4.0 zend-log 2.4.0 zend-servicemanager 2.4.0
  21. 21 “Design-To” vs. “As-Built” – Further Example Composer-Intro Composer resolves

    versions as best it can actual versions installed recorded in composer.lock Composer-Intro zend-stdlib 2.3.9 zend-log 2.3.9 zend-servicemanager 2.3.9 zendframework/ zend-log >=2.3,<2.4
  22. 22 Problems Can Occur Your Project “I need E >=1.0,<1.2”

    A B C E version ? “I need E >=1.2,<2.0”
  23. 23 Initial composer install Your Application composer.json Repository composer.lock vendor

    folder 4. Create With no composer.lock Composer will …
  24. 24 1. Read Subsequent composer install Your Application composer.json Repository

    composer.lock vendor folder With existing composer.lock Composer will … 2. Obtain lock file versions from
  25. 25 Any composer update Your Application composer.json Repository composer.lock vendor

    folder 4. Update Composer will …
  26. 26 Development Considerations D Development Workstation / Vhost Packagist.org, Local

    repos composer install B Development Workstation / Vhost A Development Workstation / Vhost composer update & commit to local VCS composer install C Development Workstation / Vhost composer install install === “synchronize”
  27. 27 Production Considerations Production Server Packagist.org composer install composer update

    Please do NOT do this.
  28. 28 Production Considerations “Build” Server Packagist.org composer install with composer.lock

    file Better. Production Server
  29. 29 Production Considerations Test Server Best. Production Server Local Repository

    (VCS / Change Mgt, Packagist) Production Server Or Local Repository (VCS / Change Mgt, Packagist)

  31. 31 Composer downloads packages from repositories Where Does Composer Obtain

    Dependencies? Package • A directory with files in it • Package description - composer.json • Name • Version • Source Definition • Repository location (URI) • Repository Type • Package Type • Dist – packaged (usually a stable release) • Source – source code (for development) • Can be both
  32. 32 More About Packages - Naming Package Names • vendor-name/project-name

    • psr/log • pear/log • zendframework/log • Best practice: use-dashes/as-word-separators • Vendor names must be unique • If you are going to publish packages: • Remember: they persist! You and the world will have to live with them. • Don’t be cute or cryptic (with vendor or package name) • Name should reflect package purpose
  33. 33 Packages - composer.json – Real (former) Example { "name":

    "zendframework/zend-log", "description": "component for general purpose logging", "license": "BSD-3-Clause", "keywords": ["zf2“, "log“, "logging”], "homepage": "https://github.com/zendframework/zf2", "autoload": { "psr-4": { "Zend\\Log\\": "" } }, "require": { "php": ">=5.3.23", "zendframework/zend-servicemanager": "self.version", "zendframework/zend-stdlib": "self.version" }, (cont. next slide)
  34. 34 Packages - composer.json – Real Example (cont.) "require-dev": {

    "zendframework/zend-console": "self.version", "zendframework/zend-db": "self.version", "zendframework/zend-escaper": "self.version", "zendframework/zend-mail": "self.version", "zendframework/zend-validator": "self.version" }, "suggest": { "ext-mongo": "*", "zendframework/zend-console": "Zend\\Console component", "zendframework/zend-db": "Zend\\Db component", "zendframework/zend-escaper": "Zend\\Escaper component, for use in the XML formatter", "zendframework/zend-mail": "Zend\\Mail component", "zendframework/zend-validator": "Zend\\Validator component" }, (cont. next slide)
  35. 35 Packages - composer.json – Real Example (cont.) "extra": {

    "branch-alias": { "dev-master": "2.3-dev", "dev-develop": "2.4-dev" } } } Notice anything missing? • package type – omit, “library”, or custom • package version • Best to omit for Composer, VCS repositories (uses branch/tags) • Format: X.Y.Z or vX.Y.Z, with optional RC, beta, alpha, patch • 1.4.26 • 2.5.6-RC3 • 1.2.3-p2 • 1.2.3-RC
  36. 36 Platform / Virtual Packages Not Installable by Composer, Used

    for checking only • php – PHP version of the server Composer is installing packages to • hhvm (not applicable for IBM i) • ext-<name> • “ext-ibm_db2” : “*” • lib-<name> • curl • iconv • icu • libxml • openssl • pcre • uuid • xsl • composer show --platform for a list of available platform packages
  37. 37 More About Repositories Repository • A download source for

    packages, specified by URL • A list of packages and versions in a packages.json file • Types • Composer – uses Packagist software, can public or private • VCS – Git, SVN, Hg • VCS client needed for “regular” git, svn, or hg repos • Uses APIs for GitHub, BitBucket (no client needed) • PEAR – public or private • Package – zip; use only if none of the above are possible
  38. 38 Repositories: Packagist.org Packagist.org Package Archivist Just a Composer Repository…

    • … but it is the primary repository for open source packages • Open Source Project Best Practice: register it at packagist.org • Searchable / Browsable • Less work for people to find and use your package. • Many, many, many packages available. There is duplication…
  39. 39 https://packagist.org/

  40. 40 Composer Private Repositories – Satis and Torin Proxy Your

    Application Packagist.org Proxy Torin / Satis Public Repositories Satis – free TorinProxy.com – license fees support development of Composer Why? 1. Speed. 2. Happier network security staff.
  41. 41 Private Repositories – Local Packagist Your Application composer.json /

    composer.lock Private Repository

  43. 43 Semantic Versioning http://semver.org/ Version Numbers Have Meaning • Essentially,

    it is a promise from the development team • Not a guarantee, but best effort • 1.2.3 – numbers increment, can have pre-release suffix • Major.Minor.Patch • Patch: bug fixes; no BC breaks! No API changes! Everyone using the package should be confident in moving from 1.2.3 to 1.2.4 • Minor: introduce new features, but change no prior APIs; no BC breaks! Changing internals (refactoring) should not affect package users. Everyone using the package should be confident in moving from 1.2.3 to 1.3.0. • Major: API changes; BC breaks (whether intentional or not). Example: 1.3.14 to 2.0.0 • For developers, not marketing department.
  44. 44 Semantic Versioning and Composer Version Constraints Shortcut notations in

    Composer for version constraints • “Next Significant Release” • ^1.2.3 is same as >=1.2.3,<2.0.0 and means 1.2.3 <= x < 2.0.0 • Specifies a min version, and all non API-changing updates • Another (older form of) “Next Significant Release” • ~1.2.3 is same as >=1.2,<1.3.0 and means 1.2.0 <= x < 1.3.0 • Specifies a min version; last number specified can increment • For this example, we accept only bug-fixes, no new features. • ~1.2 is same as >=1.2,<2.0 and means 1.2.0 <= x < 2.0.0 • For this example, we accept all non-breaking changes • https://getcomposer.org/doc/articles/versions.md
  45. 45 Some Best Practices •Do’s and Don’ts: • Building a

    deployment fileset with Composer • Unbound Version Constraints • Version Constraints combined with Wildcards • Wildcards by themselves • Install or update to the intended directory Be careful out there!
  46. 46 Don’t install development requirements Use lock file Download Distribution

    Packages composer install - - prefer-dist - - no-dev - - optimize-autoloader Generate PSR-0/4 classmap for fast autoloading Building Deployment Filesets
  47. 47 Do NOT use unbound version constraints (>=, no upper

    bound): Example: >=2.3 Example: >=1.1.* (note that * is not the problem here, >= is) Example: dev-master Composer will install new updates, as long as they become available, without regard to backwards-compatibility. (You’ll get 2.3.5, 10.5.23, etc.) Solution: >=2.3,<3.0 or ~2.3 Solution: >=1.1.0,<1.2 or ~1.1.0 Best Practice: Use ^2.3 Use ^1.1 Best Practices Do’s and Don’ts
  48. 48 •Do NOT attempt to specify a version constraint with

    a wildcard: • Example: >=2.* >=2 means any version at least 2.0.0 (2.0.5, or 2.9.9, or 3.0.7, 10.3.2, etc.) 2.* means any version in the interval [2.0.0, 3.0.0), or 2.0.0-2.9.9999 • Composer can’t tell if you want 3.0.0 to be considered, or not. Composer: “Invalid, I’m throwing an error” Solution: use >=2,<3 Best Practice: ^2 (for semantic versioning) Best Practices Do’s and Don’ts
  49. 49 Do NOT use a wildcard (except for virtual extension

    packages) Example: 1.2.* is bad – slows composer down Looks at all patch level releases, and all their sub-dependencies Also limits composer to versions < 1.3 forever Composer: “Don’t make me work so hard!” Solution: (if you really want < 1.3) use ~1.2.0 or >=1.2.0,<1.3 or (if you really want >= 1.2) use ~1.2.0 or >=1.2.0,<2.0.0 or SemVer Best Practice: ^1.2 Best Practices Do’s and Don’ts
  50. 50 Best Practices Do’s and Don’ts •Make SURE you’re in

    right folder when issuing composer install • Will read composer.json in that folder, create vendor folder, and .lock file • Regardless of existence of .lock file in project root directory • Same for composer update! Part of your vendor folder could be updated with packages not compatible with other packages Run composer install /update from root of your project.
  51. 51 Resources • Composer Manual - https://getcomposer.org/doc/ • Semantic Versioning

    - http://semver.org/ • Autoloading - http://www.php-fig.org/psr/psr-4/ • JSON (JavaScript Object Notation) - http://json.org/ • Help - https://groups.google.com/forum/#!forum/composer-users • IRC - #composer on freenode irc://irc.freenode.org/composer • Packagist Semver Checker – http://semver.mwl.be/ • Composer.json Schema https://getcomposer.org/doc/04-schema.md https://github.com/composer/composer/blob/master/res/composer-schema.json http://stackoverflow.com/questions/tagged/composer-php
  52. THANK-YOU clark.e@zend.com +ClarkEverettsAtZend @clarkphp Slides for this talk at http://slideshare/

    Tweets: #zendcon Rate & comment on this session https://joind.in/15504 Your feedback is invaluable!