頻繁に使っているけど実は基本がわかっていないという人の多いPHPのパッケージ管理ツールcomposer。今回は、composerを使ったパッケージ管理の基礎の基礎について説明を行います。本書の読み終えると自分で作成したPHPプログラム内でcomposerでインストールしたパッケージを使用できるようになります。

composerのもう一つの機能であるオートローダーの理解を深めたい人は下記の文書がおすすめです。

Composerのインストール

Composerでパッケージ管理をするためには、Composerのインストールを行わなければなりません。

インストールは非常に簡単なので、Composerのサイトにアクセスして、ダウンロード方法を確認しましょう。アクセスすると下記のような画面が表示されるので、中ほど右にあるDownloadのリンクをクリックしてください。

composerトップページ画面
composerトップページ画面
ダウンロードの方法は変更されるので、最新版をインストールしたい場合は、Composerサイトに行って、毎回ダウンロード方法を確認して下さい。

composerの理解を深めるために使用するので、composer用のディレクトリを作成し、そのフォルダの内でダウンロードのページに記載されているコマンドを実行してください。ここではMACを使用し、デスクトップにcomposerディレクトリを作成し、その下で作業を行っています。2019/6/29時点でのインストール方法は下記となります。


$php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"

インストールが完了するとコマンドを実行したディレクトリ内にcomposer.pharファイルが作成されます。


$ ls
composer.phar
拡張子pharはphpのarchive(アーカイブ)を表しています

インストールが正常に完了後、php composer.pharを実行してみてください。下記のようにコマンドの使用方法の情報が画面に出力されたら正常にインストールが完了しています。


$ ./composer.phar
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.8.0 2018-12-03 10:31:16

Usage:
  command [options] [arguments]

composer.jsonファイルの作成

新規でcomposer.jsonファイルを作成し以下を記載してください。


{

}

composer.jsonを作成した後、composerのinstallオプションを実行します


$ ./composer.phar install
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Generating autoload files

composer.jsonには、カーリーブレース以外何も記載していませんが、composer.phar installを実行した場所にvendorディレクトリが作成されます。

composerコマンドはcomposer.jsonファイルが存在するディレクトリでしか実行できません。composer.jsonファイルが見つからない場合は、エラーが発生します。

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

composerのインストールが完了したら、パッケージのインストールを行ってみましょう。日付や時刻を操作するのに便利なCarbonをインストールします。

パッケージをインストールする際は、requireオプションを使用します。実行時のログを見るとcarbonのバージョンは2.7で、carbonの他にもpolyfill-mbstringやcontractsといったパッケージも同時にインストールしていることを確認することができます。また、先ほど何も記述していなかったcomposer.jsonも更新されます。更新されたcomposer.jsonにはCarbonの情報が追加されています。

パッケージをインストールする際、composer.jsonの内容に基づき依存関係のチェックを行い、必要なパッケージがあれば追加でインストールを行います。今回は、carbonを明示的に指定してインストールしましたが、それと依存関係にあるpolyfill-mbstring他3つのパッケージも同時にインストールしています。

$ ./composer.phar require nesbot/carbon
Using version ^2.7 for nesbot/carbon
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 4 installs, 0 updates, 0 removals
  - Installing symfony/polyfill-mbstring (v1.10.0): Downloading (100%)         
  - Installing symfony/contracts (v1.0.1): Downloading (100%)         
  - Installing symfony/translation (v4.2.0): Downloading (100%)         
  - Installing nesbot/carbon (2.7.0): Downloading (100%) 

composer.jsonを確認するとインストールしたnesbot/carbonのパッケージが追加されています。


{
    "require": {
        "nesbot/carbon": "^2.7"
    }
}

【パッケージインストールの書式】


$ composer require [vendor_name]/[project_name]

vendor_nameとproject_nameを合わせたものがパッケージ名(package name)です。 project_nameが同じでもvendor_nameが異なれば別のパッケージになります。そのためインストールする場合は、[vendor_name]/[project_name]を指定する必要があります。

インストールしたパッケージを使用する

パッケージのインストールは完了したが、どうやってcarbonを呼び出して使用するのかわからないという人もいるかと思います。手順は簡単でphpファイルを作成(test.php)し、そのファイルに下記のように記述するだけで、Carbonを使用することができます。


<?php

require 'vendor/autoload.php';

use Carbon\Carbon;

echo Carbon::now();
requireでvendor/autoload.phpファイルを読み込まなければ、Carbonは実行できません。Class Carbon\Carbonのnot foundエラーが発生します。composerのもう一つの重要な機能であるオートローダーがここでは重要な役割を果たします。

実行すると時刻が表示されます。


$ php test.php
2018-12-04 10:30:44

