コードの再利用に常に付いて回る課題といえば、依存関係の管理。幸い、近年ではほとんどのプログラミング言語がこの問題への対策として、依存関係管理ツールを導入しています。PHPのエコシステムでは、使いやすさと柔軟性、そして広く普及されているという点から、Composerが標準です。

Composerは依存関係の管理を目的としたツールですが、以下のようなタスクにも使用できます。

  • 自動読み込み─外部ライブラリからクラスや関数を自動的に読み込み、コードからすぐにアクセスできるように。
  • コード生成─設定ファイルや頻繁に使用するコードなど、プロジェクトの定型コードを生成し、開発作業を高速化して一貫性を確保。
  • スクリプト作成─内蔵のスクリプトシステムにより、テストの実行やコードベースからのドキュメントの生成など、一般的なタスクを自動化。これにより開発ワークフローが合理化され、手間を省略できる。

この記事では、Composerパッケージを自作して、世界中の開発者が使用できるPHPパッケージのリポジトリ「Packagist」で公開する方法を見ていきます。

Composerの仕組み

まずは、Composerについて理解しておきましょう。Composerは、PHPプロジェクトで使用する依存パッケージの定義が格納されたcomposer.jsonファイルで動作します。一元管理されたリポジトリからパッケージを検索し、 パッケージリポジトリを使って依存関係を自動的にダウンロード、インストールします。

PHPの作業環境にComposerをインストールし、以下の手順で依存パッケージをダウンロード、インストールしていきます。

  1. プロジェクトのルートディレクトリにあるcomposer.jsonファイルで、 プロジェクトに必要な依存関係を定義。このファイルには、必要なライブラリとそのバージョン、 その他の設定や依存ライブラリの情報が格納されています。
  2. 依存関係をインストールするにはinstall、既存の依存関係を更新するにはupdate、新たな依存関係をcomposer.jsonファイルに追加するにはrequireのようなコマンドで、Composerの依存関係を解決。コマンドを実行すると、composer.jsonファイルを読み込んで必要な依存関係を定義し、 パッケージリポジトリを確認し、PHP環境に適した最新バージョンの依存関係を探して、 競合やバージョンの制約がないかどうかを検証します。
  3. Composerがライブラリを含む必要な依存関係をダウンロードし、プロジェクトのvendorディレクトリにインストール。また、インストールされた依存関係の正確なバージョンを記録したcomposer.lockファイルが生成されます。
  4. Composerがインストールされた依存関係からクラスや関数の自動読み込み(autoload)を設定。これにより、各ファイルを自分でインクルードしなくても、プロジェクトでライブラリを簡単に使用できるようになります。

このように、ComposerはPHPプロジェクトにおける依存関係の管理を効率化し、外部ライブラリやフレームワークのインストールや更新、利用を簡単にしてくれます。

Composerパッケージを自作して公開する

手順をご紹介するため、例として摂氏温度(°C)を華氏温度(°F)に変換するシンプルなPHPライブラリ「tempconv」を作成し、Composerパッケージとして公開してみます。

前提条件

このプロジェクトは、以下の条件を前提とします。

  • システムへのPHPとComposerのインストール(本記事執筆時点では、Composerの最新バージョンはv2.6.6。v2であれば問題なく動作するはず)
  • コードをホストするためのリポジトリを作成するGitHubアカウント
  • ライブラリを公開するためのPackagistアカウント

プロジェクトのリポジトリを作成

まずは、プロジェクト用にGitHubリポジトリを作成し、完成したライブラリのコードとファイルをプッシュします。

GitHubにプロジェクトリポジトリを作成
GitHubにプロジェクトリポジトリを作成

今回のプロジェクト名は「tempconv」とします。「Description」フィールドには、アプリケーションの簡単な説明を記入しましょう。「Add a README file」 にチェックを入れ、「Add .gitignore」でComposer テンプレート、「Choose a license」でライセンスを選択します。最後に「Create repository」をクリックして完了です。

リポジトリの複製

続いて、作成したリポジトリをローカルマシンに複製します。なお、このURLはプロジェクト全体を通して実際のURLに置き換えてください。

$ git clone https://github.com/rexfordnyrk/tempconv.git

これで現在の作業ディレクトリにtempconvディレクトリが作成されます。この時点では、README.mdLICENSE.gitignoreファイルのみですが、後ほどパッケージファイルもここに作成します。

PHPライブラリの作成

