# Composer: The Package Manager for PHP

> Composer explained: understand composer.json, composer.lock, vendor and the autoloader, deploy cleanly to production and maintain dependencies securely.

Source: https://phpsos.de/en/php/composer/  
As of: 25/10/2026  
Provider: PHP SOS, PHP emergency help and server security. Immediate help via WhatsApp: https://wa.me/491736494914?text=Hello%20PHP%20SOS%2C%20we%20need%20help%20with%20our%20PHP%20server.%20Company%3A%20%E2%80%A6%20Website%3A%20%E2%80%A6

**In short:** Composer is the package manager for PHP. From the file `composer.json` it reads which libraries a project needs, downloads them into the `vendor` folder, records the exact versions in `composer.lock` and generates an autoloader that finds classes automatically. Composer thus manages your application's code, not the PHP interpreter itself: a Composer update does not close a flaw in PHP such as PHP2Shell.

## What is Composer and what is it needed for?

Hardly any PHP application today consists of its own code alone. Frameworks, mail libraries, PDF generation or payment integrations are added as ready-made packages. Composer, the package manager for PHP, ensures that these packages come together in matching versions and that every dependency brings along its own dependencies.

For decision-makers this means: a large part of the code running on your server comes from third parties. That is efficient but needs maintenance. For admins and developers it means: anyone who uses Composer cleanly can trace at any time which version of which library is running in production.

According to the Composer documentation, the default source for packages is Packagist.org. Other sources, such as an agency's internal repositories, can be entered in `composer.json` under `repositories`.

## composer.json, composer.lock and vendor: the three building blocks

Composer works with three things that you should know before taking over a server or commissioning an agency.

| Building block | Content | Belongs in the repository? |
|---|---|---|
| `composer.json` | desired packages with version ranges (`require`, `require-dev`), autoload rules, settings | yes |
| `composer.lock` | exactly resolved versions of all packages, including indirect ones | yes, explicitly according to the Composer docs |
| `vendor/` | downloaded code of the packages and the generated autoloader | no, it is generated during installation |

Under `require` are packages the application needs in operation. Under `require-dev` are tools for development and testing, such as test frameworks or static analysis. This separation is important because development tools have no place on a production server.

```json
{
    "require": {
        "php": ">=8.3",
        "monolog/monolog": "^3.0"
    },
    "require-dev": {
        "phpunit/phpunit": "^11.0"
    },
    "autoload": {
        "psr-4": { "App\\": "src/" }
    }
}
```

The version numbers in the example are chosen for illustration only. Which versions your project needs follows from its requirements.

## install or update: the difference in operation

The two commands sound similar but have very different consequences.

- `composer install` reads `composer.lock` and installs exactly the versions recorded there. This is reproducible and belongs in deployment.
- `composer update` resolves all dependencies anew, fetches the latest matching versions and rewrites `composer.lock`. This belongs in development, followed by tests.

According to the Composer documentation, after writing the lock file `update` additionally runs a security check (audit), unless it is switched off with `--no-audit`. `install` does not check by default; the option `--audit` exists for that.

## Autoloading: how Composer finds classes

Composer generates the file `vendor/autoload.php`. Once it is included, PHP loads each class only when it is needed. For your own code, the `autoload` section defines which namespace lives in which folder. PSR-4, a PHP-FIG standard, is recommended for this. Exactly how this works is explained on the page [Namespaces and autoloading](https://phpsos.de/en/php/namespaces-autoloading/); an overview of all standards is given on the page [PSR standards](https://phpsos.de/en/php/psr-standards/).

```php
<?php
require __DIR__ . '/../vendor/autoload.php';

$log = new Monolog\Logger('app');   // loaded automatically when needed
```

## Composer in production: deploying cleanly

A fixed sequence has proven itself for deployment. It runs best in a build pipeline and not by hand on the server.

1. **Check the lock file:** `composer validate` ensures that `composer.json` is valid and `composer.lock` is up to date.
2. **Install without development packages:** `composer install --no-dev` leaves out `require-dev`.
3. **Optimise the autoloader:** `--optimize-autoloader` (short `-o`) converts the rules into a class list. With `--classmap-authoritative`, PHP loads classes exclusively from this list.
4. **Security check:** `composer audit --locked` checks the versions from the lock file against known security advisories and reports abandoned packages.
5. **vendor outside the web root:** Only the public folder with the entry script should be reachable via URL.

```bash
composer validate
composer install --no-dev --optimize-autoloader
composer audit --locked --no-dev
```

`composer outdated` additionally shows which installed packages have newer versions. This is the basis for planned updates instead of hectic one-off actions.

## Composer, security and PHP2Shell

Composer and PHP2Shell concern two different levels. The flaws CVE-2026-109618 and CVE-2026-109619 lie in the PHP interpreter itself. They are fixed in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, and all PHP processes must be restarted afterwards. No `composer update` and no package in `vendor` changes that.

Even so, Composer belongs in every check after an incident. Anyone who brings malicious code onto a server can also change files in `vendor`, and `vendor/autoload.php` is loaded on every request. A fresh `composer install` from the verified lock file into an empty directory is therefore a good way to restore the package inventory. How to check dependencies regularly for known flaws is described in the guide [composer audit](https://phpsos.de/en/ratgeber/composer-abhaengigkeiten-pruefen/).

> **Important:**
> A green `composer audit` says nothing about PHP's patch level. Check the PHP runtime separately, for example with our [PHP patch service](https://phpsos.de/en/leistungen/php-patch-service/).

## How does PHP SOS help?

- For each application we record the PHP version, Composer packages and lock state, cleanly separating the interpreter from the libraries.
- We check whether `vendor` and the lock file match each other and whether development packages or altered files are present in production.
- We set up reproducible deployment with `install --no-dev`, an optimised autoloader and audit.
- After an incident we rebuild the package inventory from the verified lock file and document the result.


## Frequently asked questions

**Does composer.lock have to go into the Git repository?**  
Yes. The Composer documentation explicitly recommends committing composer.lock. Only then do development, CI and production install exactly the same package versions.

**What is the difference between composer install and composer update?**  
install installs the versions recorded in composer.lock. update resolves the dependencies anew, fetches suitable newer versions and rewrites composer.lock. On the production server only install belongs.

**Does a Composer update close the PHP2Shell flaw?**  
No. Composer manages your application's libraries, not the PHP interpreter. PHP2Shell is closed only by updating the PHP runtime to a fixed version and restarting all PHP processes.

**Where should the vendor folder be located?**  
Ideally outside the publicly accessible web directory. Many frameworks place only a public folder in the web root, while vendor sits one level above.

## Sources

- [Composer: Basic usage](https://getcomposer.org/doc/01-basic-usage.md)
- [Composer: Command-line interface](https://getcomposer.org/doc/03-cli.md)
- [Composer: The composer.json schema](https://getcomposer.org/doc/04-schema.md)
