【PHP】逆引き！Composer コマンド・ライン一覧 と 基礎知識

:::note warn
🐒 【2020/11/18 追記】2020/10/24 に Composer の **v2 が[リリースされました](https://blog.packagist.com/composer-2-0-is-now-available/)**。<br><sub><sup>速度改善、PHP 7.4 以降対応、パッケージ名の厳名化、`composer` 経由の PEAR 利用の終了など[変更点が盛り沢山](https://github.com/composer/composer/blob/2.0.0/UPGRADE-2.0.md)です。そのため、急に動かなくなるパッケージが出てきています。パッケージマネージャー、Docker や CI などで `composer` を自動インストールしている人はデフォルトで v2 になるので<strong>要注意</strong>です。<br>各種主要パッケージの追随が落ち着くまでの間、バージョンを固定しておきたい場合は、composer 本体のインストールや更新は下記のように `--version` オプションでバージョンを指定してください。</sup></sub>

```bash:composerのインストーラーでv1.10.17に固定する例
composer-setup.php --version=1.10.17 
```
```bash:既存のcomposerのバージョンを変える・固定する例
composer self-update 1.10.17
```
:::

## PHP のパッケージマネージャー `Composer`

この記事は、**`Composer` のコマンド・ライン逆引き辞書**です。

- [Composer コマンドライン一覧](https://getcomposer.org/doc/03-cli.md) @ getcomposer.com （本家, 英語）
- [Composer のオススメ Qiita 記事一覧](#composer-%E3%81%AE%E3%82%AA%E3%82%B9%E3%82%B9%E3%83%A1-qiita-%E8%A8%98%E4%BA%8B%E4%B8%80%E8%A6%A7)
- Composer とは
    - [Composer の基礎知識](#composer-%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98)
    - [名前空間とは](https://qiita.com/KEINOS/items/2924ecde3e4bab0ead7e#%E5%90%8D%E5%89%8D%E7%A9%BA%E9%96%93%E3%81%A8%E3%81%AF)

:::note info
<sub><sup>🐒 &nbsp;「いいね」（旧　LGTM）が付くたびに何かしら見直して手を加えています。変更通知は送りませんので「ストック」されても変更に気づかれないかもしれません。お手すきに気が向いたら、また覗きに来てください。追加・誤記修正・同じコマンドの別表記など、何かありましたら遠慮なく<a href="https://qiita.com/KEINOS/items/86a16b06af6e936a1841/edit">編集リクエスト</a>下さい。ほぼ自動で反映させます。</sup></sub>
:::

<details><summary>まえがき</summary><div><br>

[子](https://qiita.com/tadsan)曰く 

> 「[composer.json の require を直接編集してはいけない](https://qiita.com/tadsan/items/3a753f9eca83f2867a0a)」by @tadsan @ Qiita

つまり、専用のコマンドがあるのに **`composer.json` を直接エディタで編集するのはバッドノウハウ**。専用のコマンドがあるのに、素人にエディタで編集させる記事は[バッドメディシン](https://www.google.com/search?q=%E3%83%90%E3%83%83%E3%83%89%E3%83%A1%E3%83%87%E3%82%A3%E3%82%B7%E3%83%B3)。

```php:コマンド・ラインで追記する例
$ # 文法
$ #   composer require [vendor]/[package]
$ # 使用例
$ composer require symfony/console
```

餅は餅屋に任せた方が安心でうまいということ。13 日の金曜でもないのに JSON からエスケープなんて怖いこと考えなくていいので安全ということ。

> <sup>🐒 &nbsp; ただ Composer の中の人たちは「[JSON なんだから何でも CLI で変更させる必要はないんだ、マイフレンド](https://github.com/composer/composer/issues/3398#issuecomment-210562767)」というスタンスのようで、`autoload` などの設定はコマンド・ラインからは追加できません。(´・ω・｀)</sup>
>
> - <sup>ここ１年以内に更新もしくは作成された[「php composer autoload」の Qiita 記事一覧](https://www.google.com/search?q=site:qiita.com+php+composer+autoload&tbs=qdr:y) @ Google</sup>

---

</div></details>

<details><summary>README.md</summary><div>

- 本記事は `composer.phar` を `composer` とリネームして事前に[パスを通す](https://www.google.co.jp/search?q=site:qiita.com+%E3%83%91%E3%82%B9%E3%82%92%E9%80%9A%E3%81%99)ことを前提としています。
- パスを通していない場合は `$ composer [hoge]` の箇所を `$ php /path/to/your/composer.phar [hoge]` など、**`composer.phar` の実際の設置先と置き換えて**下さい。
- `$ composer` の `$` 付き表記はコマンド・ラインでの入力例です。
- ユーザー指定の必須項目は `[]` で囲っています。

    ```php:フォーマットと実際の記述例
    $ # composer require [vendor]/[package]
    $ composer require keinos/project_x
    ```

- デフォルトの設定として登録する場合は `global` オプションをつけてください。

    ```php:現在のパッケージに適用
    $ # global なし →　./vendor/ 下にインストールされます
    $ composer require keinos/project_x
    $ # global あり → ~/.composer/vendor/ 下にインストールされます
    $ composer global require keinos/project_x
    ```

- `composer.json` のある作成中のアプリ（ライブラリ、プロジェクト、etc）は「自身のパッケージ」と呼んでいます。（`Root`パッケージ = 自身のパッケージ）
</div></details>

--------------------------------------------------------------------------------

## 逆引き一覧

### `composer` 本体

#### ダウンロードとインストール

**▼ `composer` 自体（本体）をダウンロードしたい**

本家（`composer` 公式）のサイト上部にある php から始まる 4 行を実行してダウンロードします。（王道）

> [Download Composer](https://getcomposer.org/download/) @ Composer 公式

<details><summary>... ... どれ？</summary><div>

<img width="100%" alt="スクリーンショット 2019-12-10 11.15.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78776/58f8d465-900b-335e-98e6-3924f1bb05d8.png">

PHP v5.3.2 以上がインストールされていれば、上記４行を実行すると `composer.phar` ファイルがカレント・ディレクトリ（現在の作業ディレクトリ）に作成されます。

処理内容としては、`composer-setup.php` をダウンロードして、ファイルのハッシュ値を検証したのち、OS や PHP のバージョンに合わせた最新の `composer.phar` をダウンロードします。

途中、チョロリと見えているハッシュ値（`a5c698...` のデータ識別値）はリリースごとに変わります。

そのため、[CI](https://ja.wikipedia.org/wiki/%E7%B6%99%E7%B6%9A%E7%9A%84%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3) や [Docker](https://ja.wikipedia.org/wiki/Docker) といった**自動インストールが必要な環境には向きません**。

:::note info
Docker の場合は[公式の Composer イメージ](https://hub.docker.com/_/composer)を利用するのがベストですが、CI のように別途インストールが必要な場合は、後述するシェル・スクリプトなどから `composer` 本体をダウンロードする方法各種をご覧ください。
:::

ダウンロードされた `composer.phar`（`composer` の本体）はカレント・ディレクトリに設置されるため、実行するたびに `composer.phar` ファイルをパスで指定する必要があります。

```php:ダウンロードしたcomposerの実行例
$ ./composer.phar --version
$ php ./composer.phar --version
$ php /path/to/downloaded/composer.phar --version
```

インストール、つまりパスを通したい場合は次項の「`composer` コマンドをどこからでも実行できるようにしたい」を参照してください。

:::note warn
🐒 <strong><font color=darkorange>【注意】</font></strong>
たまに <code>composer</code> のインストールは「<code>curl -sS https://getcomposer.org/installer | php</code> だけでおk」と案内しているブログ記事がありますが、推奨されていません。
この方法は <a href="https://ja.wikipedia.org/wiki/%E7%B6%99%E7%B6%9A%E7%9A%84%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3" target="_blank">CI</a> や <a href="https://ja.wikipedia.org/wiki/%E7%B6%99%E7%B6%9A%E7%9A%84%E3%83%87%E3%83%AA%E3%83%90%E3%83%AA%E3%83%BC" target="_blank">CD</a> といった使い捨ての環境で、テスト目的に使うぶんにはいいのですが、<font color=darkorange>**メインとなる開発環境へのインストール方法としては推奨されていません**</font>。
確かに、同じ `https://getcomposer.org/installer` のインストーラーをダウンロードしているし、インストーラーの中身を見ると、公開鍵暗号で署名すら確認してインストールする堅牢なスクリプトであることが確認できます。
しかし、肝心のインストーラー自身のハッシュ値を確認していません。
これには、重要な２つの理由があります。根幹となるアプリの改ざん対策と破損防止です。
１つ目の「改ざん防止」は、<strong>不正な <code>composer</code> 本体を使った場合、インストールされるパッケージ全てが信用出来なくなるから</strong>です。推奨されているどの方法も、インストーラーと、その署名（<code>signagure</code>）を「各々別のドメイン」からダウンロードしていることに注目ください。
２つ目の「破損防止」は、<strong><code>composer</code> 本体の一部が壊れてるも主な機能に支障がなく、気付かないで使い続ける事を避けるため</strong>です。PHP は Web を主体としていたため、致命的でない限り止まることより動くことを優先して来ました。一部が壊れてしまっても、該当箇所まで処理が及ばないと動いちゃう事が多くあります。コンパイル型でないためです。
この、壊れてるのに動いちゃう仕組みは意図しない不具合を発生する事にもつながり、パッケージの作者に「バグだバグだ」と再現性のない不具合を報告しない為にも、最初のステップでしっかりとハッシュ値が合っているか確認しましょう。
なお、ハッシュ関数を使って確認している理由が知りたい方は、下記記事の「ハッシュ関数の基本と特徴」をご覧ください。

- <a href="https://qiita.com/KEINOS/items/c92268386d265042ea16#%E3%83%8F%E3%83%83%E3%82%B7%E3%83%A5%E5%80%A4%E3%81%AE%E8%A1%9D%E7%AA%81%E3%81%AF%E5%88%A5%E3%81%AE%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0%E3%81%A7%E3%81%AF%E8%A1%9D%E7%AA%81%E3%81%97%E3%81%AA%E3%81%84%E9%99%90%E3%82%8A%E3%81%AA%E3%81%8F" target="_blank">ハッシュ関数の基本と特徴</a> | hashアルゴリズムとハッシュ値の長さ一覧 @ Qiita
:::

---

</div></details>

<details><summary>別途インストールが必要なものはある？</summary><div>

<h4>Composer 自体の依存（<code>Requirements</code>）</h4>

> `zip` 関連のライブラリと、`git` などのバージョン管理ツールがインストールされている必要があります。

`composer.phar` 自体は PHP v5.3.2 以上が利用可能であれば単体で動きます。しかし、条件によって `unzip` や `git` といったパッケージ管理に必要なツールを別途インストールする必要があります。

いずれのツールも、必要かつインストールされていない場合は `composer` 利用時にエラーで知らせてくれます。もしくは `composer diagnose` コマンドで確認することもできます。

<h5>ZIP 解凍ツール</h5>

`composer` はパッケージの解凍に `zip`/`unzip` を必要とします。OS に `unzip` もしくは `7z`(`7zip`) がインストールされている場合は、それらが使われ、インストールされていない場合は PHP の [ZipArchive](https://www.php.net/manual/ja/class.ziparchive.php) を使います。しかし、`ZipArchive` は `zlib` モジュールに実行権限問題が発生することがあるため、[`unzip` もしくは `7zip` コマンドを別途インストールすることが推奨](https://getcomposer.org/doc/articles/troubleshooting.md#zip-archives-are-not-unpacked-correctly-)されています。権限の問題で別途必要な場合は、メッセージが表示されます。

<h5>バージョン管理ツール</h5>

`composer` に対応したパッケージを使う場合、`zip` アーカイブされたパッケージをダウンロード & 解凍後後、パスの通ったディレクトリに設置（つまりインストール）することで使えます。しかし、この方法はオフライン環境での利用がメインです。

通常は、最新のパッケージを手軽にインストール・更新できるようにパッケージのリポジトリ（パッケージ・データの置いてあるサーバー）からインターネットを通じてダウンロード & インストールすることになります。

つまり、[Packagist](#composer-%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98) や GitHub といった [VCS（バージョン管理システム）](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)のリポジトリからインストールする場合です。その場合（通常は大半の場合）、VCS のパッケージ管理コマンド・ツールが別途必要になります。

`composer` は以下の VCS に対応しています。

- `git` `svn` `fossil` `hg`

特に利用するリポジトリの種類が決まっていない場合は、Packagist、GitHub や GitLab などの相性を考えて <strong><font color=darkorange><code>git</code> をインストールすることを個人的に（筆者は）オススメ</font></strong>します。

---

</div></details>


**▼ `composer` コマンドを、どこからでも実行できるようにしたい**

パスの通ったディレクトリに「拡張子なし」で設置してインストールします。（以下は Linux / Unix / macOS / Windows WSL2 の bash）

```shell-session
$ # カレント・ディレクトリに composer.phar があるか確認
$ ls ./
composer.phar

$ # PHP 本体（ランタイム）の保存先ディレクトリを確認
$ dirname $(which php)
/usr/bin/php

$ # PHP と同じディレクトリに拡張子なしで移動し、実行権限を与える（要 sudo 権限）
$ mv ./composer.phar $(dirname $(which php))/composer && chmod +x "$_"

$ # 動作確認
$ composer --version
```

**▼ `composer` がインストールできない環境で `composer` を使いたい**
**▼ SSH が使えないレンタルサーバーで `composer` を使いたい**
**▼ パスの通ったディレクトリにアクセス権限のないサーバーで `composer` を使いたい**

`composer` は Phar 形式というだけで、実体は PHP ファイルです。つまり、`$ php ./composer.phar [コマンド]` で `$ composer [コマンド]` と同等のことができます。

そのため、ローカルで `composer.phar` をダウンロードしてアップロードすれば利用できます。利用といってもスクリプトで `php composer.phar [コマンド]` を実行させるという意味です。

しかし、スクリプトで `composer` コマンドを代替実行をする必要はほとんどありません。大抵の場合はローカルで実行したものをアップロードするだけで動くはずです。詳しくは「[Composer の基礎知識](https://qiita.com/KEINOS/items/86a16b06af6e936a1841#composer-%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98)」をご覧ください。

**▼ macOS の `brew` で `composer` をインストールしたい**

```bash
brew install composer
```

**▼ シェル・スクリプトなどから `composer` 本体をダウンロードだけしたい**

```bash:シェル・スクリプトの中身
#!/bin/sh

EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)"
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"

if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
then
    >&2 echo 'ERROR: Invalid installer signature'
    rm composer-setup.php
    exit 1
fi

php composer-setup.php --quiet
RESULT=$?
rm composer-setup.php
exit $RESULT
```

- 最新版＆参考文献: [How do I install Composer programmatically?](https://getcomposer.org/doc/faqs/how-to-install-composer-programmatically.md) @ Composer 公式より
- **Composer 本体のバージョンを固定したい**場合は、上記の `php composer-setup.php --quiet` を `php composer-setup.php --quiet --version=1.10.17` とバージョン・オプションを指定します。[[composer のバージョン一覧](https://github.com/composer/composer/tags)]

> <sup>🐒 &nbsp; Docker、Vagrant や CI など、**スクリプトで `composer` をダウンロードしたい場合**は上記スクリプトもしくは次項のスクリプトを利用します。このスクリプトはダウンロードのみで、環境変数の `$PATH` には設置（インストール）しないので<font color=red>注意</font>してください。別途、任意のパスに移動させるスクリプトを追記する必要があります。</sup>
> <sup>**ダウンロードと同時にインストールしたい（パスを通したディレクトリに移動したい）場合は、次項も参照**してください。</sup>

**▼ シェル・スクリプトなどから `composer` 本体をダウンロード＆インストールしたい**

`--install-dir` オプションを付けるとインストール先を指定できます。また `--filename` オプションで保存時のファイル名を指定できます。

以下は、スクリプトでインストールすると同時に `/bin` ディレクトリに `composer.phar` を `composer` としてインストールする例です。

```bash:シェル・スクリプトの中身
#!/bin/sh

EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)"
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"

if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
then
    >&2 echo 'ERROR: Invalid installer signature'
    rm composer-setup.php
    exit 1
fi

php composer-setup.php --quiet --install-dir=/bin --filename=composer
RESULT=$?
rm composer-setup.php
exit $RESULT
```

- **Composer 本体のバージョンを固定したい**場合は、上記の `php composer-setup.php --quiet --install-dir=/bin --filename=composer` を `php composer-setup.php --quiet --install-dir=/bin --filename=composer --version=1.10.17` とバージョン・オプションを指定します。[[composer のバージョン一覧](https://github.com/composer/composer/tags)]

**▼ Docker イメージに `composer` 本体をダウンロード＆インストールしたい**

以下は `php:cli-alpine` の Docker イメージをベースイメージとして、`composer` をインストールする `Dockerfile` の例。

```dockerfile
FROM php:cli-alpine

# Install composer
RUN \
    EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)"; \
    php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"; \
    ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"; \
    [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ] && { >&2 echo 'ERROR: Invalid installer signature'; exit 1; }; \
    php composer-setup.php --quiet --install-dir=/bin --filename=composer && \
    composer --version && \
    rm composer-setup.php
```

- **Composer 本体のバージョンを固定したい**場合は、上記の `php composer-setup.php --quiet --install-dir=/bin --filename=composer` を `php composer-setup.php --quiet --install-dir=/bin --filename=composer --version=1.10.17` とバージョン・オプションを指定します。[[composer のバージョン一覧](https://github.com/composer/composer/tags)]


--------------------------------------------------------------------------------

### `composer.json`

#### 新規作成・初期化

**▼ 新規パッケージ作成（自身のパッケージ作成）用に `composer.json` ファイルを対話式で作りたい**
**▼ 新規パッケージの作成を確認しながら初期化したい**
 
```php
$ composer init
```

**▼ 空の `composer.json` ファイルを作りたい**

```php
$ composer init --quiet
```

- `{"require": {}}` だけの `composer.json` が作成されます。

**▼ 必要最低限の `composer.json` ファイルを作りたい**

必須項目は "`name`" と "`description`" の２項目ですが、"`license`" がないとワーニングが表示されるので、実質 "`name`"、"`description`" と "`license`" の３項目と言えます。

```php
$ composer init --quiet --name=my_vendor/my-package --description="My description" --license=MIT
```

以下の JSON ファイルが作成されます。

```json
{
    "name": "my_vendor/my-package",
    "description": "My description",
    "license": "MIT",
    "require": {}
}
```

- "`name`" は、以下の正規表現にマッチする必要があります。（`[ベンダー名]/[パッケージ名]`）
    - `^[a-z0-9]([_.-]?[a-z0-9]+)*/[a-z0-9](([_.]?|-{0,2})[a-z0-9]+)*$`
- "`license`" は、[SPDX](https://ja.wikipedia.org/wiki/Software_Package_Data_Exchange) で制定されている `Identifier` である必要があります。
    - [composer で定義できるライセンス（`dentifier`）一覧](https://spdx.org/licenses/) @ spdx.org


**▼ 新規パッケージ作成時に、依存パッケージも指定しておきたい**（ついでに `require` もしておきたい）
**▼ パッケージの初期化時に複数の依存パッケージも指定しておきたい**

```php
$ composer init --require [vendor/package1] [vendor/package2]
```

**▼ `require` 情報だけの `composer.json` を作りたい**

```php
$ composer require [vendor/package1] [vendor/package2]
```

> <sup>🐒 &nbsp; 上記は、`composer.json` がない場合に `require` 情報だけを記載した `composer.json` を新規作成してパッケージをインストールしてくれます。これは、自身のパッケージは再配布予定がなく、**シンプルに依存パッケージだけ使いたい**場合に便利です。</sup>

**▼ `composer.json` とは別の JSON ファイルに `require` 情報を追加したい**
**▼ `require` 情報だけの別の JSON ファイルを作成したい**
**▼ 別名の `composer.json` ファイルに `require` 情報だけ追加して作成したい**
**▼ 別名の `composer.json` ファイルに `require` 情報を追加したい**

```php:composer-other.jsonを作成する例
COMPOSER=composer-other.json composer require phpunit/phpunit
```

**▼ 新規パッケージ作成時に、依存パッケージもバージョンで指定しておきたい**

```php
$ composer init --require vendor/package1:1.0.0
```

**▼ 新規パッケージ作成時に、開発用のパッケージも指定しておきたい**（ついでに `require-dev` もしておきたい）
**▼ パッケージの初期化時に、複数の開発用パッケージも指定しておきたい**

```php
$ composer init --require-dev [vendor/package1] [vendor/package2]
```

**▼ 新規パッケージ作成時に GitHub 上の自作パッケージも指定したい**
**▼ 新規パッケージ作成時に GitHub 上のパッケージも一緒に `require` しておきたい**

```php
composer init --repository '{"type":"vcs","url":"https://github.com/[YOUR]/[REPO]"}' --require [vendor]/[package]:dev-master
```

--------------------------------------------------------------------------------

#### 複製／フォーク

**▼ 利用可能なリポジトリにある既存のパッケージを複製して自身のパッケージにしたい**（パッケージをフォークしたい）
**▼ フレームワークなどの既存のパッケージを複製して自身のパッケージにしたい**（パッケージをコピーしたい）

```php
$ composer create-project [vendor]/[package]
```

- 参考文献
    - [Composerのcreate-projectが何をやっているのか調べてみた](https://qiita.com/DQNEO/items/74f4bb8fe447e4582a97) @ Qiita

**▼ 既存のパッケージを複製して自身のパッケージにする際にディレクトリ名を指定したい**
**▼ 既存パッケージをフォークする際にディレクトリ名を変えたい**

```php
$ compose create-project [vendor]/[project] [target-directory]
```

--------------------------------------------------------------------------------

#### アーカイブ／バックアップ

**▼ 依存ファイル含め、自身のパッケージをまるごと zip/tar アーカイブしたい**
**▼ 依存ファイル含め、指定したパッケージをまるごとアーカイブ／バックアップしたい**

```php:ZIP
$ composer archive [vendor]/[package] [version] --format=zip
```
```php:TAR
$ composer archive [vendor]/[package] [version] --format=tar
```

--------------------------------------------------------------------------------

#### パッケージのインストール

:::note 
🐒 &nbsp; この項目は <font color="darkorange">**`composer.json` に記載済みのパッケージのインストール**</font>です。

`composer.json` にパッケージを追加、もしくはパッケージのインストール後に新たなパッケージを追加したい場合は<strong>「[追加](#%E8%BF%BD%E5%8A%A0)」セクションをご覧ください</strong>。

また、**インストール済みのパッケージを確認したい**場合は「[確認・チェック](#%E7%A2%BA%E8%AA%8D%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF)」セクションをご覧ください。
:::

**▼ `composer.json` に記載されたパッケージや依存を、現在のプロジェクト（パッケージ）にインストールしたい**

```php
$ composer install
```

**▼ PHP ベースのコマンドラインツールをどこからでも使えるようにインストールしたい**
**▼ パッケージをグローバル・インストールしたい**

```php
composer global require "[vendor]/[package]=[version]"
```
```php:PHP-CSをグローバルにインストールしたい場合
composer global require "squizlabs/php_codesniffer=*"
```

- この場合、予め `~/.composer/vendor/bin` にパスを通しておく（環境変数 `PATH` にパスを追加しておく）必要があります。

**▼ `composer.json` に記載されたパッケージや依存を、現在のプロジェクト（パッケージ）にインストールする前にインストールの挙動を確認したい**
**▼ パッケージのインストールの事前確認をしたい**

```php
$ composer install --dry-run
```

**▼ `composer.json` に記載されたパッケージや依存をインストールする際に PHP のバージョン依存確認を一時的に無効にしたい**
**▼ パッケージのインストール時に PHP のバージョンを無視させたい**

```php
$ composer install --ignore-platform-reqs
```

- パッケージ自身が PHP のバージョンを確認している場合、インストールできても動作しない場合があります。

**▼ `composer.json` の「別名ファイル」からパッケージをインストールしたい**
**▼ `composer.json` 以外の JSON ファイルに記載されたパッケージをインストールしたい**

```php:composer-other.jsonの例（環境変数）
$ export COMPOSER=composer-other.json
$ composer install
```
```php:composer-other.jsonの例（グローバル変数）
$ COMPOSER=composer-other.json composer install
```

- `COMPOSER` 環境変数/グローバル変数に指定できるのはファイル名だけで**パスの指定はできません**。無効なファイル名として、デフォルトの `composer.json` が使われます。

**▼ 依存パッケージのインストールを `vendor` とは違うディレクトリにインストールしたい**
**▼ 依存パッケージのインストール先を `vendor` ディレクトリとは別名のベンダ・ディレクトリにしたい**
**▼ ベンダーのディレクトリ名を `vendor` とは違うディレクトリ名にしたい**
**▼ composer ライブラリのインストール先を変更したい**

```php:暫定設定（hogeにディレクトリを１回のみ設定）
$ COMPOSER_VENDOR_DIR=hoge composer install
```
```php:固定設定（hogeにディレクトリを固定設定する例）
$ composer config vendor-dir hoge
$
$ # 以下の要素が composer.json に追加されます
$ # "config": {
$ #     "vendor-dir": "hoge"
$ # }
```

**▼ 依存パッケージのベンダー・バイナリを `bin` とは違うディレクトリにインストールしたい**

```php:ディレクトリがfugaの例
$ COMPOSER_BIN_DIR=fuga composer install
```

**▼ 依存パッケージのインストール時にプロクシを通してインストールしたい**

```php
$ http_proxy=[URL Proxy] composer install
```

**▼ おすすめの人気パッケージをインストールしたい**
**▼ `composer` のパッケージを探したい**

1. [Packagist の人気パッケージ一覧](https://packagist.org/explore/popular)から探す
2. インストールする

--------------------------------------------------------------------------------

#### 更新（アップデート／バージョンアップ＆ダウン）

**▼ `composer.json` に記載されているパッケージや依存をすべて最新にしたい**
**▼ インストール済みのパッケージや依存をアップデート/更新したい**

```php
$ composer update
```

**▼ `composer.json` に記載されているパッケージや依存を最新にする前に挙動を確認したい**
**▼ パッケージをアップデートする際に事前動作の確認をしたい**
**▼ パッケージ・アップデートの事前確認をしたい**

```php
$ composer update --dry-run
```

**▼ `composer.json` に記載された、特定のパッケージとその依存のみを最新にしたい**
**▼ 特定のパッケージをアップデート/更新したい**

```php
$ composer update [vendor]/[package]
```

**▼ `composer.json` に記載された、特定のベンダーのすべてのパッケージとその依存を最新にしたい**

```php
$ composer update [vendor]/*
```

**▼ インストール済みのパッケージで、更新可能なパッケージを知りたい**
**▼ インストール済みのパッケージで、パッケージが古くないかを確認したい**

```php
$ composer outdated
```
```php
$ composer show -lo
```

**▼ インストール済みのパッケージや依存をダウングレードしたい**
**▼ インストール済みのパッケージをバージョンダウンしたい**

ダウン・グレード／バージョン・ダウンしたいバージョンをピンポイント指定します。（`^`などの指定はしない）

```php
$ composer require [vendor]/[package]:1.0.0
```

- 注意：上記は `composer.json` の指定も上書きします。

**▼ `composer` 本体（`composer.phar`）を最新のリリース版にしたい**

```php
$ composer self-update
```

**▼ `composer` 本体（`composer.phar`）を最新の安定バージョンにしたい**

```php
$ composer self-update --stable
```

**▼ `composer` 本体（`composer.phar`）を最新のプレビュー版にしたい**

```php
$ composer self-update --preview
```

**▼ `composer` 本体（`composer.phar`）を指定したバージョンに変更したい**

```php:v1.0.0-alpha7の例
$ composer self-update 1.0.0-alpha7
```

**▼ `composer` 本体（`composer.phar`）を１つ前のバージョンに戻したい**
**▼ `composer` 本体（`composer.phar`）を以前のバージョンに戻したい**

```php
$ composer self-update -r
$ composer self-update --rollback
```

**▼ `composer.json` の「クラスマップの変更」を `autoloader.php` に反映/適用させたい**
**▼ `composer.json` の「名前空間の割り当てマップ」の変更を `autoloader.php` に反映/適用させたい**

```php
$ composer dump-autoload
```

**▼ `composer` の公開鍵を更新したい**（`Dev/Snapshot` と `Tags` の公開鍵）
**▼ `Missing pubkey for dev verification` が出るので公開鍵を更新したい**（`composer diagnose` 時）
**▼ `Missing pubkey for tags verification` が出るので公開鍵を更新したい**（`composer diagnose` 時）

1. [公式の最新の公開鍵](https://composer.github.io/pubkeys.html)を控える
2. 以下のコマンドで登録する

```php
$ composer self-update --update-keys
```

- ページ下部の「トラブル・シューティング」も参照のこと

--------------------------------------------------------------------------------

#### 追加

**▼ `composer.json` にパッケージを追加したい**（from 利用可能なリポジトリ）

```php
$ composer require [vendor]/[package]
```

**▼ `composer.json` にパッケージ開発時にのみ使うパッケージを追加したい**（from 利用可能なリポジトリ）

```php
$ composer require --dev [vendor]/[package]
```

**▼ `composer.json` にパッケージを対話形式で追加したい**

```php
$ composer require
```

**▼ `composer.json` に指定したバージョンのパッケージを追加したい**

```php:v2.1の例
$ composer require [vendor]/[package]:2.1
```

**▼ `composer.json` に指定したメジャー・バージョンの最新パッケージを追加したい**

```php:v1.*の例
$ composer require [vendor]/[package]:1.*
```

**▼ `composer.json` に指定したパッケージのマスターの最新版を追加したい**（リリースの最新ではない）

```php
$ composer require [vendor]/[package]:dev-master
```

**▼ PHP のバージョンに合わせて依存パッケージのバージョンを複数指定しておきたい**

例えば TravisCI で複数 PHP バージョンでテストする際の PHPUnit のバージョンなど。

```php
$ # "||" 区切りで指定する
$ composer require phpunit/phpunit:^5.0||^4.0||^3.0
```

- 左から右に評価され、該当バージョンが適用できない（エラーの）場合に次のバージョンを評価する。
- 参考文献:
  - [in reply to heiglandreas
 by samsonasic](https://twitter.com/samsonasik/status/664897613053857793?ref_src=twsrc%5Etfw%7Ctwcamp%5Etweetembed%7Ctwterm%5E664897613053857793&ref_url=https%3A%2F%2Fandreas.heigl.org%2F2015%2F11%2F12%2Ftesting-code-with-phpunit-on-travis-ci-for-php-5-5-and-php7%2F) @ twitter
  - [Testing code with phpunit on travis-ci for PHP 5.5 and PHP7](https://andreas.heigl.org/2015/11/12/testing-code-with-phpunit-on-travis-ci-for-php-5-5-and-php7/) @ andreas.heigl.org
  - [PHPUnitとPHPのバージョン対応表](https://blog.shimabox.net/2016/09/15/phpunit-php-support-version/) @ Shimabox Blog
  - [composerのバージョン指定方法 ~(チルダ) ^(キャレット) *(アスタリスク)の違いが分かる](https://qiita.com/ritukiii/items/7bb73fd8e383fb350a1d) @ Qiita

**▼ `composer.json` に GitHub の自分のリポジトリを追加（登録）したい**

```php
$ composer config repositories.github.com vcs https://github.com/[YOUR]/[REPO]
```
```php
$ composer config repositories.github.com '{"type": "vcs", "url": "https://github.com/[YOUR]/[REPO]", "//url": "https://github.com/[YOUR]/[REPO].git"}'
```

**▼ `composer.json` に GitHub 上のパッケージを追加したい**

1. GitHub を検索対象リポジトリに追加する
2. `$ composer require [vendor]/[package]:dev-master` を実行する

**▼ `composer.json` の `config` キーに要素を追加したい**

```php:「bin-dir」キーに「bin/」を追加する例
$ composer config bin-dir bin/
```

> <sup>🐒 &nbsp; 上記を実行すると、`composer.json` に以下の要素が追加されます。なお、**追加できるキーは composer が認識できるもの**に限ります。</sup>
>
> ```json
>    "config": {
>        "bin-dir": "bin/"
>    }
> ```

--------------------------------------------------------------------------------

#### 削除

**▼ `composer.json` の設定およびインストール済みのパッケージを削除したい**

```php
$ composer remove [vendor]/[package]
```

**▼ 複数パッケージを一気に削除したい**
**▼ 削除するパッケージを複数指定したい**

```php
$ composer remove [vendor]/[package1] [vendor]/[package2]
```

**▼ `composer` のキャッシュ・ディレクトリを空にしたい**（キャッシュをクリアしたい）

```php
$ composer clear-cache
```

--------------------------------------------------------------------------------

#### 設定・修正

**▼ `composer.json` の設定内容を変更したい**

`config`, `repositories` のキーのみ、コマンドで変更できます。

```php
$ composer config [options] [setting-key] [setting-value1] ... [setting-valueN]
```

**▼ `composer.json` の `"config": { "bin-dir": "bin/" }` の "bin/" を "phar/" に変えたい**
**▼ `composer.json` の `config` 設定を変更したい**
**▼ `composer.json` の `config` キーの値を変更したい**

```php:「config」項目の「bin-dir」設定を「phar/」に変える例
$ composer config bin-dir phar/
```

**▼ 自身のパッケージに登録済みのリポジトリ情報を修正したい**

```php
$ composer config repositories.[ID] vcs https://qithub.com/[foo]/[bar]
```

**▼ リポジトリをミラーサーバに変更したい**
**▼ Packagist のリポジトリを日本のミラーサーバに変更したい**

```php
$ composer config repositories.packagist composer https://packagist.jp
```

**▼ `composer.json` の設定項目を削除したい**

```php
$ composer config --unset [setting-key]
```

**▼ `require` 実行時 `composer.json` の登録パッケージをソートするようにしたい**
**▼ `composer.json` に `"config": { "sort-packages": true }` をコマンドで追加したい**

```php
 $ composer config sort-packages true
```

- 参考文献：
  - [sort-packages](https://getcomposer.org/doc/06-config.md#sort-packages) | config @ Composer公式
  - [このPHPがテンプレートエンジンのくせに慎重すぎる (前篇)](https://qiita.com/tadsan/items/bf61520eb2d455e0e8b4#%E3%83%86%E3%82%B9%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB) @ Qiita
  - [composerのsort-packagesとは？](https://qiita.com/suin/items/46831daef81d9dd877af) @ Qiita

**▼ `composer` 実行時に PHP のバージョンを偽装したい**
**▼ `composer` 実行時の PHP バージョンと違う、任意の PHP バージョンを指定したい**

```php:composerにあたかもPHP5.3.3で動かしているように伝える設定
$ composer config platform.php 5.3.3
```

上記は、各々のパッケージの `composer.json` に記載された `require:{ "php": "<ここにバージョン>" },` に対して効果のある設定です。

しかし、パッケージ独自の実装、つまり**パッケージ自身が内部でプログラム的に PHP のバージョンをチェックしている場合には効果がありません**。例えば [PHPUnit は自身のスクリプト内でバージョンチェックをしている](https://github.com/sebastianbergmann/phpunit/blob/1dc40a56dc5765efaf07a9231617e2e625bc1b35/phpunit#L12-L24)ため実行時にエラーが出ます。


- 参考文献
  - [composerでPHPのバージョンを制限したい](https://qiita.com/kd9951/items/14cddc050745185011ee) @ Qiita
  - [あんまり知られてないけど有用な composer の機能](https://qiita.com/ArimaRyunosuke/items/c706bf314536f1f034ac#configplatform) @ Qiita

**▼ `composer` が途中で強制終了するのを解除したい**
**▼ `composer` のカスタム・ユーザー・コマンドの実行時間制限 300 秒を無効にしたい**
**▼ `composer` が 300 秒で処理を終了してしまうのを解除したい**

```php:プロセスのタイムアウトまでの時間をゼロに設定する
$ composer config process-timeout 0
```
```json:上記コマンドで、composer.jsonに以下の項目が追加されます
{
    "config": {
        "process-timeout": 0
    }
}
```

- ユーザー・コマンドごとにタイムアウトを無効にしたい場合は、「その他」をご覧ください。

--------------------------------------------------------------------------------

#### 確認・チェック

**▼ `composer` 本体のバージョンを確認したい**

```shell-session:--versionオプションでcomposerのバージョン確認する
$ composer --version
Composer version 1.9.3 2020-02-04 12:58:49
```

**▼ `composer` の基本動作を確認したい**（`Hello World` パッケージをインストールして確認する）

```php:パッケージの初期化
# rivsen/hello-world を依存パッケージとして指定
composer init --quiet --name sample/hello-world --require rivsen/hello-world:dev-master
composer install
```
```php:メインのPHPスクリプトの中身
<?php
require_once "vendor/autoload.php";

$hello = new Rivsen\Demo\Hello();
echo $hello->hello(), PHP_EOL;

```

- [Hello World パッケージ](https://packagist.org/packages/rivsen/hello-world) @ packagist

<details><summary>Hello World の確認例</summary><div><br>

```shell-session
$ # 検証バージョン
$ composer --version
Composer version 1.9.0 2019-08-02 20:55:32

$ # 作業ディレクトリの作成と移動
$ mkdir hello-world && cd $_

$ # composer の動作確認
$ composer diagnose
...

$ # パッケージの初期化
$ composer init --quiet --name sample/hello-world --require rivsen/hello-world:dev-master

$ # 依存パッケージのインストール
$ composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing rivsen/hello-world (dev-master 82d892b): Cloning 82d892b200 from cache
Writing lock file
Generating autoload files

$ # ディレクトリ構造の確認
$ tree
.
├── composer.json
├── composer.lock
└── vendor
    ├── autoload.php
    ├── composer
    │   ├── ClassLoader.php
    │   ├── LICENSE
    │   ├── autoload_classmap.php
    │   ├── autoload_namespaces.php
    │   ├── autoload_psr4.php
    │   ├── autoload_real.php
    │   ├── autoload_static.php
    │   └── installed.json
    └── rivsen
        └── hello-world
            ├── composer.json
            ├── readme.md
            ├── src
            │   └── Hello.php
            └── test.php

5 directories, 15 files

$ # プログラムのファイルを作成
$ touch hello-world.php

$ # プログラムを記載（好きなエディタで。以下は vim ）
$ vi hello-world.php
...

$ # プログラムの内容
$ cat hello-world.php
<?php
require_once "vendor/autoload.php";

$hello = new Rivsen\Demo\Hello();
echo $hello->hello(), PHP_EOL;

$ # プログラムの実行
$ php hello-world.php
Hello World!

```

---

</div></details>

**▼ `composer` 本体が正常に動作しているか診断を行い結果を確認したい**
**▼ `composer` 本体の動作に問題がないか確認したい**

```php
$ compose diagnose
```

**▼ 自身のパッケージの診断を行い結果を確認したい**
**▼ 自身のパッケージの構文チェックをしたい**
**▼ 自身のパッケージの `composer.json` に不備がないか確認したい**
**▼ `composer.json` の文法や構文に問題がないか確認したい**

```php
$ composer validate
```

**▼ `composer` のヘルプを確認したい**

```php
$ composer help
```

**▼ インストール済みのパッケージ一覧を確認したい**

```php
$ composer show
```

**▼ `composer` でインストール済みのパッケージ情報を確認したい**

```php
$ composer show -i
$ composer show --installed
```

```php:グローバール・インストール
$ composer global show -i
$ composer global show --installed
```

**▼ `composer` の特定のコマンドのヘルプを確認したい**

```php
$ composer help [command]
```

**▼ `composer.json` の設定内容を一覧で確認したい**

```php
$ composer config --list
```

**▼ `composer.json` が利用環境で使えるか確認したい**
**▼ `composer.json` の依存パッケージが現在の環境で使えるか確認したい**
**▼ `composer.json` の必要要件を満たしているか確認したい**

```php
$ composer check-platform-reqs
```

**▼ インストール済みのパッケージをベンダーで絞りたい**
**▼ 特定のベンダーのパッケージがインストール済みか確認したい**

```php
$ composer show [vendor]/*
```

**▼ 指定したインストール済みのパッケージの詳細を確認したい**

```php
$ composer show [vendor]/[package]
```

**▼ インストール済みのパッケージでアップデートがあるか確認したい**

```php
$ composer outdated
```
```php
$ composer show -lo
```

**▼ 自身のパッケージのホームページもしくはリポジトリのサイトを表示して確認したい**

```php
$ composer home
```
```php
$ composer browse
```

**▼ すでにインストール済みのパッケージから、追加インストールのオススメを確認したい**
**▼ 必須ではないものの、インストール済みのパッケージが推奨する追加パッケージを確認したい**

```php
$ composer suggests
```

**▼ すでにインストール済みのパッケージの依存関係を確認したい**

```php
$ composer depends [vendor]/[package]
```
```php
$ composer why [vendor]/[package]
```

**▼ すでにインストール済みのパッケージがどのパッケージの依存関係でインストールされたか知りたい**
**▼ なぜそのパッケージがインストールされているのか確認したい**
**▼ どのパッケージが特定のパッケージをインストールしたかを知りたい**

```php
$ composer why [vendor]/[package]
```

**▼ インストールできなかったパッケージがなぜインストール出来なかったか確認したい**
**▼ パッケージのインストールで失敗した場合の理由を確認したい**

```php
$ composer prohibits [vendor]/[package]
```

**▼ 自身のパッケージおよび依存パッケージ（追加済みパッケージ）で PHP のバージョン・アップに対応できるか確認したい**

```php:PHP8にバージョンアップ可能かの例
$ composer prohibits php:8
```

**▼ 自身のパッケージ内のインストール済みパッケージが変更されていないか（マスターとの差分を）確認したい**

```php
$ composer status
```

**▼ 自身のパッケージおよび依存パッケージのバージョンやライセンスを表示したい**

```php
$ composer licenses
```
```php:json形式で表示
$ composer licenses --format=json
```

**▼ インストール済みのパッケージでベンダーが提供しているバイナリ／スクリプトを確認したい**

```php
$ composer exec
```
```php
$ composer exec --list
```

**▼ `vendor/bin` にあるバイナリ／スクリプトを確認したい**

```php
$ composer exec
```
```php
$ composer exec --list
```

**▼ 自身のパッケージの `composer.json` に記載された実行スクリプトを実行したい**

```php
$ composer run-script [script name] [args]
```

**▼ `vendor/bin` にあるバイナリ／スクリプトを実行して確認したい**

```php
$ composer exec [script name] [args]
```

**▼ `global` でインストールしたパッケージの `bin` ディレクトリの絶対パスを確認したい**

```shell-session
$ composer global config bin-dir --absolute
Changed current directory to /root/.composer
/root/.composer/vendor/bin
```

上記の場合は `/root/.composer/vendor/bin` を環境変数 `PATH` に追加します。`composer` で `phpcs` などを global インストールして、どこからでも `$ phpcs 〜` と実行したい場合などに使います。

--------------------------------------------------------------------------------

#### 検索

**▼ 利用可能なリポジトリ内のパッケージを全文検索したい**
**▼ インストールできるパッケージを検索したい**

```php
$ composer search [package]
```

**▼ 利用可能なリポジトリ内のパッケージ名で検索したい**
**▼ パッケージ検索で、パッケージ名に絞って検索したい**

```php:ロングオプション
$ composer search --only-name [package]
```
```php:ショートオプション
$ composer search -N [package]
```

--------------------------------------------------------------------------------

以下は `composer` のコマンドではないものの、`composer.json` に手書きで追記したり、少しの工夫で便利に使える機能やアイデアです。

--------------------------------------------------------------------------------

### 拡張／プラグイン／ユーザーコマンド／カスタム

> <sup>🐒 &nbsp; `composer` のコマンドを拡張するには、大きく２通りの方法があります。拡張用のパッケージを作成してインストールする方法と、[custom command](https://getcomposer.org/doc/articles/scripts.md#writing-custom-commands) と呼ばれる `composer.json` の `scripts` 要素にコマンド名と実行コマンドを記載する方法です。</sup>

**▼ `composer` プラグインを作りたい**

`composer` のプラグインもパッケージとして開発できます。`composer.json` の `type` 属性を `composer-plugin`、`extra` 属性を `class` に設定し、`composer-plugin-api` に準拠することで開発できます。

- [Setting up and using plugins](https://getcomposer.org/doc/articles/plugins.md) @ `Composer` 公式

**▼ `composer` コマンドを拡張したい**

基本的に拡張コマンド／プラグインもパッケージなので、通常のパッケージと同じ手順で拡張コマンドはインストール可能です。`global` オプションでインストールすると全体で利用可能になり、`global` オプションなしの場合は自身のプロジェクト（パッケージ）内のみで利用可能になります。手軽に拡張したい場合は、下記のユーザー・コマンドをご覧ください。

**▼ `composer test` で諸テストを実行できるテスト用ユーザーコマンドが欲しい**

> `composer` 自体の機能には `test` コマンドはありません。しかし、`composer.json` の `scripts` 要素にコマンドを指定すると、要素のキー名でそれらコマンドを実行できるようになります。

つまり、`test` というカスタム・コマンドを作るということです。[PHPUnit](https://www.google.com/search?q=site:qiita.com+PHPUnit&tbs=qdr:y) などの [Unit テスト](https://ja.wikipedia.org/wiki/%E5%8D%98%E4%BD%93%E3%83%86%E3%82%B9%E3%83%88) や、[PHP CodeSniffer](https://www.google.com/search?q=site:qiita.com+php+codesniffer&tbs=qdr:y) などのコーディング規約の準拠確認など、複数コマンドで自身のパッケージの品質管理をしている場合に利用できます。

例えば、これら確認用コマンド `scripts` 要素にコマンド名 `mytest` をキーにした要素を `composer.json` に記載すると任意のコマンド群を `composer mytest` だけで実行できます。

**注意点**として、自身のパッケージ（`root` パッケージ）内でしか利用できません。

```json:mytestで実行される一連のコマンドの例
    "scripts" :{
        "mytest": [
            "php --version",
            "composer --version",
            "php vendor/squizlabs/php_codesniffer/scripts/phpcs",
            "php vendor/phpunit/phpunit/phpunit"
        ]
    }
```

- 参考資料： [Scripts](https://getcomposer.org/doc/articles/scripts.md) | Documentation @ 公式マニュアル
- あわせて読みたい：「[composer testでQAツールの実行]()」 @ Qiita

--------------------------------------------------------------------------------

### その他／便利なTIPS

**▼ `composer.json` の `scripts` で定義したユーザコマンドの実行時間の 300 秒制限を解除したい**

```json:PHPUnitのテストが300秒以上かかる場合の解除
{
    "scripts": {
        "test": [
            "Composer\\Config::disableProcessTimeout",
            "phpunit"
        ]
    }
}
```

**▼ `composer bech` でベンチマークを取りたい**

[Symfony](https://symfony.com/) の初期メンバーでパフォーマンス改善を担当していた [dantleech](https://github.com/dantleech) 氏が公開した [PHPBench](https://github.com/phpbench/phpbench) を使うと、PHPUnit に近い使い心地で２つ以上のメソッド／関数／アルゴリズム間の速度の違いを測定できます。

<details><summary>詳細を見る</summary><div><br>

```php:パッケージのインストール
composer require phpbench/phpbench @dev --dev
```

- ベンチ・スクリプトの例

```php:./bench/HashSampleBench.php
<?php
/**
 * @BeforeMethods({"init"})
 */
class HashSampleBench
{
    public function init()
    {
        // ダミーデータの作成
        $this->dummy = strval(\mt_rand());
    }

    public function benchHashMd5()
    {
        $val = hash('md5', $this->dummy);
    }

    public function benchHashSha256()
    {
        $val = hash('sha256', $this->dummy);
    }

    public function benchHashSha512()
    {
        $val = hash('sha512', $this->dummy);
    }
}

```

`./bench/HashSampleBench.php` にある各々のメソッドを 100 万回繰り返す `composer.json` の設定例。

- `Composer\\Config::disableProcessTimeout`: Composer の<ruby>実行制限<rt>タイムアウト</rt></ruby>時間（300 秒）を無効にする。
- `--revs=1000000`: ループ回数。各々のメソッドを実行する回数。
- `--iterations=10`: 反復回数。一連のベンチ（`--revs`）を繰り返す回数。
- `--retry-threshold=1`: 許容偏差パーセンテージ/偏差間の許容エラーマージン。反復間の偏差がこの値に収まるまで反復する。
- `--report=compare`: ベンチマーク（ベンチ結果）の速度比較表を出力する。
- `--report=aggregate`: ベンチマークの総合レポート（速度、メモリ使用率など）を出力する。

```json:composer.jsonの"scripts"に"bench"コマンドを追加する
{
    "require-dev": {
        "phpbench/phpbench": "@dev"
    },
    "scripts" :{
        "bench": [
            "Composer\\Config::disableProcessTimeout",
            "./vendor/bin/phpbench run --revs=1000000 --iterations=10 --retry-threshold=1 --report=compare --report=aggregate ./bench/HashSampleBench.php"
        ]
    }
}
```

```shell-session:実行サンプル
$ composer bench
> Composer\Config::disableProcessTimeout
> ./vendor/bin/phpbench run --retry-threshold=1 --revs=1000000 --iterations=10 --report=compare --report=aggregate ./bench/HashSampleBench.php
PhpBench @git_tag@. Running benchmarks.

\HashSampleBench

    benchHashMd5............................R1 I1 [μ Mo]/r: 0.373 0.373 (μs) [μSD μRSD]/r: 0.002μs 0.42%
    benchHashSha256.........................R2 I9 [μ Mo]/r: 0.676 0.675 (μs) [μSD μRSD]/r: 0.003μs 0.49%
    benchHashSha512.........................R1 I0 [μ Mo]/r: 0.860 0.862 (μs) [μSD μRSD]/r: 0.004μs 0.41%

3 subjects, 30 iterations, 3,000,000 revs, 0 rejects, 0 failures, 0 warnings
(best [mean mode] worst) = 0.372 [0.636 0.637] 0.377 (μs)
⅀T: 19.092μs μSD/r 0.003μs μRSD/r: 0.439%

+-----------------+-----------------+-----+---------+-----------------------------------------------------+
| benchmark       | subject         | set | revs    | suite:1343c44d5a2a719c55bde25711d577d5ecbe8468:mean |
+-----------------+-----------------+-----+---------+-----------------------------------------------------+
| HashSampleBench | benchHashMd5    | 0   | 1000000 | 0.373μs                                             |
| HashSampleBench | benchHashSha256 | 0   | 1000000 | 0.676μs                                             |
| HashSampleBench | benchHashSha512 | 0   | 1000000 | 0.860μs                                             |
+-----------------+-----------------+-----+---------+-----------------------------------------------------+

suite: 1343c44d5a2a719c55bde25711d577d5ecbe8468, date: 2020-05-16, stime: 06:22:00
+-----------------+-----------------+-----+---------+-----+----------+---------+---------+---------+---------+---------+--------+-------+
| benchmark       | subject         | set | revs    | its | mem_peak | best    | mean    | mode    | worst   | stdev   | rstdev | diff  |
+-----------------+-----------------+-----+---------+-----+----------+---------+---------+---------+---------+---------+--------+-------+
| HashSampleBench | benchHashMd5    | 0   | 1000000 | 10  | 420,768b | 0.372μs | 0.373μs | 0.373μs | 0.377μs | 0.002μs | 0.42%  | 1.00x |
| HashSampleBench | benchHashSha256 | 0   | 1000000 | 10  | 420,768b | 0.672μs | 0.676μs | 0.675μs | 0.683μs | 0.003μs | 0.49%  | 1.81x |
| HashSampleBench | benchHashSha512 | 0   | 1000000 | 10  | 420,768b | 0.854μs | 0.860μs | 0.862μs | 0.864μs | 0.004μs | 0.41%  | 2.30x |
+-----------------+-----------------+-----+---------+-----+----------+---------+---------+---------+---------+---------+--------+-------+

```

---

</div></details>

**▼ 既存パッケージから新規パッケージを作る際に任意のスクリプトを実行したい**
**▼ 既存パッケージをクローン/フォークされた際に任意のスクリプトが実行されるようにしたい**

`composer create-project` コマンドで自身のパッケージをテンプレート替りに使ってもらう（自身のパッケージから新規パッケージを作る）際に、任意のスクリプトを実行したい場合は、`composer.json` の `scripts` 要素の `post-create-project-cmd` キーにスクリプトのパスを記載します。例えば、`namespace` やクラスファイル名を書き換えるなどに使えます。

```json:create-projectコマンド実行にrename_namespace.phpを実行する例
{
    "scripts": {
        "post-create-project-cmd": [
            "php 'config/rename_namespace.php'"
        ]
    }
}
```

- 参考文献： [Defining scripts](https://getcomposer.org/doc/articles/scripts.md#defining-scripts) | Scripts @ Composer 公式ドキュメント
- あわせて読みたい： [名前空間の設定やテストの作成など](https://qiita.com/piotzkhider/items/5a6a3d897890dd383f66#%E5%90%8D%E5%89%8D%E7%A9%BA%E9%96%93%E3%81%AE%E8%A8%AD%E5%AE%9A%E3%82%84%E3%83%86%E3%82%B9%E3%83%88%E3%81%AE%E4%BD%9C%E6%88%90%E3%81%AA%E3%81%A9) | Composerのcreate-projectは何をしているのか、何が出来るのか @ Qiita

--------------------------------------------------------------------------------

### トラブルシューティング

**▼ `composer` が重い**
**▼ `composer require ...` が遅い**

日本国内からであれば、@Hiraku さんが建ててくださってるミラーサーバを使ってみる。

```bash:グローバルに設定する
composer config -g repositories.packagist composer https://packagist.jp
```

- 参考文献
    - [packagist.orgのミラーサーバを立ててcomposer updateを18倍速くする](https://qiita.com/Hiraku/items/51961aa49f7a2922011d) @ Qiita
    - [composerの遅さをまじめに考える](https://www.slideshare.net/hinakano/composer-phpstudy) | [第98回PHP勉強会](https://phpstudy.doorkeeper.jp/events/37525) @ slideshare
    - [Composerの実行速度を高速化する方法](https://qiita.com/keitakn/items/37f0fac49442b72c403e) @ Qiita

**▼ `composer` で定義できるライセンスの種類が知りたい**
**▼ `composer` の "`license`" 項目の値一覧**

`composer.json` で定義できるライセンス名は [SPDX](https://ja.wikipedia.org/wiki/Software_Package_Data_Exchange) で制定されている `Identifier` のみを認識します。

- [Software Package Data Exchange のライセンス一覧](https://spdx.org/licenses/) @ spdx.org

`license` 項目が未定義の場合は、`composer diagnose` 時に以下のワーニングが表示されます。

```shell-session:license未定義時の表示
$ composer diagnose
Checking composer.json: WARNING
No license specified, it is recommended to do so. For closed-source software you may use "proprietary" as license.
Checking platform settings: OK
...
```

例えば <code>[The Unlicense](https://spdx.org/licenses/Unlicense.html)</code> の場合は、`Unlicense` となります。

```json:composer.json
{
    "license": "Unlicense"
}
```

SPDX で制定されていない `Identifier` を指定した場合は以下のメッセージが出ます。カスタム（独自）ライセンスの場合は `proprietary` を指定します。

```shell-session:license未定義時の表示
$ composer diagnose
Checking composer.json: WARNING
License "The Unlicense" is not a valid SPDX license identifier, see https://spdx.org/licenses/ if you use an open license.
If the software is closed-source, you may use "proprietary" as license.
```

**▼ Docker のコンテナ内で `composer install` や `composer require` すると「`The "http://packagist.org/p/provider-....json" file could not be downloaded: failed to open stream: Address not available `」エラーが出る。ローカルでは正常に動作する。**

Docker コンテナ内の [MTU](https://ja.wikipedia.org/wiki/Maximum_Transmission_Unit) とホストの MTU が合っていない可能性があります。コンテナ起動時に `--network` オプションで `host` をアタッチします。

```bash:エラーが出るパターン
docker run --rm -it -v $(pwd):/app composer:1.4.2 /bin/bash
```

```bash:正常なパターン（ネットワークを設定）
docker run --rm -it --network host -v $(pwd):/app composer:1.4.2 /bin/bash
```

**▼ `composer require ...` すると "`minimum-stability`" が合わないと言われる**
**▼ `... require ... -> found ... but it does not match your minimum-stability` と叱られる**

ルート・パッケージの `composer.json` で設定された安定レベル（`minimum-stability`）の要件と、パッケージが求める安定レベルの要件が合わないことにより、パッケージのバージョンを選択できないことによるエラーです。ルート・パッケージの `composer.json` で "`minimum-stability`" の指定がない場合、安定レベルの要件は "`stable`" として扱われます。

```shell-session:エラー表示
$ composer require ****/****

  [RuntimeException]                                                                                    
  No composer.json present in the current directory, this may be the cause of the following exception. 

  [InvalidArgumentException]                                                                                                                                             
  Could not find a version of package ****/**** matching your minimum-stability (stable). Require it with an explicit version constraint allowing its desired stability.

require [--dev] [--prefer-source] [--prefer-dist] [--fixed] [--no-progress] [--no-suggest] [--no-update] [--no-scripts] [--update-no-dev] [--update-with-dependencies] [--update-with-all-dependencies] [--ignore-platform-reqs] [--prefer-stable] [--prefer-lowest] [--sort-packages] [-o|--optimize-autoloader] [-a|--classmap-authoritative] [--apcu-autoloader] [--] [<packages>]... 
```
```shell-session
$ composer require ****/****
[InvalidArgumentException]                                                                                                                                                                                                                     
  Could not find a matching version of package ****/****. Check the package spelling, your version constraint and that the package is available in a stability which matches your minimum-stability (stable).
```

- 対応策１： パッケージのバージョンを指定する。
    - `composer require ****/****:1.0.0` や `composer require ****/****:dev-master` など、
- 対応策２： `composer.json` の `minimum-stability` をパッケージと同じレベルに設定する。（下記 `composer.json` 参照）
    - 設定可能なレベル: `dev`, `alpha`, `beta`, `RC`, `stable`

```json:composer.jsonに安定レベルの要件を"stable"に設定する例
{
    "minimum-stability": "stable"
}
```

```json:composer.jsonに安定レベルの要件を"dev"に設定する例
{
    "minimum-stability": "dev"
}
```

- グローバルにインストールしたい場合は、ユーザのホームディレクトリ（`~/.composer`）に移動して、`require` して見てください。

**▼ `composer require ...` すると "`Token (hidden)`" を聞かれる**

パッケージのリポジトリからダウンロードする際に SSH 接続によるダウンロードを試みています。プライベート・リポジトリでない場合や Packagist からのダウンロードの場合、おそらく `git` がインストールされていません。

```shell-session
$ composer require ****/****
...
Cloning failed using an ssh key for authentication, enter your GitHub credentials to access private repos
Head to https://github.com/settings/tokens/new?scopes=repo&description=Composer+on+docker-desktop+2020-06-27+1405
to retrieve a token. It will be stored in "/root/.composer/auth.json" for future use by Composer.
Token (hidden): 
```

- 対応策： `git` コマンドなどパッケージ提供先のバージョン管理コマンドをインストールしてください。

**▼ `composer diagnose` すると "Missing pubkey for ... verification" で失敗する。`composer` 自体は動く。**
**▼ `composer self-update` すると `Missing pubkey` エラーが出る。**

```shell-session
$ composer diagnose
Checking composer.json: OK
Checking platform settings: OK
Checking git settings: OK
Checking http connectivity to packagist: OK
Checking https connectivity to packagist: OK
Checking github.com rate limit: OK
Checking disk free space: OK
Checking pubkeys: FAIL                  ⇦ ここ
Missing pubkey for tags verification    ⇦ ここ
Missing pubkey for dev verification     ⇦ ここ
Run composer self-update --update-keys to set them up
Checking composer version: OK
Composer version: 1.10.8
PHP version: 7.4.7
PHP binary path: /usr/local/bin/php
OpenSSL version: OpenSSL 1.1.1d  10 Sep 2019

$ echo $?
1
```

これは `~/.composer/keys.dev.pub` および `~/.composer/keys.tags.pub` の公開鍵が存在しないことによるエラーです。

これらの公開鍵は、タグの検索や依存パッケージの検索からパッケージをダウンロードした際に（`hosts` ファイルの書き換えなどにより）改竄されたサイトからダウンロードされても検知出来るようにするために使われます。

- 切り分け
  1. 実行ユーザーのホームディレクトリにある `.composer` ディレクトリおよび内部のファイルの所有権およびアクセス権を確認する。

- 対応策１: `$HOME/.composer` ディレクトリがない場合
    - `brew` や `apt` などの OS 側のパッケージマネージャーでインストールした場合、`$HOME/.composer` ディレクトリが作成されないことがあるのが原因。
    - 対策: 対策4と同じ
    - インストール・ユーザーと実行ユーザーが異なることにより、`.composer` ディレクトリが作成されなかったため公開鍵がみつからなかったことが原因。
        - 対策: インストール・ユーザーのホームディレクトリにある `.composer` ディレクトリを実行ユーザーのホームにコピーし、所有権とアクセス権を実行ユーザーに変更する。
- 対応策２: `$HOME/.composer` ディレクトリがあるが、所有者が違う
    - インストール・ユーザーと実行ユーザーが異なっていた可能性があるので、実行ユーザーに変更する。
- 対応策３: `$HOME/.composer` ディレクトリもあり、所有者も同じである
    - 以下の手順で正しい公開鍵に更新する。
    - 公開鍵を確認する: https://composer.github.io/pubkeys.html
    - 次のコマンドで `Dev` と `Tags` の公開鍵を登録する: `composer self-update --update-keys`
- 対応策４: `apk` `apt` `brew` と言った他のパッケージマネージャーからインストールした場合
    - 以下のサイトから、`Dev / Snapshot Public Key` にある内容を `keys.dev.pub`、`Tags Public Key` にある内容を `keys.tags.pub` として、ホームディレクトリにある `~/.composer/` 下に設置する必要があります。
        - https://composer.github.io/pubkeys.html
            - https://composer.github.io/snapshots.pub を `~/.composer/keys.dev.pub` に保存
            - https://composer.github.io/releases.pub を `~/.composer/keys.tags.pub` に保存

---

## Composer のオススメ Qiita 記事一覧

- `Composer` `PHP` タグの Qiita 記事
  - [参照順](https://www.google.com/search?q=site%3Aqiita.com+tag%3Acomposer+tag%3Aphp) @ Google
  - [ここ１年で作成/更新のあった人気記事](https://www.google.com/search?q=site:qiita.com+tag%3Acomposer+tag%3Aphp&tbs=qdr:y) @ Google
  - [いいね順](https://qiita.com/search?q=tag%3Acomposer+tag%3Aphp&sort=like) @ Qiita
  - [ストック順](https://qiita.com/search?q=tag%3Acomposer+tag%3Aphp&sort=stock) @ Qiita
  - [新着順](https://qiita.com/search?q=tag%3Acomposer+tag%3Aphp&sort=created) @ Qiita

--------------------------------------------------------------------------------

## Composer の基礎知識

<h3>Composer とは</h3>

PHP における Composer とは **PHP ライブラリのパッケージ・マネージャーのこと**です。[Docker](https://www.google.com/search?q=site:qiita.com+Docker%E3%81%A8%E3%81%AF&tbs=qdr:y) の [compose](https://en.wikipedia.org/wiki/Docker_(software)#Tools) とは似て非なる別のアプリです。

`composer` 自身も PHP で書かれており、`composer.phar` という [phar](https://www.php.net/manual/ja/intro.phar.php) 形式で[アーカイブ](https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%BC%E3%82%AB%E3%82%A4%E3%83%96_(%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF))された「単体 PHP ファイル」として提供されています。

実態は PHP スクリプトであるため、PHP コードを `$ php my_script.php` と実行するのと同じように、コマンド・ラインから `$ php ./composer.phar` とファイルを指定して実行できます。

この時の `$ php ./composer.phar` の `php` を[インタプリタ](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%97%E3%83%AA%E3%82%BF)（`interpreter`）と言います。

「[interpret](https://eow.alc.co.jp/search?q=interpret)」とは「通訳する」「解釈する」「読み取る」といった意味があります。スクリプト言語においては、スクリプトを解釈して実行してくれるプログラムのことを `interpreter` と呼びます。

スクリプト実行時に走らせることから「インタプリタ」を「ランタイム」とも呼んだりもします。PHP の場合は、プリ・コンパイル型言語（スクリプトを中間言語にコンパイルしてから実行する）ため、`php` プログラムは「インタプリタ」であり「ランタイム」でもあります。

`composer.phar` は OS の[シバン](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%90%E3%83%B3_(Unix))に対応しているため `$ ./composer.phar` のように PHP ランタイム（[インタプリタ](https://ja.wikipedia.org/wiki/%E3%82%A4%E3%83%B3%E3%82%BF%E3%83%97%E3%83%AA%E3%82%BF)）を指定せずに実行できます。そのため、通常はパスの通ったディレクトリに `composer` と拡張子を付けずにリネームして設置し、`composer` コマンドとして利用します。

```bash:phpランタイム・インタプリタ経由で実行（確実）
$ php ./composer.phar --help
```

```bash:shebang経由で実行
$ ./composer.phar --help
```

```bash:コマンドとして実行（推奨）
$ composer --help

$ # 設置先の例（macOS）
$ which composer
/usr/local/bin/composer
```

:::note info
ポイント: `composer` も PHP で書かれたプログラム
:::


### パッケージ・マネージャーとは

[パッケージ・マネージャー](https://ja.wikipedia.org/wiki/%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)とは**パッケージの「ダウンロード」「更新」「削除」「共有」「利用」を手助けしてくれるツール**です。一般的にコマンドで実行して利用します。

パッケージとは、自身もしくは他者が開発したプロジェクト／ライブラリ／ツール／プログラム／etc. を**セットとして提供できるように１つに<ruby>まとめた<rt>・・・・</rt></ruby>もの**です。パッケージマネージャーは、それらパッケージの「管理を補佐するためのツール」です。

例えば、Python における `pip`、Anaconda における `conda`、Ruby における `gem`、Node.js における `npm` や `yarn`、Debian における `apt`、CentOS における `yum`、Alpine における `apk`、Mac/Linux における `brew`、Windows における `choco` や `winget` などのように、PHP にもパッケージを管理するコマンド・ツールがあります。

従来からある [PECL](https://ja.wikipedia.org/wiki/PECL) と [PEAR](https://ja.wikipedia.org/wiki/PEAR) に加えて、本記事の `composer` です。他にも、依存ファイルも含めて [Phar](https://www.php.net/manual/ja/intro.phar.php) で固めた（アーカイブされた）パッケージを管理する [Phive](https://phar.io/) もあります。

`PEAR` は永らく PHP の主要なパッケージマネージャーとして君臨していました。しかし `PEAR` は「[お役御免](https://qiita.com/rana_kualu/items/cda171324e98124c8d23)」となり、**現在は `composer` が主要なパッケージマネージャーである**と言えます。

特に `composer` の v1 系では `pear` の代替コマンドがあったのですが、新しい [`composer` の v2 からは `pear` も使えなくなりました](https://github.com/composer/composer/blob/2.0.0/UPGRADE-2.0.md?#:~:text=PEAR%20support)。最近の書籍でも `PEAR` でのインストールを案内するものがありますが、同じパッケージが提供されているなら `composer` でインストールすることをお勧めします。

対して `PECL` は（まだ？）現役です。なぜならコンパイル済みのバイナリ、つまり PHP の `Extension`（拡張機能）を扱うことが出来るからです。

PHP の `composer` の場合は、位置付け的に Python の `pip` や Node.js の `npm` が一番近いかもしれません。対して PHP の `PECL` は、Python の `Anaconda` との関係に近いと思います。Mac ユーザーであれば `composer` と `PECL` の関係は `brew` と `brew cask` の関係みたいなものと言えばピンと来るでしょうか。

と言うのも、PHP の `composer` や Python の `pip` は基本的に自身のプログラム言語で書かれたパッケージを管理するのに対し、PHP の `PECL` や Python の `Anaconda` は、それ以外にも C 言語と言ったコンパイル型言語で書かれた外部モジュール（言語を拡張する機能）も取り扱え、必要であればソースコードからコンパイルを行うこともできます。

しかし、PHP も PHP 7.4 から [FFI](https://ja.wikipedia.org/wiki/Foreign_function_interface) と言う「多言語で書かれたライブラリを使う仕様・機能」が使えたり、PHP 8 からは [JIT](https://ja.wikipedia.org/wiki/%E5%AE%9F%E8%A1%8C%E6%99%82%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9) と言う「 実行時にコードのコンパイルを行い実行速度の向上を図る機能」も使えたりと、プリ・コンパイル言語になりつつあるので `PECL` もいずれ消えていく可能性は高いと思われます。

<h3>パッケージ・マネージャーの目的</h3>

<strong>パッケージ・マネージャーの主な目的は「[車輪の再発明](https://ja.wikipedia.org/wiki/%E8%BB%8A%E8%BC%AA%E3%81%AE%E5%86%8D%E7%99%BA%E6%98%8E)防止」</strong>です。

つまり、既存のパッケージを再利用することで [DRY の原則](https://ja.wikipedia.org/wiki/Don%27t_repeat_yourself)を支援するツールでもあります。

車輪を再発明して大車輪を作る場合を除き、既存のパッケージを利用することで工数削減が期待できます。また、公開してシェアすることで多数の目を通すことになるため、改善やセキュリティ対策などのメンテナンスの気付きを得られるという目的もあります。

:::note info
とは言え、「車輪を作れない人」よりは「作ったことがあるので苦労がわかる人」向けとも言えます。なんちゃってでも車輪を作ったことがある・なしで、トラブル発生時に何が問題を起こしているか見えるため、切り分けが大きく変わるからです。
:::

<h3>パッケージ・マネージャーの特徴</h3>

パッケージ・マネージャーの<strong>基本となる特徴として「依存関係の管理」</strong>があります。

つまり、「パッケージ A を使うためには、パッケージ B のバージョン X が必要だが、パッケージ B はパッケージ C のバージョン Y が必要」といった場合に、必要なメインのパッケージ A を宣言するだけで、芋づる式に必要な（関係する）他のパッケージも管理してくれます。

<h3>パッケージの管理</h3>

`composer` のパッケージの管理は、基本情報を記載した **`composer.json` ファイルと `composer` コマンドで管理します**。

`composer` コマンドは `composer.json` を参照して処理を行います。そのため、`composer.json` ファイルと同じ階層、もしくはオプションでファイルのパスを指定して `composer` コマンドを実行することで管理します。

一般的に、自身のプロジェクト（プログラム）の[ルート・ディレクトリ](https://ja.wikipedia.org/wiki/%E3%83%AB%E3%83%BC%E3%83%88%E3%83%87%E3%82%A3%E3%83%AC%E3%82%AF%E3%83%88%E3%83%AA)に `composer.json` 設置しますが、`composer` では、そのディレクトリを「`root` パッケージ」と呼びます。

`composer.json` ファイルがプロジェクトにまだない場合は `composer init` で初期化するか、`composer require` で依存パッケージを追加するか、手動で設置します。

もし、自身のプロジェクトで特定のパッケージを使うことがわかっている場合は `composer require <パッケージ名>` と実行して `composer.json` に追記 & パッケージのインストールをします。

この時 `composer.json` が存在しない場合は作成してから追記とインストールをしてくれるので、再配布する予定がない場合は `init` より `require` が<ruby>楽<rt>らく</rt></ruby>でしょう。

逆に、すでに記述済みの `composer.json` がある場合、`composer install` で依存するパッケージのインストール（`vendor` ディレクトリにダウンロード）が行えます。

ダウンロードまでの大まかな流れですが、`composer require` もしくは `composer install` が実行されると、`composer.json` に記載されている依存パッケージの各々の `composer.json` をローカル（`~/.composer/cache`）に一旦ダウンロードします。

次に、それらの `compose.json` から依存関係を計算したのち、必要にあわせてパッケージの本体を `vendor/` ディレクトリ下にダウンロードして行きます。

<h3>Composer では自分のプロジェクトもパッケージ</h3>

このように、自身のプロジェクトの**ルート・ディレクトリにある `composer.json` は、自分のプロジェクトの依存関係を記載したファイル**です。

同様に、自身のプロジェクトだけでなく依存するパッケージの**各々のルート・ディレクトリにも `composer.json` が設置されるのが `composer` の特徴**です。

Python でいう `__init__.py` や Golang でいう `go.mod` に近い役割をするものです。

`composer` では、この `composer.json` ファイルがあるディレクトリ以下を「パッケージ」と呼び、１つの単位とします。そして、自分のプロジェクトを「ルート・パッケージ」と呼びます。つまり、これが `composer` において、自分のアプリも「パッケージ」と呼ぶゆえんです。

この仕組みにより、自分のプログラムが他のプログラムからでもパッケージとして気軽に使えます。

また、依存するプログラムも一緒に配布しなくても済むため、**開発用の配布データのサイズが小さくなる**というメリットもあります。特に、ライセンス上の問題で自身のパッケージと一緒に配布できない場合にも効力を発揮します。

<h4>パッケージの種類</h4>

`composer` のパッケージには主に4つの種類（`type`）があり、パッケージの用途によって異なります。

`composer.json` の "`type`" 設定項目（JSON の要素）でパッケージの用途を示すことができ、下記の４種類から選べます。

1. **`library`**（ライブラリ）：<br>デフォルトの設定値。ライブラリ用途で使うパッケージの場合に指定します。**ライブラリとは、使いやすいように１ヶ所に整理してまとめられたもの**で、特定の目的に合わせて選抜された関数やクラスなどまとめたパッケージを指します。他の言語でいう `.dll` や `.so` のような位置付けのパッケージです。
2. **`project`**（プロジェクト）：<br>ライブラリではなく、それ自体がアプリケーションとして動作するパッケージを示します。たとえば、[Symfony SE](https://github.com/symfony/symfony-standard) のようなアプリケーション・シェル、[SilverStripe インストーラー](https://github.com/silverstripe/silverstripe-installer)のような [CMS](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)、またはパッケージとして配布される本格的なアプリケーションなどです。[IDE](https://ja.wikipedia.org/wiki/%E7%B5%B1%E5%90%88%E9%96%8B%E7%99%BA%E7%92%B0%E5%A2%83) によっては、新しいワークスペースを作成するときに、この値を利用して初期化するプロジェクトのリストを提供するものもあります。
3. **`metapackage`**（メタ・パッケージ）：<br>要件のみを定義した空のパッケージの場合に指定します。パッケージ自体はファイルを含まないため、`composer install` で実行してもファイルシステムに何も書き込みませんが、記載されたパッケージのみをインストールします。主に、開発前の定番のパッケージをインストールする用途に使われます。
4. **`composer-plugin`**：<br>`composer` の拡張機能用のパッケージである場合に指定します。`vendor` ディレクトリ以下にインストールしない[カスタム・インストーラー](https://getcomposer.org/doc/articles/custom-installers.md)を実装する必要があります。

上記４つ以外にもユーザー定義の値を指定することができます。その場合 `symfony-bundle` や `wordpress-plugin` などのように、特定のプロジェクト用の固有パッケージであることを意味し、カスタム・インストーラーなどから利用されます。

以上から、通常は `library` として使うことが多く、次点として `project` が多く使われます。

<h3>composer.lock とは</h3>

`composer.lock` とは<strong>「ダウンロードされたパッケージの諸情報」が記載されているファイル</strong>です。別の言い方をすると「動作確認された時のバージョン情報ファイル」です。Golang の場合は `go.sum` に相当するものです。

`composer.lock` は `composer.json` と同じ階層に作成され、`composer` コマンドを実行すると作成・更新されます。

`composer.json` は自身のパッケージの情報、`composer.lock` はダウンロードされたパッケージの情報と覚えるといいでしょう。「自身のパッケージが動作した」と確認が取れた場合、その時点の各々のパッケージのバージョン情報などが記載されるため、**パッケージの動作保証ファイル**とも言えます。

<h3>composer.lock の注意点</h3>

一般的に `composer.lock` はユーザーに提供しません。しかし、**`composer.lock` も `composer.json` と一緒に配布する場合がある**ので注意します。

と言うのも、自身のパッケージや依存するパッケージの各々の `composer.json` ファイルではバージョンが決め打ちされていないことが多くあります。

例えば「バージョン 1.0 以上」の意味である「`^1.0`」などと設定されてる場合です。その場合、**`composer` は依存関係を見ながら可能な範囲で一番最新のバージョンを使おうとします**。（バージョンの詳細は次項）

つまり、「ある時点」もしくは「ある環境」では動いたはずなのに、別のタイミングや環境で動かそうとすると、パッケージの最新バージョンが異なるため動かなくなる場合が出てくるということです。

その可能性がある場合は、`composer.lock` も共有します。

使い方は `composer.json` と `composer.lock` を同階層に設置した状態で `$ composer install` もしくは `$ composer update` します。すると、動作確認の取れたバージョンの依存パッケージがダウンロードされます。

**`composer.lock` を提供する際の注意点**もあります。それは、全てのパッケージのバージョンが `composer.lock` で決め打ちになることです。

つまり、セキュリティ・アップデートなどが適用されないバージョンになる可能性があると言うことです。

そのため、一般公開するパッケージには `composer.lock` は共有しません。

テスト環境から本番環境への移行や Docker のコンテナといった「デプロイ先の環境の均質度が高い」場合、つまり利用する環境が明確な場合や、「動かない」と言った場合などに提供します。

更新を忘れない自信がある場合は `composer.lock.debug` などとリネームして提供してもいいでしょう。

各々のパッケージのバージョンを「決め打ちする」と安定性は増しますが、メンテナンス（バージョンの追随）頻度が高くなります。

逆に、バージョンを「常に最新にする」と、競合する頻度が高くなります。これは依存する複数のパッケージが、とある 1 つのパッケージを参照するも、依存元がアップデートによるパッケージの仕様変更に追随できていない場合などです。

どちらが良い・悪いではなく、運用ポリシーや人件費との問題で、どのパッケージ・マネージャーも持っているジレンマと言えます。

開発手法の1つである「[テスト駆動開発](https://ja.wikipedia.org/wiki/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA)」は、このジレンマを軽減することができます。[ユニット・テスト](https://ja.wikipedia.org/wiki/%E5%8D%98%E4%BD%93%E3%83%86%E3%82%B9%E3%83%88)および [CI](https://ja.wikipedia.org/wiki/%E7%B6%99%E7%B6%9A%E7%9A%84%E3%82%A4%E3%83%B3%E3%83%86%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3) の導入によって、「古いバージョンおよび最新のバージョンでも問題なく動くか」の確認が容易になるからです。

### Composer パッケージのバージョン指定の種類

`composer` のバージョン検知は[セマンティック・バージョニング](https://semver.org/lang/ja/)の記法に準拠しています。

つまり、`1.10.3` のような `X.Y.Z` と3つの区切りで分けられ、各々`<メジャー>.<マイナー>.<パッチ>` と3つのバージョンをドット区切りで示しています。

`1.2` のようなパッチ・バージョンが指定されていない場合は、内部で `1.2.0` もしくは `1.2.x` の最大値といった補完を行います。

そのため、自身のパッケージのバージョンを変更する場合のルールも、セマンティック・バージョニングに準拠する事が推奨されています。

前述したように、`composer` のバージョン指定には大きく「静的指定」と「動的指定」の２種類があります。

静的指定は、いわゆる「バージョンの決め打ち」で、`^` `~` `-` と言った記号を使わないバージョン指定です。`1.2.3` のように指定し、常にそのバージョンが使われるように指定するタイプです。

逆に動的指定は、記号を使うことで使用するバージョンに条件を付ける事ができます。

- バージョン範囲: `>`, `>=`, `<`, `<=`, `!=`, `-`, `~`, `*`, `^`
- `AND` 指定: スペースもしくは `,`
- `OR` 指定: `||`

|記号|概要|指定例|最小バージョン|最大バージョン|
|:--:|:--:|:--:|:--:|:--:|
|`-`|範囲指定|`1.0 - 2.0`|`>=1.0.0`|`<2.1`|
|`-`|〃|`1.0.0 - 2.1.0`|`>=1.0.0`|`<=2.1.0`|
|`.*`|ドット付きワイルドカード|`1.0.*`|`>=1.0.0`|`<1.1`|
|`*`|ワイルドカード<br>（必須だがバージョンは問わない）|`*`|問わない|問わない|
|`~`|最新パッチバージョン|`~1.2`|`>=1.2.0`|`<2.0.0`|
|`~`|〃|`~1.2.0`|`>=1.2.0`|`<1.3.0`|
|`~`|〃|`~1.2.3`|`>=1.2.3`|`<1.3.0`|
|`^`|最新マイナーバージョン|`^1.2.3`|`>=1.2.3`|`<2.0.0`|
|`^`|〃|`^0.3`|`>=0.3.0`|`<0.4.0`|

- [Versions and constraints](https://getcomposer.org/doc/articles/versions.md) @ Composer公式

<h3>パッケージのダウンロード元</h3>

`composer` の場合、**パッケージのダウンロードは指定された[リポジトリ](https://ja.wikipedia.org/wiki/%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA)から行われます**。

デフォルトでは、[`composer` の有志のコミュニティ](https://getcomposer.org/doc/08-community.md)が管理している "[Packagist](https://packagist.org/about)" のリポジトリが検索対象になっています。

この `Packagist` に登録されたパッケージは、リポジトリの追加なく「`vendor`/`package`」（作者名／パッケージ名）を指定するだけで使えるようになっています。Python の `pip` で言うところの [PyPI（Python Package Index）](https://pypi.org/)です。

`Packagist` で公開していないパッケージも**任意の [VCS](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0) リポジトリを検索対象に追加することで利用可能**になります。

例えば [GitHub](https://github.com/)、[GitLab](https://www.gitlab.jp/) や[ローカルで立てた Git サーバ](https://qiita.com/KEINOS/items/a0742e7f4c2195816b38)といったリポジトリ先で公開しているパッケージも、検索対象に追加することで利用できます。macOS の `brew` で言うところの `tap` に近い仕組みです。

また、リポジトリ追加時にログインやパスワードといったアクセス設定をすることで、プライベートなパッケージ、つまり一般非公開なパッケージを利用することもできます。

`Packagist` や `GitHub` などの有料オプションでプライベート・リポジトリを契約して利用したり、ローカル・ネットワーク上の Git サーバーにアクセス権を設けている場合などです。

`composer` が現在対応しているリポジトリの [VCS](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0) の種類は `Git`/`SVN`/`Hg` です。（詳しくは下記「自作パッケージの公開方法」参照）

<h3>パッケージのダウンロード先／インストール先</h3>

インストールした**パッケージの保存先は `global` オプションを「付けた場合」と「付けない場合」で異なります**。

- `global` オプション「あり」 ... 同じユーザーの全プロジェクトで利用可能なパッケージとしてインストール
- `global` オプション「なし」 ... そのプロジェクトでのみ利用可能なパッケージとしてインストール

`global` オプション「あり」でインストールした場合は、現在のユーザーのホーム直下の `~/.composer/vendor/` ディレクトリにインストールされます。

`global` オプション「なし」でインストールした場合は、`composer.json` のあるカレント・ディレクトリ直下の `./vendor/` ディレクトリにインストールされます。

いずれのインストール方法にしても、**パッケージをインストールすると `vendor` ディレクトリ下に保存される**と覚えておいてください。

<h3>ダウンロード／インストールされるパッケージの種類</h3>

`composer` には、パッケージをダウンロード／インストールする際、**２種類のパッケージがあります**。

「プロジェクト本体が使う」パッケージと「プロジェクトの開発に使う」パッケージです。つまり、オーペレーション（`Ops`）用とデベロップメント（`Dev`）用です。

<h4>Ops 星人用パッケージ</h4>

オペレーション（運用／実行）に必要なパッケージとは「プロジェクト本体（自分のアプリ）を動かす際に必要なパッケージ」です。

例えば、作りためていた汎用の俺様クラスや俺様関数があった場合、別のパッケージとしてリポジトリに用意しておき再利用する場合です。

それ以外にも、他の先人方が開発・共有してくださってるパッケージを利用する場合などです。これらのパッケージの力を借りて実装します。

具体例としては、PHP でコマンド・ライン・ツールを作りたい場合、Pure PHP と[制御コード](https://ja.wikipedia.org/wiki/%E5%88%B6%E5%BE%A1%E6%96%87%E5%AD%97#:~:text=%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0%E3%81%A8%E9%9B%BB%E6%B0%97%E9%80%9A%E4%BF%A1,%E3%81%AB%E4%BD%BF%E3%81%86%E6%96%87%E5%AD%97%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82)を駆使してゼロから開発してもいいのですが、スキルと経験がつくなど勉強にはなるものの、時間がかかります。

そこで既存のパッケージの利用を検討します。この場合、老舗の [Web のフレーム・ワーク](https://ja.wikipedia.org/wiki/Web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF)の１つである [Symfony](https://ja.wikipedia.org/wiki/Symfony) が、その機能を[コンポーネント](https://ja.wikipedia.org/wiki/%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88)化して `symfony/console` パッケージとして[提供している](https://symfony.com/components)ので、以下のコマンドでパッケージを導入します。

```php:プログラム本体用に使うパッケージを指定する例
composer require symfony/console
```

<h4>Dev 専パッケージ</h4>

対して、デベロップメント（開発）に必要なパッケージとは「プロジェクト本体（自分のアプリ）を動かす際に**必要のないパッケージだが、入れておくと開発が捗るパッケージ**」です。

例えば、[ユニット・テスト](https://ja.wikipedia.org/wiki/%E5%8D%98%E4%BD%93%E3%83%86%E3%82%B9%E3%83%88)、コーディング規約のチェック、[静的解析](https://ja.wikipedia.org/wiki/%E9%9D%99%E7%9A%84%E3%82%B3%E3%83%BC%E3%83%89%E8%A7%A3%E6%9E%90)、脆弱性のチェックやベンチマークといった**開発やメンテナンスに必要なパッケージ**を指します。

Dev 専用として使いたい場合は `composer require` する際に `--dev` オプションを付けてパッケージを指定します。

例えば自分のプロジェクトにユニット・テストを取り入れたい場合、有名どころでは [PHPUnit](https://phpunit.de/) の `phpunit/phpunit` パッケージがあるので `--dev` を付けて指定します。

```php:プログラム本体の開発に使うパッケージを指定する例
composer require --dev phpunit/phpunit
```

`--dev` オプションをつけると `composer.json` 内の `require-dev` 要素に追加されます。上記の例の場合は、バージョンの指定がないため、`composer` が自動的に現在の PHP バージョンに合わせて必要なバージョンの記載もしてくれます。

<h4>Ops 専用インストール</h4>

実際の利用、つまりエンドユーザー（利用者）には基本的に開発用パッケージは必要ありません。開発のフレームワークによってはサイズが大きいものもあり、空き容量を無駄に消費することになります。

その場合、利用先で `composer install` する際に `--no-dev` オプションを付けることで、`dev` 系のパッケージはインストールされないのでダイエットできます。

```php:プログラム本体に必要なパッケージのみをインストールする
composer install --no-dev
```

<h3>パッケージの実行方法／パッケージの利用方法</h3>

インストールした**パッケージの実行／利用には大きく２種類の方法**があります。「インポートして利用する」か「直接実行する」かです。

「インポートして利用する」場合は、後述する `autoload` の仕組みにより自身のパッケージ内でライブラリとして呼び出して利用します。つまりパッケージを `require` して利用する場合は、一般的に `global` オプション「なし」でインストールします。

「直接実行する」場合は、一般的に `global` オプション「あり」でインストールし、`~/.composer/vendor/bin/` ディレクトリにパスを通して**コマンドとして利用**します。

`bin` ディレクトリとは言っても必ずしもコンパイルされたバイナリデータの置き場所というわけではなく、「単体で実行可能なファイル」を置きます。例えば[シェバン](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%90%E3%83%B3_(Unix))付きの PHP ファイルです。

具体的な例として、コーディングやスタイルの規約に準拠しているか判定する「[PHP CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer)」をインストールすると `vendor/squizlabs` にライブラリが、`vendor/bin/` に `phpcs` コマンドが設置されます。

この `vendor/bin/phpcs` は拡張子のないシェバン付きの単体 PHP ファイルです。標準入力を受け取るように組んであるため、シェルからコマンドとして利用できるようになっています。

試しに適当な空のディレクトリを作成し、そのなかでシェルから `global` オプション「なし」で `composer require squizlabs/php_codesniffer` と実行してインストールしてみてください。ディレクトリ構造を確認してみるとパッケージ作りの参考になると思います。

しかし、**全てのパッケージが `vendor/bin` にコマンドを設置するわけではありません**。

それでも、もしパッケージが `bin` ディレクトリにコマンドを設置するタイプであった場合は、ターミナルから `$ ./vendor/bin/phpcs --version` と、コマンドとして実行できます。

そのため、プログラム内でなく汎用的に使いたいパッケージの場合は「`global` オプションあり」でインストールし `~/.composer/vendor/bin/` にパスを通しておくと `$ phpcs --help` とどこからでも使えるようになります。

もちろん「`global` オプションなし」でインストールし、アプリ内から相対パスで `../../bin/` とディレクトリを参照し、外部コマンドとして実行することも可能です。しかし、イレギュラーな使い方なので、障害対応やデバッグ時の知識の 1 つとして知っているだけで十分です。

パッケージの利用方法は、ライブラリとして利用するのが一般的です。後述する `autoload` の仕組みでインポート、つまり `include` したのと同じように、そのライブラリのクラスや関数が使えるようになるからです。

<h3>自身のパッケージで bin のファイルを提供する</h3>

`composer` は、各々のパッケージの設定で `bin` 設定を見つけると（`composer.json` に `bin` の設定を見つけると）、`./vendor/bin` ディレクトリに各々のシンボリック・リンク（エイリアスを張ったファイル）を作成します。

そのため、自身のパッケージがコマンドなど単体として利用可能なものであった場合、`bin` ディレクトリにメインのプログラムを置いておくとユーザーは使いやすくなります。

設置する方法は主に以下の３通りがあります。

1. [BOX3](https://qiita.com/KEINOS/items/62653805b554a538d970) などのアーカイバーを使って `phar` アーカイブを作成して設置する。
2. メイン・スクリプトを相対パスで参照するスクリプトを設置する。<br>（メイン・スクリプトのシンボリック・リンクを置いても動きますが、OS に依存する可能性があることに留意します）
3. 全てを内包した単体の PHP ファイルを設置する。

いずれの場合も `composer.json` の `bin` 要素にスクリプトのパスを記載しておく必要があります。

```json:composer.json
{
    "bin": ["bin/my-script", "bin/my-other-script"]
}
```

<h3>Composer の特徴とメリット 〜オートローダー〜</h3>

`composer` ならではの特徴とメリットとして「**<code>[autoloading](https://www.php.net/autoload)</code> を標準で備えている**」があります。

これはパッケージの管理だけでなく「ライブラリとしての利用を便利にする機能」で、一言で言うと「クラスや関数を小分けにしているのに `require` や `include` が減らせる」ことです。

ここで言う「ライブラリ」とは、再利用やメンテナンスしやすいように、特定のディレクトリにクラスや関数などを個別のファイルにわけたものです。そして利用時に `require` や `include` などでインポートして利用するものを言います。つまり `composer` でインストールしたパッケージもライブラリの１種なのです。

通常、これら外部ファイルを使う場合は毎回 `require` や `include` しないといけません。しかし、`autoload` の機能を使うと自動的に読み込んでくれるのです。

この仕組みを「オートローダー」と呼び、自分で実装することも可能です。`composer` のありがたみを知るためにも、以下の記事を一読されることをおすすめします。

- [include って書きたくない僕たちのためのオートローディングとComposer](https://qiita.com/tadsan/items/a78c9160418200e2d47a) @ Qiita

<h4>オートローダーの基本</h4>

`composer` のオートローダーを使うには、パッケージをインストールすると自動作成される `vendor/autoload.php` のファイルを `require_once` することで使えます。

つまり、自分のプログラム内で１度だけ `require_once('vendor/autoload.php');` と記述することでパッケージやライブラリが呼び出されます。（もちろん `require` でなく `include` でも動きます）

逆に言えば **`composer` のパッケージを使うには、この記述は必須**とも言えます。

```php:./src/index.php
<?php

require_once("../vendor/autoload.php");
```

さて、`composer` でインストールしたパッケージ以外にも、自作ライブラリ用のディレクトリを作成し `composer.json` にパスを記載しておくと自動読み込みさせることができます。つまり、以降はファイルを増やすたびに `require` や `include` する手間が省けるようになります。

**問題は、このパスを記載するためのコマンドがないこと**です。

そのため、「手動で `composer.json` に記載しないといけない」ので、いささか初心者には敷居が高くなりますが、強力で便利な機能なので知っておいて損はありません。

<h5>オートロードの種類</h5>

自身のパッケージ内に置いた自作ライブラリをオートロードの対象にするには、`composer.json` の `autoload` 要素に「オートロードの種類」と「パス」を記述する必要があります。

「オートロードの種類」には、"`files`"、"`psr-4`"、"`psr-0`" と "`classmap`" の合計4つが指定できます。いずれも `vendor/autoload.php` を読み込むと発動するものです。

1. `files`<br>この項目に記載されているファイルを全て `include` します。
2. `psr-4`<br>PSR-4 に準拠したクラス・ファイルを読み込みます。具体的には、この項目に記載されている名前空間と検索ディレクトリを紐付けて `use` で指定すると `include` されます。（PSR については後述）
3. `psr-0`<br>PSR-0 に準拠したクラス・ファイルを読み込みます。現在は非推奨となっています。具体的には、名前空間とディレクトリを同じにして `use` で指定すると `include` されます。
3. `classmap`<br>指定されたディレクトリにあるファイルを検索して、クラス名とファイルのパスの対応表が作成されます。クラスが利用された際、それが未定義の場合に対応表を参照し `include` される[遅延読み込み](https://ja.wikipedia.org/wiki/%E9%81%85%E5%BB%B6%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%81%BF)型です。主に PSR-4 もしくは PSR-0 に準拠していないクラス・ファイルを使いたい場合に利用します。

<h5>オートロードの書き方</h5>

いくつか例を上げますが、以下の記事もご覧ください。

- [Composerのautoloadの書き方早見表](https://qiita.com/suin/items/b31e3c5bff15c821ccaa) @ Qiita

以下は、「オートロードの種類」に `files` を指定する例です。

```json:composer.json
{
    "autoload": {
        "files": [
            "src/MyConstants.php",
            "src/MyLibrary/Myfunctions.php",
            "lib/network/MyClassess.php"
        ]
    }
}
```

上記は、`vendor/autoload.php` のファイルを１回読み込むだけで、記述されているファイルを全て `include` してメモリに読み込みます。

便利な反面、注意すべき点があります。

1. 全てをメモリに読み込むため速いが、使わなかったとしてもメモリを食う。
2. ソースコードを見ただけでは、これらが読み込まれていることが把握しづらい（確認事項が増える）。
3. ファイルを追加するたび、`composer dump-autoload` コマンドを実行して `vendor/autoload.php` を更新する必要がある。

上記は、プロジェクトが大きくなると開発のボトルネックになりうるため、さらに２種類の方法があります。`use` で宣言して読み込む方法と、クラスが利用された時に宣言されていない場合に検索して読み込む方法です。

いずれもクラスの利用に特化しているので、関数をオートロードしたい場合は、クラス化してメソッドにするか、`files` で読み込む必要があります。

<h5><code>PSR-4</code> のオートロードの例</h5>

PHP には PHP-FIG と言う団体による PSR と言う規格があります。このうち PSR-0 と PSR-4 がオートローダーの規格です。PSR-0 は非推奨となっているので、ここでは `PSR-4` を例にします。

```json:composer.json
{
    "autoload": {
        "psr-4": {
            "MyVendorName\\MyPackageName\\": "src/class/"
        }
    }
}
```

上記設定の場合は、ソースコードに `use MyVendorName\MyPackageName\Hoge;` と記述すると、`src/class/` ディレクトリにある `Hoge.php` を読み込み、そこに記載されている`Hoge` クラスがコード内で使えるようになります。

「え？毎回 `include()` や `require()` するのと変わらないじゃん...」と思うかもしれません。

これに関してはそうです。

しかし、`include()` などの場合はファイルのパスを指定するのに対し、PSR のオートローダーは名前空間から読み込むファイルを指定します。これにより、複数ライブラリがあった場合に、設置先を気にせず、どんなライブラリが使われているかの把握がしやすくなります。

また、中間的なタイプとして、名前空間とディレクトリ構成を同じにした `PSR-0` もあります。しかし、柔軟性に乏しいなどメリットよりデメリットの方が多いことから、現在は非推奨となっています。

- [PHP の PSR-0 と PSR-4 で autoloader の違い](https://qiita.com/KEINOS/items/2924ecde3e4bab0ead7e) @ Qiita
- [「php composer autoload」の Qiita 記事の検索結果](https://www.google.com/search?q=site:qiita.com+php+composer+autoload&tbs=qdr:y) @ Google
- 「[Composer](https://ja.wikipedia.org/wiki/Composer)」 @ Wikipedia

<h3>自作パッケージの公開方法</h3>

自作パッケージの公開には、**主に２種類の方法があります**。`Packagist` で公開するか、それ以外です。

１つは `Packagist` に公開して `composer require` してもらう方法です。もっとも一般的であり、関係者以外にも利用してもらいたいパッケージの場合に利用します。関係者のみ、つまり `Packagist` で非公開利用したい場合は、有償の [Private Packagist](https://packagist.com/) も利用可能です。

もう1つは、GitHub などの [VCS](https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E7%AE%A1%E7%90%86%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0) リポジトリ・サービスや、[ローカルで立てた Git サーバ](https://qiita.com/KEINOS/items/a0742e7f4c2195816b38)などにパッケージを公開する方法です。その場合は、利用者にそのリポジトリを検索先として追加してもらい `require` してもらう必要があります。[非公開のリポジトリの場合はログイン情報なども必要](https://www.google.com/search?q=site:qiita.com+composer+%E9%9D%9E%E5%85%AC%E9%96%8B%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA&tbs=qdr:y)になります。

いずれの方法でも、リポジトリのルートに `composer.json` が設置されており、最低限の項目（`name` `description` の[必須情報](https://getcomposer.org/doc/04-schema.md)）を記載しておく必要があります。

<h4>自作パッケージを Packagist で公開する</h4>

自作パッケージを `Packagist` で公開するには、**`Packagist` にアカウントを作成し、リポジトリの URL を登録します**。

具体的には、`Packagist` にログインして "[[submit]](https://packagist.org/packages/submit)" からパッケージを登録できます。この時、パッケージそのものを指定（アップロード）するのではなく、外部 VCS リポジトリを指定します。対応している VCS は `Git`/`SVN`/`Hg` です。

例えば、GitHub にパッケージを公開し、リポジトリの URL（末尾に`.git` が付いたもの）を `Packagist` の "`submit`" から登録をすると、問題がない場合は `Packagist` でパッケージが公開されます。

> <sup>🐒 &nbsp; **Packagist での公開例：** [GitHub のリポジトリ](https://github.com/KEINOS/parsedown-extension_table-of-contents) と、それを紐づけた [Packagist のリポジトリ](https://packagist.org/packages/keinos/parsedown-toc)</sup>