こうこく
作 ▸

Composer使ってみる (オートローダー, PHPUnit含む)

自分用のライブラリをComposerパッケージ化するために勉強中

Composer 1.9.0
もくじ

構成

ここでは以下のようにします

  • ベンダー名・パッケージ名は napoporitataso/myapp とする。
  • ソースコードの名前空間は Napoporitataso\MyApp とする。
  • 本体のソースコードは src/ 以下に置く。
  • テストプログラムは tests/ 以下に置く。
  • オートローダーを使う。
  • テストプログラムはPHPUnitを使う (日本語マニュアル)。
フォルダ構成
├ src/
│  └ (ソースコード)
├ tests/
│  └ (テストプログラム)
├ vendor/
│  ├ (オートローダー)
│  └ (PHPUnit)
├ .gitignore
└ composer.json

セットアップ

composer.json 作成

まずプロジェクト置き場で composer init します。

いろいろ聞かれるので、答えると composer.json が作成されます。詳細は以下のComposer公式マニュアルを読みます。

The composer.json Schema - Composer

  • Minimum Stability ... composer require とかで他のパッケージをインストールする時の挙動。dev を設定すると、何でもインストールできる。stable を設定すると、安定版だけインストールできる。デフォルト値は stable
  • Package Type ... このパッケージを他の人がインストールする時の挙動。library を設定すると、単純に vendor フォルダ以下にコピーされる。普通はこれでよいので他の説明は割愛。デフォルト値も library

ここでは以下のような composer.json になりました。(追加のパッケージは指定しませんでした。)

composer.json
{
    "name": "napoporitataso/myapp",
    "description": "example",
    "type": "library",
    "authors": [
        {
            "name": "napoporitataso",
            "email": "kkfkgn@hoge.piyo"
        }
    ],
    "require": {}
}

PHPUnitインストール

次に、以下コマンドでPHPUnitをインストールします。

コマンド
composer require --dev phpunit/phpunit

すると vendor フォルダが作成され、PHPUnitとその依存ライブラリがインストールされます。また、composer.jsonrequire-dev が追記されます。

composer.jsonに追記される内容
    "require-dev": {
        "phpunit/phpunit": "^8.4@dev"
    }

また、この時点でオートローダーも自動で作成されており、vendor/autoload.php および vendor/composer/ 以下がそうです。プログラム内で verdor/autoload.phprequire (include) すれば、PHPUnitほかインストール済みライブラリをオートロードできます。

オートローダー設定追加

最後に、自分のソースコードもオートロードできるように、オートローダーに設定を追加します。

composer.json に以下を手動で追記します。

composer.jsonに追記する内容
    "autoload": {
        "psr-4": {
            "Napoporitataso\\MyApp\\": "src/"
        }
    }

そしたら以下コマンドを実行し、verdor/ 以下に作成されているオートローダーを更新します。

コマンド
composer dumpautoload

これでプログラム内で verdor/autoload.phprequire (include) すれば、インストール済みライブラリだけでなく、Napoporitataso\MyApp 以下もオートロードできるようになりました。

なお、psr-4 というのはPHPのオートロードの仕様名だそうです。ここらへんは以下の記事が参考になりました。

【PHP】PSR-4 Autoloader(オートローダー)

Composerのautoloadの書き方早見表 - Qiita

.gitignore作成

うっかり vendor/ 以下をコミットしてしまわないように、.gitignore も作成します。

.gitignore
/vendor/

以上でセットアップは終わりです。この時点で composer.json は以下の通りになっています。

composer.json
{
    "name": "napoporitataso/myapp",
    "description": "example",
    "type": "library",
    "authors": [
        {
            "name": "napoporitataso",
            "email": "kkfkgn@hoge.piyo"
        }
    ],
    "require": {},
    "require-dev": {
        "phpunit/phpunit": "^8.4@dev"
    },
    "autoload": {
        "psr-4": {
            "Napoporitataso\\MyApp\\": "src/"
        }
    }
}

段階を踏まなくても、最初からこのファイルを置いて composer install するだけで同じ環境を作ることは可能です。その場合、composer update してPHPUnitを最新版に更新した方がいいかも。

本体プログラム作成

src/ 以下に本体のプログラムを作っていきます。ここでは以下のように用意します。ひよこ (Chick) が虫 (Worm) を食べられそうなだけのプログラムです。

src/Chick.php
<?php echo '<?php'; ?>


namespace Napoporitataso\MyApp;

use Napoporitataso\MyApp\Feed\Worm;

class Chick
{
	private $eatCount = 0;
	
	public function eat(Worm $worm)
	{
		$this->eatCount++;
	}
	
	public function getEatCount()
	{
		return $this->eatCount;
	}
}
src/Feed/Worm.php
<?php echo '<?php'; ?>


namespace Napoporitataso\MyApp\Feed;

class Worm
{
	public function cry()
	{
		return 'yamete-';
	}
}

テストプログラム作成

tests/ 以下にテストプログラムを作っていきます。ここでは以下のように用意します。

tests/ChickTest.php
<?php echo '<?php'; ?>


use PHPUnit\Framework\TestCase;
use Napoporitataso\MyApp\Chick;
use Napoporitataso\MyApp\Feed\Worm;

class ChickTest extends TestCase
{
    public function test_eat()
    {
        $chick = new Chick();
        
        $chick->eat(new Worm());
        $this->assertSame(1, $chick->getEatCount());
        
        $chick->eat(new Worm());
        $this->assertSame(2, $chick->getEatCount());
    }
}
tests/Feed/WormTest.php
<?php echo '<?php'; ?>


use PHPUnit\Framework\TestCase;
use Napoporitataso\MyApp\Feed\Worm;

class WormTest extends TestCase
{
    public function test_cry()
    {
        $worm = new Worm();
        $this->assertSame('yamete-', $worm->cry());
    }
}

ここまでで構成は以下のようになっています。

フォルダ構成
├ src/
│  ├ Feed/
│  │  └ Worm.php
│  └ Chick.php
├ tests/
│  ├ Feed/
│  │  └ WormTest.php
│  └ ChickTest.php
├ vendor/
│  ├ (オートローダー)
│  └ (PHPUnit)
├ .gitignore
└ composer.json

テスト実行

以下コマンドでテストプログラムを起動します。対象をフォルダで指定してるので、フォルダ内の *Test.php* ファイルを、PHPUnitが全て実行してくれます。

コマンド
.\vendor\bin\phpunit .\tests

ところで、ここまでオートローダーを読み込むコードを一切書いてないのですが、どうも phpunit コマンドを実行した際、PHPUnit自身が自分でオートローダーを require してるようです。なのでPHPUnitからプログラムを実行する限りなら、テストプログラム内でオートローダーを require しなくてもちゃんと動くみたいです。

(少しググった感じだと bootstrap でオートローダーを読み込んでるコードが多かったのですが、古いバージョンではそうする必要があったのか?)

実行すると、以下のように問題なく終了しました。

PHPUnit 8.4-g51359f5 by Sebastian Bergmann and contributors.

..                                                                  2 / 2 (100%)

Time: 412 ms, Memory: 4.00 MB

OK (2 tests, 3 assertions)

以上

以上、とりあえずComposer使ってみた感じです。探してたら以下のようなものもあるみたいなので、もうちょい色々見てみます。

GitHub - php-pds/skeleton: Standard PHP package skeleton.

この記事に何かあればこちらまで (非公開)