Diese Präsentation wurde erfolgreich gemeldet.
Die SlideShare-Präsentation wird heruntergeladen. ×

Composer Helpdesk

Wird geladen in …3

Hier ansehen

1 von 48 Anzeige

Weitere Verwandte Inhalte

Diashows für Sie (20)

Andere mochten auch (20)


Ähnlich wie Composer Helpdesk (20)

Aktuellste (20)


Composer Helpdesk

  1. 1. PHP Usergroup Munich 2015-01-28 HELPDESK
  2. 2. About me ● Sven Rautenberg ● Developing with PHP for >15 years now ● Currently working for Kabel Deutschland – Doing API stuff for ordering GUI interfaces – aka the PHP middleware in front of the Java middleware ● I do have a past at SELFHTML (selfhtml.org) ● Some activity at Stackoverflow for PHP, Log4php and Composer ● Twitter: @SvenRtbg
  3. 3. Questions ● Please ask at once – anything directly related to the current slide – me not cleanly explaining stuff, talking too fast or incomprehensible ● Try to wait until the end, Q&A session – anything broader, which may be answered by an upcoming slide – your own examples of Composer usage, failure and fixes
  4. 4. How to generally use it ● On 1 slide, because you already know it (or should): – getcomposer.org is the main page for software and documentation – downloading Composer from there is a one line CLI command curl -sS https://getcomposer.org/installer | php – mind the security implications of this command (discussed later) – for convenience: symlink/rename/move the downloaded phar file to composer and make it available in your $PATH – This should work anywhere now: composer –-help
  5. 5. Now let Composer do the work for you ● You have an existing project, or want to start a new ● Go to the root folder (top level GIT folder etc.) ● Use the command line composer init – This asks a lot of questions, with sensible default answers. – creates the initial composer.json in less than a minute.
  6. 6. vagrant@vbox /home/vagrant/myapplication $ composer init Welcome to the Composer config generator This command will guide you through creating your composer.json config. Package name (<vendor>/<name>) [root/composer-demo]: fancy-devshop/myapplication Description []: Does useful stuff for everybody. Author [Jane Doe <jane.doe@fancy-devshop.example>]: Minimum Stability []: License []: proprietary
  7. 7. Define your dependencies. Would you like to define your dependencies (require) interactively [yes]? no Would you like to define your dev dependencies (require-dev) interactively [yes]? no { "name": "fancy-devshop/myapplication", "description": "Does useful stuff for everybody.", "license": "proprietary", "authors": [ { "name": "Jane Doe", "email": "jane.doe@fancy-devshop.example" } ], "require": {} } Do you confirm generation [yes]? vagrant@vbox /home/vagrant/myapplication $
  8. 8. Epic win! ● You just enabled your project to make use of Composer – it has a name attached to be identified. – automatic detection of tagged versions and branches in it's repository – started the list of contributors with the configured GIT default info ● probably works with the other supported VCS as well – the license is optional, “proprietary” is for non-open source ● we are not going into details for this here ● Everything you did until now allows others to use your project, including yourself. We'll see some use cases later.
  9. 9. Using others' code for your project ● The obvious usage: Include useful libraries ● Main page to search: packagist.org ● Hint: – command line is easier than fiddling with the composer.json composer require zendframework/zend-cache:~2.2 composer require --dev symfony/console:~2.3 – and barely more typing – will install the library if a version matches everything else, or roll back – we get to the version details later on
  10. 10. How to install a foreign library 1. Find a suitable library – It should do what you want (useful, secure, nice defaults etc.) – It may match your style of programming – It should have an amount of documentation that you are happy with – It may have a reasonable number of installs according to Packagist – It should (read as: MUST) have tagged releases as version numbers. – The stability of the tagged releases don't matter as long as you can live with it. – Reminder: Versions do come later in this talk.
  11. 11. How to install a foreign library 2. Run Composer to fetch the code. composer require vendor/library:~1.0 3. Include the Composer autoloader in your bootstrapping require “vendor/autoload.php”; 4. Use the library classes, don't care about how to load them. 5. Profit!
  12. 12. Using Composer for your own project ● Using the autoloading of Composer for your own project! ● Multiple choices to make it work: – PSR-4 – PSR-0 – classmap – files ● Every existing code should be loadable via Composer somehow
  13. 13. PSR-4 ● Works for classes in namespaces only! ● Allows for shallow directory structures ● This autoload definition in composer.json “Namespace” : “src/” will autoload this class name new NamespaceAdapterFoobar() in this location src/Adapter/Foobar.php
  14. 14. PSR-4 ● Works for classes in namespaces only! ● Allows for shallow directory structures ● This autoload definition in composer.json “Namespace” : “src/” will autoload this class name new NamespaceAdapterFoobar() in this location src/Adapter/Foobar.php Escaping a backslash
  15. 15. PSR-4 ● Works for classes in namespaces only! ● Allows for shallow directory structures ● This autoload definition in composer.json “Namespace” : “src/” will autoload this class name new NamespaceAdapterFoobar() in this location src/Adapter/Foobar.php No namespace in path
  16. 16. PSR-0 ● Works for classes in namespaces and Under_Scored_Classes! ● This autoload definition in composer.json “Namespace” : “src/” will autoload this class name new NamespaceAdapterFoobar() in this location src/Namespace/Adapter/Foobar.php
  17. 17. PSR-0 ● This autoload definition in composer.json “Under_Scores_” : “src/” will autoload this class name new Under_Scores_Adapter_Foobar() in this location src/Under/Scores/Adapter/Foobar.php
  18. 18. PSR-0 What to avoid! ● This autoload definition in composer.json “” : “src/” will autoload this class name new Under_Scores_Adapter_Foobar() in this location src/Under/Scores/Adapter/Foobar.php ● Any will try to locate all other classes under src as well. ● Failing to find the file here, will search in the next possible location, but with useless file system lookups – is slow!
  19. 19. PSR-0 What to avoid! ● A real example from this morning: – We are using a modified Zend Framework 1 with this autoloading: “Zend” : “src” – and the stock Zend Framework 2 components ● Loading this class from ZF2 new ZendEventManagerSharedEventManager() will incorrectly detect this file as existing from ZF1 src/Zend/Eventmanager/SharedEventManager.php – which contains class Zend_EventManager_SharedEventManager …
  20. 20. PSR-4 & PSR-0 summary ● Prefer PSR-4 if possible – When you are using namespaces, use PSR-4! ● Aim for the longest possible or reasonable prefix! – Have an underscore or backslash at the end of the prefix! – You can define multiple entries for different prefixes in your code base “Models”: “lib/models/” “Database_”: “lib/databases/” – If the same prefix is also used in a different code base, make it longer. ● PSR-0 can be converted to PSR-4 for namespaced classes “Namespace” : “src/” <=> “Namespace”: “src/Namespace/”
  21. 21. Classmap ● If your code doesn't fit into PSR-4 or PSR-0 scheme. ● Composer will scan all directories for PHP files containing classes/interfaces/traits and will add them to a lookup array (aka classmap). ● Newly created files won't be added automatically! Annoying. composer dump-autoload ● Good for old code bases that you don't actively work on, but can't convert to PSR-* either.
  22. 22. Classmap ● This definition “classmap”: [“src1/path”, “src2/path”] will search for auto-loadable stuff in both directories. ● Try to scan as few directories as possible - it will slow down any Composer command that creates a new autoloader. ● Don't impose it on everyone for PSR-0 or PSR-4 code because “Classmaps are faster” - let them decide themselves with composer dump-autoload –optimize ● Performance discussion on Stackoverflow (link)
  23. 23. Files ● The final method if all else fails. ● Composer will always include the files you declare here, the code is always available even if not needed. – Try to avoid doing slow things in these files. ● Use this for your functions that are not inside classes – Autoloading for functions doesn't exist yet. – Maybe moving the functions to a class and call them statically instead. ● You may also add your own autoloading function here in case you cannot make classmap work for you.
  24. 24. ... "require": { "zendframework/zend-cache": "~2.2" }, "require-dev": { "symfony/console": "~2.3" }, "autoload": { "psr-4": { "Fancy": "src/fancystuff/" "Devshop: "library/Devshop/" }, "psr-0": { "Devshop_": "library/legacy/" }, "classmap": [ "library/non-fancy-stuff/" ] } }
  25. 25. Epic win! ● Your own code is now autoloaded via Composer alongside all external libraries. ● All classes you might use anywhere in the code are available without first loading their code! ● You are only one step away from creating your own library that you can use in multiple of your own projects!
  26. 26. Versions and Composer ● Composer does not impose any specific version scheme besides the fact that it has to be numeric. – No code names as version identifiers. – One single integer number should work, but is uncommon. ● However Composer suggest to use semantic versioning and has convenient operators for this – Tilde operator: ~2.3 – Caret operator: ^4.4.2
  27. 27. Semantic versioning: X.Y.Z ● Independent integers x,y,z, no float, more than one digit possible – Example 1.9.0 → 1.10.0 → 1.11.0 ● Bugfixes: increase Z ● Compatible new feature: increase Y ● Incompatible new releases: increase X ● Suffix like “alpha”, “beta”, “RC” allowed to denote lesser stability – Denotes a version before the original, i.e. 1.0.0-alpha < 1.0.0 ● More details: semver.org
  28. 28. Tagging your library ● Try to stick to semantic versioning as closely as possible – It will make your life so much easier! ● 1.0 and 1.0.0 is semantically the same, but a different VCS tag! – Accidentially re-tagging 1.0 as 1.0.0 cannot be detected by your VCS – Haven't checked what Composer will do in this case. – Best practice: Always three digits ● Do use alpha, beta, RC for versions undergoing development ● Avoid using 0.9.x for development and 1.0.0 for release – understood as an incompatible change, probably wrong
  29. 29. Adding your library to your own project ● Assume you have tagged your first version 1.0.0 – You want to use this version only composer require fancy-devshop/library:1.0.0 – You want to allow updating to later bugfixes composer require fancy-devshop/library:1.0.* – You want to allow updating to later compatible features composer require fancy-devshop/library:~1.0 composer require fancy-devshop/library:^1.0.0 ● How to make your library known to Composer without publishing it on packagist.org: Wait a few slides.
  30. 30. Version requirements ● When you update all your dependencies, you run composer update ● The version requirement affects what may be installed – 1.0.0 → exactly this version – 1.0.* → any version starting with 1.0 – allows all later patches – ~1.0 → equivalent to >=1.0, <2.0, allows for compatible updates – ^1.0.0 → equivalent to >=1.0.0, <2.0, allows for compatible updates ● Not really useful – >=1.0.0 → allows for incompatible updates to versions 2 and beyond
  31. 31. Difference between ~ and ^ ● ^ is the newest addition from 2014-12-08 – “^1.0.2” → >= 1.0.2, < 2.0, installs at least the patch level mentioned – “^0.8.1” → >=0.8.1, <0.9, is more defensive with unstable versions ● Doing almost same with ~ isn't the same – “~1.0.2” → => 1.0.2, <1.1 won't include compatible updates – “~1.0, >=1.0.2” → minimum patch level needs two constraints – No special case for unstable versions ● Use ~ or ^ for your version requirements! – Unless the external software does not honor semantic versioning.
  32. 32. { "name": "fancy-devshop/myapplication", "description": "Does useful stuff for everybody.", "license": "proprietary", "authors": [ { "name": "Jane Doe", "email": "jane.doe@fancy-devshop.example" } ], "require": { "fancy-devshop/library": "^1.0.2" }, "autoload": { "psr-4": { "Devshop: "library/Devshop/" }, "psr-0": { "Devshop_": "library/legacy/" } } }
  33. 33. { "name": "fancy-devshop/library", "description": "Increases fancyness.", "license": "proprietary", "authors": [ { "name": "Jane Doe", "email": "jane.doe@fancy-devshop.example" } ], "require": {}, "autoload": { "psr-4": { "Fancy: "src/" } } }
  34. 34. Epic win! ● Our application is using Composer for autoloading, and adding internal and external libraries. ● Our internal library is using Composer for autoloading. – It may use Composer for it's own internal and external dependencies. ● The library has releases that are simply tags in the VCS. ● The application can update everything based on version requirements that SHOULD be compatible to the initial version. – You DO have tests to check if everything works after an update?
  35. 35. What is still missing? ● How to publish your internal libraries without making them public on packagist.org? ● How to develop a library and use a dev version in the application at the same time? ● How to figure out what dependencies and sub-dependencies are really included in a package? ● How to define dependencies that are only used for development? ● What about security?
  36. 36. Publishing the quick way ● Composer by default only asks packagist.org as repository. ● You can add your own repository in composer.json: “repositories”: [ { “type”: “vcs”, “url”: “ssh://git@fancy-repo.example” } ] ● Composer will then ask for the composer.json in this repo (in all branches and tags), check whether it has a package name you want to use, and clone or download the correct version. ● Drawback: Does only work at the top level (i.e. your application) – Does not work recursively in libraries you require (with good reasons)
  37. 37. Publishing the easy way ● You need a local instance of either one of these: – Satis (generates static files and dumps downloadable versions) – Packagist (available for local hosting, dynamic updates) – Toran Proxy (license costs support Composer development) ● You add this instance location to all your composer.json files “repositories”: [ { “type”: “composer”, “url”: “http://fancy-repos.example/satis-files” } ]
  38. 38. Publishing the “easy” way ● You configure your local Packagist clone accordingly. – It should fetch all necessary data from your local repositories. – It will publish these at the location given. ● Composer will first read from this local repo before going to packagist.org – Works recursively, because the packagist clone is defined at top level in every package. – All local packages are known by the clone. – All external packages are known by packagist.
  39. 39. Satis example ● Satis is available on Github ● Configuration example creates downloadable ZIP packages for each version. Composer will cache these locally. ● Run the Satis CLI command every time you need the static files updated. ● Lesser known feature: Composer allows to link to other composer-repositories
  40. 40. { "name": "Fancy Devshop", "homepage": "https://fancy-devshop.example/satis-files", "repositories": [ { "type": "vcs", "url": "ssh://git@fancy-gitserver.example:2222/repos/library.git" }, { "type": "composer", "url": "https://fancy-devshop.example/released-fairy-dust" } ], "require-all": true, "archive": { "directory": "dist", "format": "zip", "prefix-url": "https://fancy-devshop.example/satis-files", "skip-dev": true }, "twig-template": "views/index-fancy.html.twig" }
  41. 41. Epic win! ● The application's dependencies can be loaded from the local Satis or from Packagist. ● New versions of local libraries will be detected and published locally (manually, with a cronjob, with a repo hook). ● This should be all you need to finally be able to deploy! – I won't go into deployment details now, but as a hint: composer install --no-dev
  42. 42. How to use a package under development? ● Tagging every single commit is not helpful. ● Add a branch with a version alias composer require "fancy-devshop/library:dev-master as 2.0.0-dev" ● Or create a branch resembling the target version git branch 2.0.x composer require "fancy-devshop/library:~2.0@dev" – Update regularly composer update ● Upgrade the version requirement after release.
  43. 43. How to get an overview of used packages? ● The composer.lock file has every package and version recorded that is being used. Always commit this file! ● Reading it isn't nice, but you can see some details. ● What about a picture? Use clue/graph-composer ● Needs graphviz installed to render the pictures. ● Shows all the dependencies and version requirements.
  44. 44. How to treat code used for development only? ● Add stuff like PHPUnit, Mockery, as a dev dependency composer require --dev phpunit/phpunit:~4.4 ● Add your own development code as dev autoloading: “autoload-dev”: { “psr-4”: { “Tests”: “tests/helpers/” } } ● This will not be added or installed when you run with --no-dev
  45. 45. Security considerations ● Composer currently has no code signing or security layer! ● There is some security coming from GIT commit ids and using HTTPS. ● Assume everything outside your own environment is compromised and broken if you really have sensitive applications that undergo audits. ● Think about cloning external software into local repos, then treating them as local software. ● You can disable using Packagist in composer.json “repositories”: [ { “packagist”: false } ]
  46. 46. Thank you! ● And now it's time for all your questions! ● Slides will be online soon. ● Contact me or ask questions here: – Twitter: @SvenRtbg – StackOverflow: Sven