プロジェクトのディレクトリに「TemperatureConverter.php」という名前でファイルを追加します。

<?php

namespace RexfordnyrkTempconv;

class TemperatureConverter
{
    //呼び出し側は、温度値と単位(摂氏または華氏)を指定する必要がある
    public function convert($temperature, $unit)
    {
        //単位が摂氏か華氏かを確認
        if ($unit === 'C') {
            $fahrenheit = ($temperature * 9 / 5) + 32;
            return $fahrenheit;
        } elseif ($unit === 'F') {
            $celsius = ($temperature - 32) * 5 / 9;
            return $celsius;
        } else {
            //単位が摂氏でも華氏でもない場合はエラーを投げる
            throw new InvalidArgumentException('Invalid unit, only C (Celsius) or F (Fahrenheit) are allowed');
        }
    }
}

このクラスにはconvertメソッドがひとつあり、温度と単位を引数にとり、変換後の温度を返します。また、単位が無効な場合には例外を投げます。

実際のシナリオとしては、コードを修正したり更新したりしても正常に動作するかを確認するため、おそらくユニットテストを書くことになりますが、とりあえずはこれで十分です。

Composerパッケージを作成する

ライブラリのコードが完成したら、Composerパッケージを作成します。ウィザードの指示に従って、パッケージ用のcomposer.jsonファイルを生成しましょう。また、コードをリポジトリにプッシュする前に、パッケージとして整理するためのベストプラクティスにも触れていきます。

composer.jsonパッケージファイルの作成

composer.jsonファイルの内容をプロジェクトディレクトリのルートに書き込むこともできますが、以下のComposerコマンドを使用して生成するのがおすすめです。

$ composer init

このコマンドにより、細かな手順を指示するウィザードが表示されます。パッケージ名、説明、作者情報、ライセンスタイプなどのプロンプトに答えると、パッケージのcomposer.jsonファイルが生成されます。

Composerの公式ドキュメントには、期待値やcomposer.jsonファイルの定義に使用できるその他の機能の概要が記載されています。

composer initを使用して設定を生成
composer initを使用して設定を生成

なお、ウィザードには、Gitから名前やメールアドレスを導き出すなど、質問に対して予測される回答が自動入力されます。必要に応じて自由に変更してください。

このライブラリの機能は他のパッケージに依存していないため、依存関係を指定する質問に対しては「No」を選択してください。

最後に生成されたファイルの内容がプレビュー表示されたら、確認した上で確定してください。

パッケージファイルの整理

ウィザードを完了すると、composer.jsonファイルの他に以下2つのディレクトリが作成されます。

  • ソースコード用のsrc
  • ダウンロードした依存ファイルを格納するvendor

TemperatureConverter.phpファイルをsrcディレクトリに移動します。ライブラリに依存関係がある場合は、composer installを実行してオートロード機能を生成し、パッケージの依存関係をインストールしてください。

GitHubにコードをアップロード

変更と新規ファイルをGitに追加します。

$ git add -A

ローカルリポジトリに加えた変更をコミットし、GitHubのリモートリポジトリにプッシュします。

$ git commit -am "Initial Release" && git push

ライブラリのリリースバージョンを作成

コードをリポジトリに追加したら、バージョン番号を付けてライブラリのリリースを作成します。これによって、他の開発者が安定版や重要な更新を追跡できるようになります。

GitHubのリポジトリに移動し、「About」セクションの下にある「Releases」をクリックします。このページにはまだ何もない状態です。中央にある「Create a new release」をクリックしてください。

GitHubのReleasesページ
GitHubのReleasesページ

タグのバージョンやリリースのタイトルなど、リリースの詳細を入力します。例として、タグのバージョンはこのリリースの一意な識別子「v1.0.0」として、リリースタイトルはリリースに含まれる変更点を表す「Initial release」(初期リリース)とします。

任意で説明文を追加することも可能です。コンパイル済みのバイナリやソースコードアーカイブなどのファイルをアップロードする場合は、「Attach binaries by dropping them here or selecting them」(ここにバイナリをドロップして添付)にファイルをドラッグ&ドロップしてください。

GitHubに初期リリースの詳細を入力
GitHubに初期リリースの詳細を入力

最後に「Publish release」をクリックして作成します。

これでリポジトリの「Releases」ページにプロジェクトが表示されるように。他のユーザーが添付したファイルをダウンロードしたり、リリースノートを閲覧したりすることができるようになります。さらに、リリースにタグを追加していれば、ユーザーがタグを使用してリリースに含まれる正確なコードをチェックすることもできます。

