Na navigaci | Klávesové zkratky

Composer: How to Install in Different Ways

Composer, the most important tool for PHP developers, offers three methods to install packages:

  • local composer require vendor/name
  • global composer global require vendor/name
  • as a project composer create-project vendor/name

Local Installation

Local installation is the most common. If I have a project where I want to use Tracy, I enter in the project's root directory:

composer require tracy/tracy

Composer will update (or create) the composer.json file and download Tracy into the vendor subfolder. It also generates an autoloader, so in the code, I just need to include it and can use Tracy right away:

require __DIR__ . '/vendor/autoload.php';
Tracy\Debugger::enable();

As a Project

A completely different situation arises when, instead of a library whose classes I use in my project, I install a tool that I only run from the command line.

An example might be ApiGen for generating clear API documentation. In such cases, the third method is used:

composer create-project apigen/apigen

Composer will create a new folder (and thus a new project) apigen and download the entire tool and install its dependencies.

It will have its own composer.json and its own vendor subfolder.

This method is also used for installations like Nette Sandbox or CodeChecker. However, testing tools such as Nette Tester or PHPUnit are not installed this way because we use their classes in tests, calling Tester\Assert::same() or inheriting from PHPUnit_Framework_TestCase.

Unfortunately, Composer allows tools like ApiGen to be installed using composer require without even issuing a warning.

This is equivalent to forcing two developers, who don't even know each other and who work on completely different projects, to share the same vendor folder. To this one might say:

  • For heaven's sake, why would they do that?
  • It just can't work!

Indeed, there is no reasonable reason to do it, it brings no benefit, and it will stop working the moment there is a conflict of libraries used. It's just a matter of time, like building a house of cards that will sooner or later collapse. One project will require library XY in version 1.0, another in version 2.0, and at that point, it will stop working.

Global Installation

The difference between option 1) and 2), i.e., between composer require and composer global require, is that it involves not two, but ten different developers and ten unrelated projects. Thus, it is nonsensical squared.

Because composer global is a bad solution every time, there is no use case where it would be appropriate. The only advantage is that if you add the global vendor/bin directory to your PATH, you can easily run libraries installed this way.

Summary

  • Use composer require vendor/name if you want to use library classes.
  • Never use composer global require vendor/name!
  • Use composer create-project vendor/name for tools called only from the command line.

Note: npm uses a different philosophy due to JavaScript's capabilities, installing each library as a “separate project” with its own vendor (or node_modules) directory. This prevents version conflicts. In the case of npm, global installations of tools, like LESS CSS, are very useful and convenient.

10 years ago in section PHP | blog written by David Grudl | back to top

You might be interested in


phpFashion © 2004, 2024 David Grudl | o blogu

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.