sci

最果て風呂

PHP で Composer と PHPUnit を使ってみる

PHP では自分の好きなものを組み合せてやるのが文化らしく、これといった決定版はないらしいです。ぼんやりとみんががやってるので合わせているみたいな。日本語で調べた範囲では Composer と PHPUnit を使う例が多いので、それにしたがうことにしました。

Composer も PHPUnit も Phar というひとつのパッケージになっているので、ダウンロードして実行ビットを付けるだけで良い。~/bin に入れることにしました。

wget https://getcomposer.org/download/1.6.5/composer.phar
wget https://phar.phpunit.de/phpunit-6.5.phar

雛形の作成

phpmto の中で composer init を実行すると、composer.json が作成されます。Composer でインストールされるライブラリは $HOME/.composer にインストールされるらしいです。

プロジェクトの設定

Composer コマンドに global オプションを付けると composer global config home に設定されている場所にインストールされます。デフォルトでは /Users/home/.composer になっていました。

実行コマンドがある場合にインストールされる場所は composer global config bin-dir --absolute でわかります。デフォルトでは /Users/home/.composer/vendor/bin になっていますが、環境変数 COMPOSER_HOME で変更できます。

つまり、composer requre vender/package だとカレントディレクトリの vendor/ 以下になり、composer global requre vender/package だとホームディレクトリの .composer/vendor 以下にインストールされるというわけです。グローバルの意味がちょっと違う?

ローカルに置いてあるパッケージをインストールすることができるようなので試してみます。提供側は composer.json がコミットされている状態でないといけないようなので入れておきます。

引っぱる側の composer.json に下記だけを記述して composer install を実行。

{
    "require": {
        "user_name/phpmto": "dev-master"
    },
    "repositories": [
        {
            "type": "vcs",
            "url": "/Users/home/phpmto/"
        }
    ]
}

最初に実行した時はネットワークで探すのに時間がかかっているので中断してしまいました。ネットワーク接続を解除 (WiFi を無効に) してから再度実行すると次のようにインストールが完了しました。

> composer install
Loading composer repositories with package information
The "https://packagist.org/packages.json" file could not be downloaded: php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known
failed to open stream: php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known
https://packagist.org could not be fully loaded, package information was loaded from the local cache and may be out of date
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing user_name/phpmto (dev-master e1d229e): Cloning e1d229eeff from cache
Writing lock file
Generating autoload files

composer.lock と vendor/ が作成され、vendor/ 以下に bin/ と user_name/ ができています。/bin/phpmto@ を実行すると動作しました。ライブラリへのパスは大丈夫みたい。

下記のような test.php を作成して実行すると、10 と表示されて使えた!

<?php
include_once "vendor/autoload.php";
use user_name\phpmto\Mto;
$innerdict = Mto::Create_dict("/Users/home/phpmto/tests/sample-jisyo");
echo sizeof($innerdict);

あとは実際に GitHub から composer global install user_name/phpmto としてインストールすることができるかどうかですね。

プロジェクトの実装

namespace を使ったり publick static を付けたくらいで、他は今まで通り。

テストの記述

テストスクリプトの名前は xxxTest.php とするらしいのでそれに倣って MtoTest.php としました。先頭部分に use PHPUnit\Framework\TestCase; を記述すると良いらしい。自作したテストを少し変更するだけで良かった。

phpunit test を実行するとテストができます。

phpunit.xml に bootstrap="tests/bootstrap.php" を追記し、そのファイルに

<?php

require __DIR__ . '/../vendor/autoload.php';

だけを記述しました。この状態で phpunit を実行すると、次のようなエラーになってしまいました。

Non-static method user_name\phpmto\Mto::create_dict() should not be called statically

src/Mto.php の各関数に public static を付けると動くようになりました。テストスクリプトの先頭に記述していた require_once(__DIR__ . "../../src/Mto.php"); が不要に。

これでテストに関するパス設定は解決です。

パッケージの作成

Phar を作るのは面倒っぽいのでスルー。

GitHub からのインストール

gem 等のように直接インストールはできなくて、composer.json を書く必要があるみたい。つまり、$COMPOSER_HOME/composer.json

{
    "require": {
        "user_name/phpmto": "dev-master"
    },
    "repositories": [
        {
            "type": "vcs",
            "url": "https://github.com/user_name/phpmto/"
        }
    ]
}

を記述して composer global require user_name/phpmto:dev-master をするしかないと。