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

Composer Helpdesk

Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Wird geladen in …3
×

Hier ansehen

1 von 48 Anzeige

Weitere Verwandte Inhalte

Diashows für Sie (20)

Andere mochten auch (20)

Anzeige

Ähnlich wie Composer Helpdesk (20)

Aktuellste (20)

Anzeige

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

×