Help us understand the problem. What is going on with this article?

逆引き!Composer コマンド・ライン一覧(と基礎知識)

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

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

🐒 「LGTM」(旧いいね)が付くたびに何かしら手を加えています。変更通知は送りませんので「ストック」されても変更に気づかれないかもしれません。お手すきに気が向いたら覗きに来てください。また、追加・誤記修正・同じコマンドの別表記など、何かあれば遠慮なく編集リクエスト下さい。ほぼ自動で反映させます。

まえがき

曰く

composer.json の require を直接編集してはいけない」by @tadsan @ Qiita

つまり $ vi composer.jsoncomposer.json を直接エディタで編集するのはバッドノウハウ。専用のコマンドがあるのに、素人にエディタで編集させる記事はバッドメディシン

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

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

🐒 ただ Composer の中の人たちは「JSON なんだから何でも CLI で変更させる必要はないんだ、マイフレンド」というスタンスのようで、autoload などの設定はコマンド・ラインからは追加できません。(´・ω・`)

README.md
  • 本記事は composer.pharcomposer としてパスを通すことを前提としています。
  • パスを通していない場合は $ composer [hoge] の箇所を $ php /path/to/composer.phar [hoge] など、composer.phar の実際の設置先と置き換えて下さい。
  • $ composer$ 付き表記はコマンド・ラインでの入力例です。
  • ユーザー指定の必須項目は [] で囲っています。

    フォーマットと実際の記述例
    $ # composer require [vendor]/[package]
    $ composer require keinos/project_x
    
  • デフォルトの設定として登録する場合は global オプションをつけてください。

    現在のパッケージに適用
    $ # global なし → ./vendor/ 下にインストールされます
    $ composer require keinos/project_x
    $ # global あり → ~/.composer/vendor/ 下にインストールされます
    $ composer global require keinos/project_x
    
  • composer.json のある作成中のアプリ(ライブラリ、プロジェクト、etc)は「自身のパッケージ」と呼んでいます。(Rootパッケージ = 自身のパッケージ)


逆引き一覧

composer 本体のダウンロードとインストール

composer 自体(本体)をダウンロードしたい

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

Download Composer @ Composer 公式

どれ?他に別途必要なものは?

スクリーンショット 2019-12-10 11.15.30.png

上記4行を実行するとcomposer.phar ファイルがカレント・ディレクトリに作成されます。

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

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

🐒 【注意】 たまにcomposer.phar のダウンロードは「curl -sS https://getcomposer.org/installer | php だけでおk」と案内しているブログ記事がありますが推奨されていません
これはクラッキングされた composer 本体を使った場合、インストールされるパッケージ全てが汚染される可能性が高いからです。ハッシュ関数を使って確認している理由が知りたい方は、下記記事の「ハッシュ関数の基本と特徴」をご覧ください。

Composer 自体の依存(Requirements

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

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

ZIP 解凍ツール

composer はパッケージの解凍に zip/unzip を必要とします。Windows の場合は PHP の ZipArchive が使われますが、Linux/macOS の場合は、zlib モジュールに実行権限問題が発生することがあるため unzip コマンドを別途インストールすることが推奨されています。権限の問題で別途必要な場合は、メッセージが表示されます。

バージョン管理ツール

パッケージを zip アーカイブでインストールせず、VCS(バージョン管理システム)のリポジトリからインストールする場合、利用しているリポジトリのパッケージ管理コマンドをインストールします。

composer は以下の VCS に対応しています。特にリポジトリが決まっていない場合は、GitHub や GitLab などの相性を考えて git をインストールすることを個人的(筆者は)オススメします。

  • git svn fossil hg

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

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

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

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

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

$ # 動作確認
$ composer --version

▼ macOS の brewcomposer をインストールしたい

brew install composer

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

シェル・スクリプトの中身
#!/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

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

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

以下は、スクリプトでインストールすると同時に /bin ディレクトリにインストールする例。

シェル・スクリプトの中身
#!/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

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

以下は php:cli-alpine の Docker イメージをベースイメージとして、composer をインストールする 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.json の新規作成・初期化

▼ 新規パッケージ作成(自身のパッケージ作成)用に composer.json ファイルを対話式で作りたい(初期化したい)

$ composer init

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

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

▼ 新規パッケージ作成時に依存パッケージも指定しておきたい(ついでに require もしておきたい)

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

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

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

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

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

$ composer init --require vendor/package1:1.0.0

▼ 新規パッケージ作成時に開発用のパッケージも指定しておきたい(ついでに require-dev もしておきたい)

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

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

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

複製/フォーク

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

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

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

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

アーカイブ/バックアップ

▼ 依存ファイル含め自身のパッケージをまるごと zip/tar アーカイブしたい

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

▼ 依存ファイル含め指定したパッケージをまるごとアーカイブ/バックアップしたい

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

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

🐒 パッケージのインストール後にパッケージを追加したい場合は「追加」セクションをご覧ください。
また、インストール済みのパッケージを確認したい場合は「確認・チェック」セクションをご覧ください。

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

$ composer install

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

$ composer install --dry-run

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

$ composer install --ignore-platform-reqs

composer.json別名ファイルからパッケージをインストールしたい

composer-other.jsonの例
$ COMPOSER=composer-other.json composer install

▼ 依存パッケージのインストールを vendor とは違うディレクトリにインストールしたい

hogeにディレクトリを1回のみ設定
$ COMPOSER_VENDOR_DIR=hoge composer install
hogeにディレクトリを固定設定する例
$ composer config vendor-dir hoge

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

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

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

$ http_proxy=[URL Proxy] composer install

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

  1. Packagist の人気パッケージ一覧から探す
  2. インストールする

更新(アップデート)

composer.json に記載されているパッケージや依存をすべて最新にしたい

$ composer update

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

$ composer update --dry-run

composer.json に記載された特定のパッケージとその依存のみを最新にしたい

$ composer update [vendor]/[package]

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

$ composer update [vendor]/*

▼ インストール済みのパッケージで更新可能なパッケージを知りたい

$ composer outdated
$ composer show -lo

composer 本体(composer.phar)を最新のリリース版にしたい

$ composer self-update

composer 本体(composer.phar)を最新の安定バージョンにしたい

$ composer self-update --stable

composer 本体(composer.phar)を最新のプレビュー版にしたい

$ composer self-update --preview

composer 本体(composer.phar)を指定したバージョンに変更したい

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

composer 本体(composer.phar)を1つ前のバージョンに戻したい

$ composer self-update -r
$ composer self-update --rollback

composer.jsonクラスマップの変更を autoloader.php に反映/適用させる
composer.json名前空間の割り当てマップの変更を autoloader.php に反映/適用させる

$ composer dump-autoload

追加

composer.jsonパッケージを追加したい(from 利用可能なリポジトリ)

$ composer require [vendor]/[package]

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

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

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

$ composer require

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

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

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

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

composer.json指定したパッケージのマスターの最新版を追加したい(リリースの最新ではない)

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

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

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

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

composer.jsonGitHub の自分のリポジトリを追加(登録)したい

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

composer.jsonGitHub 上のパッケージを追加したい

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

composer.jsonconfig キーに要素を追加したい

「bin-dir」キーに「bin/」を追加
$ composer config bin-dir bin/

🐒 上記を実行すると、composer.json に以下の要素が追加されます。なお、追加できるキーは composer が認識できるものに限ります。

   "config": {
       "bin-dir": "bin/"
   }

削除

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

$ composer remove [vendor]/[package]

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

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

composerキャッシュ・ディレクトリを空にしたい(キャッシュをクリアしたい)

$ composer clear-cache

設定・修正

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

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

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

composer.json"config": { "bin-dir": "bin/" } の "bin/" を "phar/" に変えたい場合

$ composer config bin-dir phar/

▼ 自身のパッケージに登録済みのリポジトリ情報を修正する

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

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

$ composer config --unset [setting-key]

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

 $ composer config sort-packages true

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

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

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

しかし、パッケージ独自の実装、つまりパッケージ自身が内部でプログラム的に PHP のバージョンをチェックしている場合には効果がありません。例えば PHPUnit は自身のスクリプト内でバージョンチェックをしているため実行時にエラーが出ます。


確認・チェック

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

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

composer の基本動作を確認したい(Hello World パッケージをインストールして確認する)

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

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

Hello World の確認例

$ # 検証バージョン
$ 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!

composer 本体が正常に動作しているか診断を行い結果を確認する

$ compose diagnose

▼ 自身のパッケージの診断を行い結果を確認する

$ composer validate

composer のヘルプを確認する

$ composer help

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

$ composer show

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

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

composer の特定のコマンドのヘルプを確認する

$ composer help [command]

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

$ composer config --list

composer.json でインストールしたパッケージが利用している環境で使えるか確認したい

$ composer check-platform-reqs

composer.json の必要要件を満たしているか確認したい

$ composer check-platform-reqs

▼ インストール済みのパッケージをベンダーで絞りたい

$ composer show [vendor]/*

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

$ composer show [vendor]/[package]

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

$ composer outdated
$ composer show -lo

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

$ composer home
$ composer browse

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

$ composer suggests

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

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

▼ すでにインストール済みのパッケージがどのパッケージの依存関係でインストールされたか知りたい

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

▼ インストールできなかったパッケージがなぜインストール出来なかったか確認する

$ composer prohibits [vendor]/[package]

▼ 自身のパッケージおよび依存パッケージ(追加済みパッケージ)で PHP のバージョン・アップに対応できるか確認する

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

▼ 自身のパッケージの composer.json に不備がないか確認する
composer.json の文法や構文に問題がないか確認する

$ composer validate

▼ 自身のパッケージ内のインストール済みパッケージが変更されていないか(マスターとの差分を)確認する

$ composer status

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

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

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

$ composer exec
$ composer exec --list

vendor/bin にあるバイナリ/スクリプトを確認する

$ composer exec
$ composer exec --list

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

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

vendor/bin にあるバイナリ/スクリプトを実行して確認する

$ composer exec [script name] [args]

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

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

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


検索

▼ 利用可能なリポジトリ内のパッケージを全文検索する

$ composer search [package]

▼ 利用可能なリポジトリ内のパッケージ名で検索する

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

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


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

🐒 composer のコマンドを拡張するには、大きく2通りの方法があります。拡張用のパッケージを作成してインストールする方法と、custom command と呼ばれる composer.jsonscripts 要素にコマンド名と実行コマンドを記載する方法です。

composer プラグインを作りたい

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

composer コマンドを拡張したい

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

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

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

つまり、test というカスタム・コマンドを作るということです。PHPUnit などの Unit テスト や、PHP CodeSniffer などのコーディング規約の準拠確認など、複数コマンドで自身のパッケージの品質管理をしている場合に利用できます。

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

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

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

その他

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

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

詳細を見る

パッケージのインストール
composer require phpbench/phpbench @dev --dev
  • ベンチ・スクリプトの例
./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 の実行制限タイムアウト時間(300 秒)を無効にする。
  • --revs=1000000: ループ回数。各々のメソッドを実行する回数。
  • --iterations=10: 反復回数。一連のベンチ(--revs)を繰り返す回数。
  • --retry-threshold=1: 許容偏差パーセンテージ/偏差間の許容エラーマージン。反復間の偏差がこの値に収まるまで反復する。
  • --report=compare: ベンチマーク(ベンチ結果)の速度比較表を出力する。
  • --report=aggregate: ベンチマークの総合レポート(速度、メモリ使用率など)を出力する。
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"
        ]
    }
}
実行サンプル
$ 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 |
+-----------------+-----------------+-----+---------+-----+----------+---------+---------+---------+---------+---------+--------+-------+



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

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

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

Composer のオススメ Qiita 記事一覧


Composer の基礎知識

Composer とは

PHP における Composer とは PHP ライブラリのパッケージ・マネージャーのことです。

Dockercompose とは似て非なる別のアプリです。

composer 自身も PHP で書かれており、composer.phar という phar 形式でアーカイブされた単体 PHP ファイルとして提供されています。php ./composer.phar ./composer.phar としても実行できますが、通常はパスの通ったディレクトリに composer と拡張子を付けずにリネームして設置し、コマンドとして利用します。

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

パッケージ・マネージャーとはパッケージの「ダウンロード」「更新」「削除」「共有」「利用」を手助けしてくれるツールです。一般的にコマンドで実行して利用します。

自身もしくは他者が開発したプロジェクト/ライブラリ/ツール/プログラム/etc. を総称して「パッケージ」と呼ぶのですが、その「パッケージの管理を補佐するためのツール」です。

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

従来からある PECLPEAR に加えて、本記事の composer です。他にも、依存ファイルも含めて Phar で固めたパッケージを管理する Phive もあります。PHP の composer の場合は、位置付け的に Python の pip や Node.js の npm が一番近いかもしれません。また、PHP の PECLcomposer の関係は、Python の C 言語ライブラリも扱える Anaconda と Python only の pip の関係に近いと思います。

パッケージ・マネージャーの目的

パッケージ・マネージャーの主な目的は「車輪の再発明防止」です。

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

パッケージ・マネージャーの特徴

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

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

パッケージの管理

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

具体的には、自身の PHP プロジェクト(PHP プログラムのあるルートディレクトリ)に composer.json ファイルを設置し、composer コマンドを実行することで管理できます。composer では、このディレクトリを「root パッケージ」と呼びます。

composer コマンドは composer.json を参照して処理を行います。そのためプロジェクトに対してコマンドを実行するには、この JSON ファイルと同じ階層にいる必要があります。

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

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

この時 composer.json が存在しない場合は作成してから追記してくれるので、再配布する予定がない場合は init より requireらくでしょう。また、すでに記述済みの composer.json がある場合、composer install で依存するパッケージのダウンロードが行えます。

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

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

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

このように、自身のプロジェクトのルート・ディレクトリにある composer.json は、自分のプロジェクトの依存関係を記載したファイルです。このファイルがあるディレクトリ以下を composer では「パッケージ」と呼びます。

つまり、自身のプロジェクト(ルート・パッケージ)だけでなく依存するパッケージの各々のルート・ディレクトリに composer.json が設置されるのが composer の特徴です。これが composer において、自分のアプリも「パッケージ」と呼ぶゆえんです。(厳密にはルート・パッケージ)

この仕組みにより自分のプログラムが他のプログラムからでも気軽に使えます。

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

パッケージの種類

composer.json には "type" というパッケージの用途を示す設定項目(要素)があり、下記の4種類から選べます。

  1. library(ライブラリ):デフォルトの設定値。ライブラリ用途で使うパッケージの場合に指定します。ライブラリとは、使いやすいように1ヶ所に整理してまとめられたもので、特定の目的に合わせて選抜された関数やクラスなどまとめたパッケージを指します。他の言語でいう .dll.so のような位置付けのパッケージです。
  2. project(プロジェクト):ライブラリではなく、それ自体がアプリケーションとして動作するパッケージを示します。たとえば、Symfony SE のようなアプリケーション・シェル、SilverStripe インストーラーのような CMS、またはパッケージとして配布される本格的なアプリケーションなどです。IDEによっては、新しいワークスペースを作成するときに、この値を利用して初期化するプロジェクトのリストを提供するものもあります。
  3. metapackage(メタ・パッケージ):要件のみを定義した空のパッケージの場合に指定します。パッケージ自体はファイルを含まないため、composer install で実行してもファイルシステムに何も書き込みませんが、記載されたパッケージのみをインストールします。主に、開発前の定番のパッケージをインストールする用途に使われます。
  4. composer-plugincomposer の拡張機能用のパッケージである場合に指定します。vendor ディレクトリ以下にインストールしないカスタム・インストーラーを実装する必要があります。

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

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

パッケージのダウンロード元

composer の場合、パッケージのダウンロードは指定されたリポジトリから行われます

デフォルトでは、composer の有志のコミュニティが管理している "Packagist" のリポジトリが検索対象になっており、Packagist に登録されたパッケージはリポジトリの追加なく「vendor/package」(作者名/パッケージ名)を指定するだけで使えるようになっています。Python の pip で言うところの PyPI(Python Package Index)です。

プライベートなパッケージ、つまり Packagist で公開していないパッケージも利用できます。

GitHub やローカルで立てた Git サーバなどのアクセス可能な VCS リポジトリに公開されたパッケージは、その対象リポジトリを追加することで検索対象にすることができます。macOS の brew で言うところの tap みたいな仕組みです。現在対応しているリポジトリの種類は Git/SVN/Hg です。(詳しくは下記「自作パッケージの公開方法」参照)

composer.lock とは

composer.lock とは「ダウンロードされたパッケージの諸情報」が記載されているファイルです。

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

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

composer.lock の注意点

composer.lockcomposer.json と一緒に配布する場合があるので注意します。一般的に、自身のパッケージや依存先のパッケージの各々の composer.json ファイルではバージョンが決め打ちされていないことが多くあります。「バージョン 1.0 以上」の意味である「^1.0」などと設定されています。その場合、composer は依存を見ながら可能な範囲で一番最新のバージョンを使おうとします。

つまり、「ある時点」もしくは「ある環境」では動いたはずなのに、別のタイミングや環境で動かそうとすると、パッケージの最新バージョンが異なるため動かなくなる場合が出てくるということです。その可能性がある場合は、composer.lock も共有します。composer.jsoncomposer.lock を同階層に設置した状態で $ composer install もしくは $ composer update すると、動作確認の取れたバージョンの依存パッケージがダウンロードされます。

composer.lock を提供する際の注意点は、全てのパッケージのバージョンが composer.lock で決め打ちになることです。そのため、セキュリティ・アップデートなどが適用されないバージョンになる可能性もあります。通常、一般公開するパッケージには composer.lock は共有しません。テスト環境から本番環境への移行や Docker のコンテナといった「デプロイ対象の環境の、均質度が高い」場合(利用する環境が明確な場合)や、「動かない」と言った場合などに提供します。更新を忘れない自信がある場合は composer.lock.debug などとリネームして提供してもいいでしょう。

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

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

global オプションあり」でインストールした場合は、現在のユーザーのホーム直下の ~/.composer/vendor/ ディレクトリにインストールされます。「global オプションなし」でインストールした場合は、composer.json のあるカレント・ディレクトリ直下の ./vendor/ ディレクトリにインストールされます。いずれのインストール方法にしても、パッケージをインストールすると vendor ディレクトリ下に保存されると覚えておいてください。

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

composer には、パッケージをダウンロード/インストールする際、2種類のパッケージがあります。プロジェクト本体が使うパッケージと、プロジェクトの開発に使うパッケージです。

開発に使うパッケージは、プロジェクト本体(自分のアプリ)を動かす際には必要のないものです。例えば、ユニット・テスト、コーディング規約のチェック、脆弱性のチェックやベンチマークといった開発やメンテナンスに必要なパッケージを指します。

具体的には composer require する際に composer require --dev--dev オプションが指定されたパッケージが開発用パッケージです。composer.json には require-dev 要素に追加されます。

エンドユーザー(利用者)には基本的に必要のないパッケージなので、プロジェクト本体のみ使いたい場合は composer install --no-dev--no-dev オプションを指定します。

開発・メンテナンスのみに利用するパッケージには --dev を付けると覚えるといいでしょう。ちなみに devdevelop(開発)の略です。

パッケージの実行方法/パッケージの利用方法

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

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

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

例えば、コーディングやスタイルの規約に準拠しているか判定する PHP CodeSniffer をインストールすると vendor/squizlabs にライブラリが、vendor/bin/phpcs コマンドが設置されます。この vendor/bin/phpcs は拡張子のないシェバン付きの単体 PHP ファイルです。標準入力を受け取るように組んであるため、シェルからコマンドとして利用できるようになっています。

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

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

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

もちろん「global オプションなし」でインストールし、アプリ内から相対パスで ../../bin/ とディレクトリを参照し、外部コマンドとして実行することも可能です。また、ライブラリとして対応していれば、後述する autoload の仕組みでインポート、つまり include したのと同じように、そのライブラリのクラスや関数が使えるようになります。

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

composer は、各々のパッケージに bin ディレクトリがを見つけた場合は、ルート・パッケージの bin ディレクトリにエイリアスを貼ったファイルを作成します。

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

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

  1. BOX3 などのアーカイバーを使って phar アーカイブを作成して設置する。
  2. メイン・スクリプトを相対パスで参照するスクリプトを設置する。
    (メイン・スクリプトのシンボリック・リンクを置いても動きますが、OS に依存するためオススメしません)
  3. 全てを内包した PHP ファイルを設置する。

Composer の特徴とメリット

composer ならではの特徴とメリットとして autoload があります

これはパッケージの管理だけでなく「ライブラリとして利用を便利にする機能」です。ここで言うライブラリとは、再利用やメンテナンスしやすいように特定のディレクトリに、クラスや関数などを個別のファイルにわけて置いておき、インポートして利用するものを言います。つまり composer でインストールしたパッケージもライブラリの1種なのです。

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

具体的には、パッケージをインストールすると自動作成される vendor/autoload.phprequire_once することで使えます。つまり、自分のプログラム内で1度だけ require_once('vendor/autoload.php'); と記述することでパッケージやライブラリが呼び出されます。

パッケージ以外にも、自作ライブラリ用のディレクトリを作成し composer.json にパスを記載しておくと自動読み込みされるため、以降はファイルを増やすたびに requireinclude する手間が省けるようになります。問題は、このパスを記載するためのコマンドがなく、手動で composer.json に記載しないといけないため、若干初心者には敷居が高くなります。

自作パッケージの公開方法

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

1つは Packagist に公開して composer require してもらう方法です。もっとも一般的であり、関係者以外にも利用してもらいたいパッケージの場合に利用します。関係者のみ、つまり Packagist で非公開利用したい場合は、有償の Private Packagist も利用可能です。

もう1つは、GitHub などの VCS リポジトリ・サービスや、ローカルで立てた Git サーバなどにパッケージを公開する方法です。その場合は、利用者にそのリポジトリを検索先として追加してもらい require してもらう必要があります。非公開のリポジトリの場合はログイン情報なども必要になります。

いずれの方法でも、リポジトリのルートに composer.json が設置されており、最低限の項目(name description必須情報)を記載しておく必要があります。

自作パッケージを Packagist で公開する

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

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

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

🐒 Packagist での公開例: GitHub のリポジトリ と、それを紐づけた Packagist のリポジトリ

KEINOS
A Japanese made in Mexico with Mexican quality ;-) Who monkey around the jungle of codes.記事の日本語がおかしかったら遠慮なく編集リクください。また、記事に「LGTM」が付くたび、なるべく見直して、何かしら加筆・修正してブラッシュアップしています。更新頻度が高いためストックされても基本的に通知はお送りしません。
https://blog.keinos.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした