Composer使ってみる (オートローダー, PHPUnit含む)
自分用のライブラリをComposerパッケージ化するために勉強中
構成
ここでは以下のようにします
- ベンダー名・パッケージ名は
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
になりました。(追加のパッケージは指定しませんでした。)
{
"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.json
に require-dev
が追記されます。
"require-dev": {
"phpunit/phpunit": "^8.4@dev"
}
また、この時点でオートローダーも自動で作成されており、vendor/autoload.php
および vendor/composer/
以下がそうです。プログラム内で verdor/autoload.php
を require
(include
) すれば、PHPUnitほかインストール済みライブラリをオートロードできます。
オートローダー設定追加
最後に、自分のソースコードもオートロードできるように、オートローダーに設定を追加します。
composer.json
に以下を手動で追記します。
"autoload": {
"psr-4": {
"Napoporitataso\\MyApp\\": "src/"
}
}
そしたら以下コマンドを実行し、verdor/
以下に作成されているオートローダーを更新します。
composer dumpautoload
これでプログラム内で verdor/autoload.php
を require
(include
) すれば、インストール済みライブラリだけでなく、Napoporitataso\MyApp
以下もオートロードできるようになりました。
なお、psr-4
というのはPHPのオートロードの仕様名だそうです。ここらへんは以下の記事が参考になりました。
【PHP】PSR-4 Autoloader(オートローダー)
Composerのautoloadの書き方早見表 - Qiita
.gitignore作成
うっかり vendor/
以下をコミットしてしまわないように、.gitignore
も作成します。
/vendor/
以上でセットアップは終わりです。この時点で 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) を食べられそうなだけのプログラムです。
<?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;
}
}
<?php echo '<?php'; ?>
namespace Napoporitataso\MyApp\Feed;
class Worm
{
public function cry()
{
return 'yamete-';
}
}
テストプログラム作成
tests/
以下にテストプログラムを作っていきます。ここでは以下のように用意します。
<?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());
}
}
<?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使ってみた感じです。探してたら以下のようなものもあるみたいなので、もうちょい色々見てみます。