コンテンツにスキップ

パッケージ管理@PHP

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. パッケージ管理ツールの種類

- composer


02. Composer

セットアップ

▼ インストール

# インストーラーをダウンロードする。
$ php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"

# インストーラーのハッシュ値を確認する。
$ php -r "if (hash_file('sha384', 'composer-setup.php') === '906a84df04cea2aa72f40b5f787e49f22d4c2f19492ac310e8cba5b96ac8b64115ac402c8cd292b8a03482574915d1a8') { 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.json ファイル

▼ autoload

名前空間とパスの対応関係を設定する。

require 関数を使用せずに、クラスの名前空間を use で指定するのみでファイルを読み込めるようになる。

{

    ...

    "autoload": {
        "psr-4": {
            # "<名前空間>": "<パス>",
            "App\\": "app/",
            "Database\\Factories\\Infrastructure\\DTO\\": "database/factories/production",
            "Database\\Seeders\\": "database/seeds/production"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ]
    }

    ...

}

▼ config

Composerのコマンドのオプションのデフォルト値を設定する。

{

    ...

    "config": {
        "preferred-install": "dist",
        "sort-packages": "true",
        "optimize-autoloader": "true"
    }

    ...

}

▼ require

インストールされるパッケージとバージョンを設定する。

パッケージ数が少ないプロジェクトではキャレット表記で積極的にアップグレードし、規模が大きくなるほどチルダ表記で慎重にアップグレードすると良い。

# キャレット表記
# メジャーバージョンはそのままで、マイナーバージョンとパッチバージョンを自動でアップグレードする
{

    ...

    "require": {
        "foo": "^1.1.1",  # >=1.1.1 and <1.2.0
        "bar": "^1.1",    # >=1.1.0 and <1.2.0
        "baz": "^0.0.1"   # >=0.0.1 and <0.0.2
    }

    ...

}
# チルダ表記
# メジャーバージョンとマイナーバージョンはそのままで、パッチバージョンを自動でアップグレードする
{

    ...

    "require": {
        "foo": "~1.1.1",  # >=1.1.1 and <2.0.0
        "bar": "~1.1",    # >=1.1.0 and <2.0.0
        "baz": "~1"       # >=1.1.0 and <2.0.0
    }

    ...

}
# エックス、アスタリスク表記
{

    ...

    "require": {
        "foo": "*",     # どんなバージョンでもOK
        "bar": "1.1.x", # >=1.1.0 and <1.2.0
        "baz": "1.X",   # >=1.0.0 and <2.0.0
        "qux": ""       # "*"と同じことになる = どんなバージョンでもOK
    }

    ...

}
# 固定
{

    ...

    "require": {
        "bar": "1.1.1", # 1.1.1
    }

    ...

}

▼ scripts

コマンドのエイリアスを設定する。

{

    ...

    "scripts": {
        # エイリアス
        "post-autoload-dump": [
            # 実行するコマンド
            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
            "@php artisan package:discover --ansi"
        ],
        "post-root-package-install": [
            "@php -r \"file_exists(".env") || copy(".env.example", ".env");\""
        ],
        "post-create-project-cmd": [
            "@php artisan key:generate --ansi"
        ]
    }

    ...

}

▼ version

Composerのバージョンを設定する。

インストールされているcomposerと齟齬がないようにする。

{
    ...

    "version": "1.10.23"

    ...
}


composer.lock ファイル

プロジェクトで composer install コマンドが実行されたとき、composer.json ファイルでのバージョンの指定方法が『固定』以外であると、コマンドの実行タイミングによって、インストールされるバージョンが変わってしまう。

インストーされるバージョンをチーム内で固定するため、プロジェクトが正しく動作するバージョンのセットを記載した composer.lock ファイルを作成しておく必要がある。

これは、composer update の実行時に作成される。

composer install の実行タイミングに限らず、共通のバージョンのセットをインストールできる。

