require_onceを使わず、Composerを使う

Posted by Tatsuyano on Tue, Dec 2, 2014
In
Tags php

毎回require_onceを書くのがだるかったので、ローカルのパッケージを自動で読み込む方法を調べてみたら、 PHP5.3以上ならComposerが使えることを知ったので試してみた。

ただ前提として読み込まれる側のソース(パッケージ)は、Gitなど バージョンコントロールシステム(vcs)で管理されている必要がある。

Composer のインストール

まずはComposerのインストールから。 今回はすでにpathの通っている/usr/local/binにインストールする。

$ sudo bash
# cd /usr/local/bin
# curl -sS https://getcomposer.org/installer | php

$ which composer.phar
/usr/local/bin/composer.phar

### ローカルパッケージの構成 読み込まれる(require_onceされる)側の構成は以下のようにした。
composer-test
│
├── composer.json
└── src
    └── Tatsuyano
        ├── ParentClass
        │   └── ChildClass.php
        └── ParentClass.php

まずは作成したパッケージ(composer-test)をかならずgit commitする。
というのも、たとえ読み込む側、読み込まれる側、両方が同じローカル環境内にあっても 読み込む側は、Git 経由でソースを読み込む(インストールする)ので、 commitした内容しか反映されない。

composer.json

{
    "name": "composer-test/tatsuyano",
    "description": "Composerを使ってのファイルのロードテスト",
    "license": "MIT",
    "autoload": {
        "psr-0": {
            "Tatsuyano\\": "src/"
        }
    }
}

#### ParentClass.php
namespace Tatsuyano;

class ParentClass
{
    public static function name()
    {
        return "ParentClass";
    }

    public static function nameOfChild()
    {
        return ParentClass\ChildClass::name();
    }

    public static function child($class_name = 'ChildClass')
    {
        # namespaceを切ったクラスを生成する場合、'\'で区切る必要があるが
        #クラスを動的に生成する場合は、sprintfで指定しないと
        #シンタックスエラーになる
        $class = sprintf("Tatsuyano\ParentClass\%s",$class_name);
        return new $class();
    }
}

あえてuseは使わずに namespace をすべて指定している。 結局useを使いまくるとrequire_onceを使いまくるのと同じになってしまうのと、 動的にクラスを生成したい場合、実装時にクラスを明示(use)できないため。

ChildClass.php

namespace Tatsuyano\ParentClass;

class ChildClass
{
    public static function name()
    {
        return "ChildClass";
    }

    public function say()
    {
        return "hello";
    }
}

### パッケージの読み込み 読み込む側の構成は以下とする。
.
├── composer.json
├── test.php #-> composer-testパッケージを利用する側のソース
└── vendor #-> Composerでパッケージをインストールしたあとに生成される
    ├── autoload.php
    └── composer
    └── composer-test #-> インストールされたパッケージ

パッケージを読み込む(インストール)には

$ composer.pear update

ちなみに、vendorディレクトリ以下にインストールしたソースを直接編集したあとに 再度$ composer.pear updateしても、編集したソースは更新(上書き)されない。

composer.json

repositories/urlディレクティブには、 読み込まれる側のcomposer.jsonが入っているディレクトリを指定する。

{
    "repositories": [
        {
            "type": "vcs",
            "url": "/home/noguchi/src/git/composer-test/"
        }
    ],
    "require": {
        "composer-test/tatsuyano" : "dev-master"
    }
}

また、BitBucket の非公開リポジトリを設定することもできる。
"url": "git@bitbucket.org:tatsuyano/composer-test.git"

test.php(読み込む側のプログラム)

インストールされたパッケージを使うにはinclude_once "vendor/autoload.php"で。
まとめてソースをincludeすることができる。

include_once “vendor/autoload.php”;

use Tatsuyano\ParentClass;

print ParentClass::name() . “\n”; print ParentClass::nameOfChild() . “\n”;

$child = ParentClass::child(); print $child->say() . “\n”;


参考サイト