追加のパッケージをインストールする

プログラムを作成していくと新しいパッケージを追加したい場合があります。その場合は、Carbonをインストールした時と同様にrequireオプションを実行すれば追加インストール可能です。

Carbonは時刻を操作するパッケージでしたが、今回は、ログを操作するmonologを追加インストールします。


$ ./composer.phar require monolog/monolog
Using version ^1.24 for monolog/monolog
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 2 installs, 0 updates, 0 removals
  - Installing psr/log (1.1.0): Downloading (100%)         
  - Installing monolog/monolog (1.24.0): Downloading (100%) 

インストールが完了するとcomposer.jsonも更新され、2つのパッケージの情報を確認することができます。


{
    "require": {
        "nesbot/carbon": "^2.7",
        "monolog/monolog": "^1.24"
    }
}

インストールしたパッケージCarbonとmonologを使って動作確認してみましょう。下記のプログラムは、現在の時刻をログファイル(your.log)に書き込むといった単純なものです。


<?php

require 'vendor/autoload.php';

use Carbon\Carbon;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$log = new Logger('composer');

$log->pushHandler(new StreamHandler(__DIR__ .'/your.log', Logger::WARNING));

$log->warning(Carbon::now());

実行後、作成したファイルと同じディレクトリにyour.logファイルが作成され、実行時刻が記述されています。


[2018-12-04 07:05:08] composer.WARNING: 2018-12-04 07:05:08 [] []

2つのパッケージをインストールしましたが、composerを利用すれば、簡単に追加したパッケージを使用することができます。

composer.jsonを利用したインストール

ここまでのインストールはすべてcomposerのコマンドラインで行なってきましたが、composer.jsonファイルの中に記述されている内容を元にパッケージのインストールを行うことができます。

下記のように記述されたcomposer.jsonを別の場所に移動します。移動したcomposer.jsonがあるディレクトリでcomposer installを実行するとcomposer.jsonに記述されたパッケージがインストールされます。


{
    "require": {
        "nesbot/carbon": "^2.20",
        "monolog/monolog": "^1.24"
    }
}

composer.lockについて

composer.lockファイルにはcomposerを使ってインストールされた正確なバージョンの情報が記載されています。そのため、別の環境でcomposer.jsonとcomposer.lockを使ってパッケージのインストールを行なった場合は、composer.lockの正確なパッケージの情報を確認するので、全く同じバージョンでパッケージをインストールすることができます。

しかし、composer.jsonだけでインストールすると同じパッケージはインストールされるが、バージョンは異なる場合があります。

理由はcomposer.jsonのバージョン指定が特定のバージョン指定ではなく幅をとって指定ができるためです。

下記のcomposer.jsonではバージョンの前に”^”がついているため、2.20以上で3.00未満のパッケージをインストールする設定になっています。インストールした時に2.2.0だったパッケージを数ヶ月間アップデートしないままでいると2.3.0に更新されている可能があります。更新を行わないで同じcomposer.jsonファイルを使用して別の環境でインストールを行うと最新の2.3.0がインストールされてしまうため、パッケージが同じでもバージョンが異なるという状況が発生します.

composer.lockがあれば2.2.0の情報が登録されているので、別の環境でも2.2.0のインストールを行います。


{
    "require": {
        "nesbot/carbon": "^2.20",
        "monolog/monolog": "^1.24"
    }
}

パッケージを更新する

パッケージの更新方法

パッケージの更新を行いたい場合は、composer updateを実行すると更新を行うことができます。


$composer update

個別のパッケージのみ更新を行いたい場合はupdateの後ろにパッケージ名を指定してください。何も更新がなければ、下記のようなメッセージが表示されます。


$ composer update monolog/monolog
Loading composer repositories with package information
Updating dependencies (including require-dev)
Nothing to install or update
Generating autoload files

更新可能なパケージを確認する

更新可能なパッケージがあるかどうか確認したい場合は、composer outdatedコマンドを実行します。実行後、更新可能パッケージがある場合は下記のようにパッケージの情報が表示されます。更新可能はパッケージが無い場合はコマンドを実行しても何も表示されません。


$ composer outdated
monolog/monolog 1.23.0 1.24.0 Sends your logs to files, sockets, inboxes

インストール済みのパッケージを確認する

インストールされているパッケージを確認したい場合は、composer infoまたはcomposer showを実行すると確認することができます。


$ composer info
monolog/monolog               1.24.0  Sends your logs to files, sockets, in...
nesbot/carbon                 2.20.0  A simple API extension for DateTime.
psr/log                       1.1.0   Common interface for logging libraries
symfony/polyfill-mbstring     v1.11.0 Symfony polyfill for the Mbstring ext...
symfony/translation           v4.2.0  Symfony Translation Component
symfony/translation-contracts v1.1.5  Generic abstractions related to trans...

