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

Managing Dependencies with Composer (LakeKenosh...

Beau Simensen
September 17, 2013

Managing Dependencies with Composer (LakeKenoshaPHP September 2013)

Traditionally, managing third-party code in PHP projects has not been a trivial task. Fortunately, the PHP community now has Composer (https://getcomposer.org/), 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.

Beau Simensen

September 17, 2013
Tweet

More Decks by Beau Simensen

Other Decks in Programming

Transcript

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

    { “silex/silex”: “1.1.*” }, “autoload”: { “psr-0”: { “Acme\\MyProject\\”: “src” } } }
  2. // // Example autoloader that will load any fully qualified

    // class name in the Foo\Bar namespace. If someone tries // to load Foo\Bar\Baz, this autoloader will attempt to // include a file named src/Baz.php which is expected to // define Foo\Bar\Baz. // spl_autoload_register(function ($fqcn) { $prefix = 'Foo\\Bar\\'; $class = ltrim($class, '\\'); if (strncmp($prefix, $class, strlen($prefix)) === 0) { $relative = substr($class, strlen($prefix)); $file = __DIR__ . '/src/' . str_replace('\\', '/', $relative) . '.php'; if (is_readable($file)) { include $file; } } });
  3. // // life when everyone has their own custom //

    autoloader bootstrap, registration classes // and manually configuring class loaders // require “../vendor/whizbang/bootstrap.php”; require “../vendor/awesomesoft/bootstrap.php”; require “../vendor/lessawesome/bootstrapper.php”; require “../vendor/ultraframework/classloader.php”; LessAwesome\BootStrapper::register(); UltraFramework\ClassLoader::register(array( “\\Acme\\MyApp\\” = “../src” ));
  4. Other Version Schemes Can Be Used But don’t expect Composer

    to read your mind and do anything smart with them.
  5. • Integration into existing VCS workflow • Packaging is as

    simple as tagging and pushing • Hosting can be handled automatically by GitHub and BitBucket VCS Repository Benefits
  6. { “name”: “acme/my-project”, “description”: “Acme’s My Project”, “license”: “MIT”, “require”:

    { “silex/silex”: “1.1.*” }, “autoload”: { “psr-0”: { “Acme\\MyProject\\”: “src” } } }
  7. { “name”: “acme/my-project”, “description”: “Acme’s My Project”, “license”: “MIT”, “require”:

    { “silex/silex”: “1.1.*” }, “autoload”: { “psr-0”: { “Acme\\MyProject\\”: “src” } } }
  8. { “name”: “acme/my-project”, “description”: “Acme’s My Project”, “license”: “MIT”, “require”:

    { “silex/silex”: “1.1.*” }, “autoload”: { “psr-0”: { “Acme\\MyProject\\”: “src” } } }
  9. { “name”: “acme/my-project”, “description”: “Acme’s My Project”, “license”: “MIT”, “require”:

    { “silex/silex”: “1.1.*” }, “autoload”: { “psr-0”: { “Acme\\MyProject\\”: “src” } } }
  10. PSR-0’s Big Ideas • 1:1 mapping between fully qualified class

    names and the filesystem (one file / class) • Embrace namespaces • Support some legacy naming conventions
  11. { “autoload”: { “psr-0”: { “Acme\\MyProject\\”: “src” } } }

    $bar = new Acme\MyProject\Foo\Bar(); src/Acme/MyProject/Foo/Bar.php
  12. PSR-4’s Big Ideas • 1:1 mapping between a part of

    fully qualified class names and the filesystem (one file / class) • Minimize the number of extra directories that PSR-0 required • Drop support for legacy naming conventions that PSR-0 supported
  13. { “autoload”: { “psr-4”: { “Acme\\MyProject\\”: “src” } } }

    $bar = new Acme\MyProject\Foo\Bar(); src/Foo/Bar.php
  14. // // Example autoloader that will load any fully qualified

    // class name in the Foo\Bar namespace. If someone tries // to load Foo\Bar\Baz, this autoloader will attempt to // include a file named src/Baz.php which is expected to // define Foo\Bar\Baz. // // This is PSR-4 in a nutshell. // spl_autoload_register(function ($fqcn) { $prefix = 'Foo\\Bar\\'; $class = ltrim($class, '\\'); if (strncmp($prefix, $class, strlen($prefix)) === 0) { $relative = substr($class, strlen($prefix)); $file = __DIR__ . '/src/' . str_replace('\\', '/', $relative) . '.php'; if (is_readable($file)) { include $file; } } });
  15. Classmap Generates a single key => value map classes found

    by scanning for .php and .inc files in specified directories
  16. $ composer install If composer.lock does not exist, it installs

    from composer.json and creates composer.lock. If composer.lock exists, it installs from there.
  17. 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). — Semantic Versioning http://semver.org/
  18. If dependencies are specified too loosely, you will inevitably be

    bitten by version promiscuity (assuming compatibility with more future versions than is reasonable). — Semantic Versioning http://semver.org/
  19. { “require”: { “dflydev/doctrine-orm-service-provider”: “1.0.*”, “silex/silex”: “1.1.*”, “pimple/pimple”: “1.1.*”, “doctrine/orm”:

    “2.4.*” } } { “name”: “silex/silex”, “require”: { “pimple/pimple”: “1.*” } } { “name”: “dflydev/doctrine-orm-service-provider”, “require”: { “pimple/pimple”: “1.*”, “doctrine/orm”: “~2.3” } }
  20. Branch Aliases Composer can alias a named branch to a

    specific development version. Branch named master is treated as 2.0.*@dev
  21. • It is best to rely on version detection using

    tags and branches • There is a version key but do not use it • Composer skips branches and tags that do not have composer.json so you won’t magically get legacy versions VCS Repository Version Detection Gotchas
  22. Solver A C B I H 1.* ~2.3 D F

    E G 1.* 1.4.* >=2.3.5 J K 1.4.10