もし、アプリケーションに実際にインストールされている各パッケージのバージョンを知りたい場合は、composer.json ファイルではなく、composer.lock ファイルを確認すること。


autoload.php ファイル

autoload.php ファイルとは

プロジェクト内の全てのphpファイルを名前空間に対応づけ、require 関数を使用せずに名前空間のみでパッケージを読み込めるようにする。

エントリーポイント (index.php ファイル) あるいは bootstrap.php ファイルで、autoload.php ファイルを読み込むようにすると良い。

<?php
# エントリーポイント

require_once realpath(__DIR__ . "/vendor/autoload.php");
<?php
# autoload.phpファイルの一部

// autoload_classmap.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

# 名前空間とファイルの対応関係
return array(
    'App\\Console\\Kernel' => $baseDir . '/app/Console/Kernel.php',
    'App\\Events\\Event' => $baseDir . '/app/Events/Event.php',
    'App\\Events\\ExampleEvent' => $baseDir . '/app/Events/ExampleEvent.php',

    ...

    'phpDocumentor\\Reflection\\Types\\Void_' => $vendorDir . '/phpdocumentor/type-resolver/src/Types/Void_.php',
    'phpDocumentor\\Reflection\\Utils' => $vendorDir . '/phpdocumentor/reflection-docblock/src/Utils.php',
    'voku\\helper\\ASCII' => $vendorDir . '/voku/portable-ascii/src/voku/helper/ASCII.php',
);

▼ 確認方法

登録済みのphpファイルと名前空間の対応関係は、php コマンドで確認すると良い。