パッケージを削除する

パッケージを削除する前に現在入っているパッケージとcomposer.jsonの中身をチェックしておきましょう。


$composer show
monolog/monolog           1.24.0  Sends your logs to files, sockets, inboxe...
nesbot/carbon             2.7.0   A simple API extension for DateTime.
psr/log                   1.1.0   Common interface for logging libraries
symfony/contracts         v1.0.1  A set of abstractions extracted out of th...
symfony/polyfill-mbstring v1.10.0 Symfony polyfill for the Mbstring extension
symfony/translation       v4.2.0  Symfony Translation Component

下記がcomposer.jsonの中身です。


{
    "require": {
        "nesbot/carbon": "^2.7",
        "monolog/monolog": "^1.24"
    }
}

パッケージを削除する時はremoveを使用します。monolog/monologの削除を行います。依存性の確認を行い、monologを含め、2つのパッケージが削除されています。

monologをインストールした時は2つのパッケージがインストールされたので、削除の際も2つのパッケージが削除されています。


$composer remove monolog/monolog
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 0 installs, 0 updates, 2 removals
  - Removing psr/log (1.1.0)
  - Removing monolog/monolog (1.24.0)
Writing lock file
Generating autoload files

composer.jsonからもmonologに関する情報が削除されていることが確認できます。


{
    "require": {
        "nesbot/carbon": "^2.7"
    }
}

vendorディレクトリも確認を行いましたが、monolog に関するディレクトリが削除されていることが確認できました。

composerのアップデート

composer自体の更新があった場合は、composer self-updateで更新を行うことができます。現在のバージョンは、compser -Vで確認できます。


$ composer -V
Composer version 1.8.5 2019-04-09 17:46:47

composer self-updateで更新を行います。


$ composer self-update
Updating to version 1.8.6 (stable channel).
   Downloading (100%)         
Use composer self-update --rollback to return to version 1.8.5

実行ログで1.8.6への更新が行われたことがわかります。


$ composer -V
Composer version 1.8.6 2019-06-11 15:03:05

composerコマンドの使用方法の確認

composerの使用法がわからなくなったら、引数にhelpを入力して、実行してください。また各処理に関する情報が知りたい場合は、composer help <コマンド名>を入力して実行してください。


$composer help
$composer help remove

開発環境用と本番環境用にわける

phpunit/phpunitなど開発環境のテストのみで使用するパッケージは–devをつけてインストールすることで通常のインストールとわけることができます。


$ composer require phpunit/phpunit --dev

インストール完了後にcomposer.jsonの中身を確認すると–devをつけずにインストールしたパッケージで分けられて、require-devで追加されていることが確認できます。


{
    "require": {
        "nesbot/carbon": "^2.20",
        "monolog/monolog": "1.23"
    },
    "require-dev": {
        "phpunit/phpunit": "^7.5"
    }
}

本番環境でcomposer.jsonを利用してパッケージをインストールをしたい場合は、–no-devを追加することでrequire-devにあるパッケージはインストールされません。インストール時に–devをつけるかつかないかで本番環境と開発環境をわけることができます。

–devでインストールしたパッケージもcomposer install を実行すればインストールが行われます。インストールをしたくない場合に–no-devをつけてインストールを実行します。

パッケージを探す

インストールしたいパッケージを探したい場合は、pakagistを利用することができます。

packagistトップページ
packagistトップページ

Seach packagesにインストールしたいパッケージ名やパッケージの機能に関するキーワードを入れると検索を行い探すことができます。例えばPHPのテストツールを探しているためtestと入力するとテストツールであるphpunitの情報が表示されます。

【付録:composerのメモリ不足エラー】

運用していく中でcompserコマンドでパッケージを追加インストールしようとした場合にメモリ不足のエラーが表示される場合があります。


PHP Fatal error:  Allowed memory size of 1073741824 bytes exhausted (tried to allocate 72 bytes)
PHP Fatal error:  Allowed memory size of 1073741824 bytes exhausted (tried to allocate 72 bytes)
Check https://getcomposer.org/doc/articles/troubleshooting.md#memory-limit-errors for more info on how to handle out of memory errors.[

その場合は下記のようにmemory_limitを一時的に増やせば回避することができます。


$ php -d memory_limit=2G /usr/local/bin/composer require XXXX/XXXX

まとめ

ここまで読み終えてくれた人はcomposerのパッケージ管理の基礎をしっかりと理解して頂けたかと思います。ぜひ、この知識をより複雑なパッケージ管理が必要なフレームワーク等にも生かしてください。