ライブラリを共有する準備は以上で完了です。次に、Packagistでパッケージとして公開してみましょう。

Packagistにログインする

Packagistは、PHPの主要なパッケージリポジトリ。PHPのパッケージを公開したり共有したり、あるいは他の開発者のパッケージを入手して自分のプロジェクトで使用する場です。このサイトでパッケージを公開してみましょう。

Packagistのサイトに移動し、「Sign in」をクリックします。「Log in with GitHub」を選択して、GitHubアカウントでログイン認証を行いましょう。

GitHubでPackagistのアカウント登録を行う
GitHubでPackagistのアカウント登録を行う

Authorize」をクリックして、PackagistにGitHubアカウントへのアクセス権を付与します。

GitHubでPackagistにログイン
GitHubでPackagistにログイン

PackagistにComposerパッケージを投稿する

Packagistでパッケージを公開するには、パッケージとその依存関係を記述したcomposer.jsonファイルを含む GitHubリポジトリを投稿します。まずは、Packagistのサイトで「Submit」をクリック。表示されたページでリポジトリのURLを貼り付けて、「Check」をクリックして検証します。

リポジトリが有効であれば、パッケージ名が検出され、「Check」ボタンが「Submit」に変わります。

Composerパッケージ「rexfordnyrk/tempconv」が検出され公開できるように
Composerパッケージ「rexfordnyrk/tempconv」が検出され公開できるように

Submit」をクリックすると、プロジェクトがセットアップされ、公開されます。

Composerパッケージが正常に公開された状態
Composerパッケージが正常に公開された状態

これで、Packagistでパッケージが公開されました。他の開発者が自由にプロジェクトの依存関係として利用できるようになります。

他のプロジェクトでComposerパッケージを使用する

公開したパッケージを他のプロジェクトで使用するには、依存関係としてcomposer.jsonファイルにパッケージを追加します。ファイルを作成して編集する手もありますが、以下のComposerコマンドを使用すると簡単です。

$ composer require rexfordnyrk/tempconv

composer.jsonファイルが存在していない場合は自動生成され、Packagistからパッケージが検出され自動的に読み込まれます。出力は以下のようになります。

Composerでプロジェクトにライブラリを追加した後のターミナルのスクリーンショット

demo.phpファイルを作成し、ライブラリと連動するデモアプリケーションのコードを記述し、TemperatureConverterクラスを次のように使用します。

<?php
use RexfordnyrkTempconvTemperatureConverter;

require_once './vendor/autoload.php';

$converter =  new TemperatureConverter();

$fahrenheit = $converter->convert(20, 'C');
echo "20°C is equivalent to $fahrenheit °Fn";

$celsius = $converter->convert(68, 'F');
echo "68°F is equivalent to $celsius °Cn";

このコードは、TemperatureConverterクラスを使って摂氏20度、華氏68度の温度を変換し、結果を出力します。インポートされたautoloader.phpファイルは、必要な依存関係を読み込むためにComposerが作成したものです。これにより、必要時にクラスを自動読み込みすることができます。

最後に、ターミナルで以下のコードを実行します。

$ php demo.php

この出力は以下のようになります。

$ php demo.php
20°C is equivalent to 68 °F
68°F is equivalent to 20 °C

まとめ

温度を摂氏(°C)から華氏(°F)、またはその逆に変換するシンプルなPHPライブラリを、他のアプリケーションで再利用可能なオブジェクト指向クラスで作成する手順をご紹介しました。Composer Initコマンドを使用してクラスからパッケージを作成し、ライブラリの基本的なコード構成のベストプラクティスにも触れました。作成したライブラリをPackagistで公開すると、他の開発者がプロジェクトで依存関係として使用できるようになります。

アプリケーションの開発を終えたら、必要になるのがホスティング。Kinstaのウェブアプリケーションホスティングでは、ComposerベースのPHPアプリケーションをものの数分でデプロイすることができます。プロジェクトのGitリポジトリからアプリケーションを追加するだけ。Kinstaの紙システムがComposerファイルを自動検出し、アプリケーションをビルドします。まずはリスクなしで、無料利用枠をお試しください。

Rexford Nyarko

Rexford Nyarko is a solution architect with a background in software and network systems, cloud environments, server administration, and various database technologies. Rexford particularly enjoys explaining technical concepts to non-technical audiences.