$ php -r '
    $autoloader = require "vendor/autoload.php";
    echo json_encode($autoloader->getPrefixesPsr4(), JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
  '


02-02. composerコマンド

clear-cache

インストール時に作成されたキャッシュを削除する。

$ composer clear-cache


create-project

パッケージがすでに組み込まれたプロジェクトを作成する。

プロジェクトを git clone コマンドを実行することにより、プロジェクト内で composer install コマンドを実行することと同じである。

新しいディレクトリを作成しつつ、プロジェクトのファイルを展開もできるが、カレントディレクトリ配下にそのまま展開したほうが便利である。

補足として、ファイルが1つでもあるディレクトリにはプロジェクトのファイルを展開できないため、一時的に削除しておく。

# カレントディレクトリ配下にプロジェクトを作成する。
$ composer create-project --prefer-dist laravel/lumen .


diagnose

Composerを使用するための準備が揃っているかを検証する。

$ composer diagnose

You are running Composer with SSL/TLS protection disabled.
Checking composer.json: OK
Checking platform settings: OK
Checking git settings: OK
Checking http connectivity to packagist: OK
Checking https connectivity to packagist: OK
...


dump-autoload

事前に設定された autoload プロパティを基に、クラスの名前空間とパスの対応関係を登録する。

$ composer dump-autoload

存在するクラスが見つからないエラーに悩まされたときは、クラスが登録されていない可能性があるため、dump-autoload を実行すると良い。

 Exception : Target class [FooClass] does not exist.

また、autoload プロパティに登録されているパスが誤っていないかも確認したほうが良い。

{"autoload": {"psr-4": {}}}


init

対話形式で composer.json ファイルを作成する。

$ composer init


install

▼ installとは

composer.json ファイルに書き込まれたパッケージを、composer.lock ファイルに書き込まれたバージョンでインストールする。

$ composer install

▼ -vvv

コマンド処理中のログを表示する

$ composer install -vvv

▼ --no-dev

require-devタグ内のパッケージは除いてインストール

$ composer install --no-dev

▼ --prefer-dist

Composerの配布サイトからインストールする。prefer-source オプションを使用するよりも高速でインストールできる。

デフォルトでdistを使用するため、実際は宣言しなくても問題ない。

$ composer install --prefer-dist

▼ --prefer-source

GitHubのComposerリポジトリからインストールする。

Composerの開発者用である。

$ composer install --prefer-source


reinstall

▼ reinstallとは

指定したパッケージをアンインストールした後、再インストールする。

$ composer reinstall <パッケージ名>

再インストールで問題を解決できなければ、全てのパッケージを再インストールすると良い。

composerキャッシュと vendor ディレクトリを削除し、composer install コマンドを実行する。

$ composer clearcache
$ rm -rf vendor
$ composer install -vvv


remove

▼ removeとは

パッケージを composer.json ファイルと composer.lock ファイルの両方から削除する。

$ composer remove <パッケージ名>


require

▼ requireとは

パッケージ名を composer.json ファイルと composer.lock ファイルの両方に書き込み、インストールする。

または、パッケージのアップグレード/ダウングレードする場合、パッケージのバージョンを書き換える。

コマンドを使用せずに自分で実装しても良い。

$ composer require <パッケージ名>:^1.0


scripts

設定された scripts プロパティのスクリプトを実行する。

$ composer <スクリプト名>


update

▼ updateとは

composer.json ファイルに書き込まれたパッケージを最新のバージョンでインストールし、composer.lock ファイルを書き換える。

composer.lock ファイルに全てのパッケージ情報を書き込むため、リポジトリの利用者がインストールするパッケージにも影響を与える。

パッケージ内でエラーが発生したら、composer update コマンドによるパッケージの更新が原因だと考えたほうが良い。

いずれかのパッケージで新バージョンをリリースした。ただし、このリリースは不具合が含まれていた可能性が高い。

# 必要なパッケージをcomposer.jsonファイルに追加した上で実行する。
$ composer update

▼ -vvv

コマンド処理中のログを表示する

$ composer update -vvv


環境変数

COMPOSER_MEMORY_LIMIT

Composerのコマンドの実行時のメモリ上限を設定する。

メモリ上限を無しにして、コマンドを実行できる。

phpバイナリファイルを使用する。

コンテナ内で実行する場合、設定画面からコンテナのCPUやメモリを増設もできる。

$ COMPOSER_MEMORY_LIMIT=-1 composer install --prefer-dist -vvv
$ COMPOSER_MEMORY_LIMIT=-1 composer update -vvv


03. バージョンアップの手順

事前確認の重要性

バージョン更新により、アプリケーションや関連する他のアプリケーションに影響が出る場合もある。

そのため、想定外の影響が起こらないように、マニュアルやリリースノートにて、バージョン間の差異を全て確認しておく必要がある。


バージョン間の互換性を確認

破壊的変更のためにバージョン間で互換性が全くない。旧バージョンと新バージョンで使用方法やオプションが変わる場合もある。

一方で、互換性があるものの、大きな変更がなされている可能性がある。


追加、廃止、非推奨を確認

バージョンアップにより、新機能が追加されている可能性がある。

一方で、今までの方法が廃止または非推奨に移行している可能性がある。


予約語や関数を確認

バージョンアップにより、予約語や関数が変更されている可能性がある。

予約語を自身が使用しているとバッティングしてエラーになってしまう。


アプリケーションの修正作業の考慮

バージョンアップに伴ってコードの修正が必要だとわかった場合、バージョンアップ手順へ修正作業を組み込む必要がある。


メンテナンスページの表示

バージョンアップによりダウンタイムが発生する場合、その間はメンテナンスページを表示する必要がある。

例えば、AWS ALBにはメンテナンスページを表示するための機能がある。

ダウンタイム中にシステムでリクエストを受信しないことで、負荷をかけない目的もある。


更新作業をリハーサル

テスト環境で更新作業をリハーサルし、問題なく完了することを確認する。


アプリケーションのテスト

テスト環境のバージョンアップ後に、アプリケーションを検証する必要がある。


リードレプリカを最初にアップデート


切り戻し作業の考慮

本番環境のバージョンアップ後に想定外の問題が起こることも考慮して、バージョンアップの手順自体に切り戻し作業を組み込む必要がある。