PHP
Composer

PHP開発でComposerを使わないなんてありえない!基礎編

More than 1 year has passed since last update.

久方ぶりにPHPのレガシーなシステムを触りましたが、なんというか。。。
名前空間とcomposerが無いだけで、こうも大変になるのかと思いましたね

というわけで、もはやデファクトスタンダードとなったcomposerを使用した開発について、その有り難みを噛み締めつつ、まとめていきたいと思います

composer

composerは依存性管理ツール

composerは依存性管理ツールです。。。ってナンノコッチャですが、例えば以下の状況を考えてみましょう

便利そうなライブラリAを使用したいのだが、このライブラリは更に別のライブラリB, Cを必要としている。さらに、ライブラリBはライブラリD, Eを。。。

そう、ライブラリの依存性地獄です。
使用したいのはAなのに、そのために必要なライブラリがボコボコ必要になる
こんなのは日常茶飯事です。

でもcomposerがあればどうでしょう。
ライブラリAが欲しいなぁ、と思ったらその場で

composer require A

と打てば、Aと同時に必要なライブラリ群を参照して一緒にダウンロードしてくれるのです
もちろん、composerに対応できているライブラリでなければなりませんが、それで必要なライブラリがない、ってことにはならないと思います

composerの利点

リポジトリを汚さない

私はリポジトリに自分もしくはプロジェクトメンバー以外が書いたコードが紛れ込むのが好きではありません。自分たちの成果でもないものをリポジトリに成果としてあげることに抵抗感を覚えるのです。
しかし、composerでライブラリを管理する限り、このような心配はなくなります
composerでインストールしたライブラリ群は一括でvendorというディレクトリに放り込まれているので、このディレクトリだけignoreしてしまえばいいのです
ライブラリの依存性は別途作成されているcomposer.jsonに記載されるのみとなり、大量のライブラリでリポジトリが汚れることがなくなります

composer.lockで共有も高速

他のメンバーがcomposerで管理されたライブラリを落とすには、composer.jsonを共有すればよいです。
composer.jsonがあるディレクトリ上でcomposer installとするだけで、依存しているライブラリを持ってきてくれます。

ここで、composerの挙動は、各ライブラリを見に行ってはそのライブラリの依存性を確かめ、依存ライブラリについて同様に依存性を確かめに行く、を繰り返すため、処理が遅い場合が多々有ります。
しかし、実はcomposerでライブラリをインストールするとき、同時にcomposer.lockというファイルが生成されていることに気づくでしょう。
このcomposer.lockはcomposer.jsonにあるライブラリを取得するのに、実際にどのファイルを落としたのかをひとまとめにしたものです。
つまり、composer.lockがあるといちいち依存性を確かめることなく、初めにライブラリをインストールした人と同じファイル、バージョンのものをインストールすることができるのです。

オートローダを吐き出せる

PHPにおける名前空間とオートローダの機構は非常に強力なもので、こいつを導入しているかどうかで開発効率が大きく変わります。
そして、composerはこのオートロードの設定までも世話してくれるのですから驚きです。
composerを使用してライブラリをインストールすると、vendor/autoload.phpというファイルが生成され、このファイルをrequireすることで、vendor配下のライブラリをオートロードできるように設定してくれるのです。
さらに、composer.jsonに以下の様な記述を追加することで、オートロードに設定を追加することだってできます

    "autoload": {
        "psr-4": {
            "Niisan\\": "src/"
        }
    },

この設定は、Niisan\で始まる名前空間のオートロードをpsr-4にしたがって、src/配下で行うということです。
例えば、Niisan\Model\Classという名前に対し、src/model/Class.phpをオートロードするようになります。
オートロードの設定を後から付け加えた場合は、composer dump-autoloadとしてやることで、vendoer/autoload.phpに設定を加える事ができます

composer前提の環境を用意しよう

composerは最近はみんな使っているのですが、PHPには同梱されていません
composerでの開発を前提にする場合は、前もって導入済みの環境があると便利です
私の場合は、dockerで以下の様なDockerfileを元に導入済みのイメージを予めビルドしておいたりしています

FROM php:latest
MAINTAINER niisan-tokyo <***@****>

# php で必要なもの入れとく
RUN apt-get update && apt-get install -y unzip git && \
    docker-php-ext-install pdo_mysql mysqli mbstring

RUN mkdir /var/php -p
WORKDIR /var/php

# composer入れる(2行目はバージョンによってハッシュ値が変わるので作成時の最新のものを入れるべき)
# => https://composer.github.io/pubkeys.html
RUN php -r "readfile('https://getcomposer.org/installer');" > composer-setup.php ;\
php -r "if (hash_file('SHA384', 'composer-setup.php') === 'a52be7b8724e47499b039d53415953cc3d5b459b9d9c0308301f867921c19efc623b81dfef8fc2be194a5cf56945d223') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" ;\
php composer-setup.php --filename=composer;\
php -r "unlink('composer-setup.php');" ;\
mv composer /usr/local/bin/composer

CMD /bin/bash

composerのよく使うコマンド

composerを使った開発は手順がはっきりしていて楽です。
まずプロジェクトを作るのに、composer initcomposer create-projectを使う。
続いて必要なパッケージを入れるために、composer requireを使用していく
不要なパッケージはcomposer removeで取り除いておき、
アプリケーションで名前空間の設定が追加されればcomposer dump-autoloadでオートローダを刷新させれば良いので、

そんなコマンド群をちょっと見ておきます

init

composer init

composer使ったプロジェクトを自作するときに使うものです
ちゃちゃっとライブラリ書きたい時とかに使います
対話式で幾つか設定を加える事もできますが、全部スキップしてもいいです

create-project

あるプロジェクトはプロジェクト作成時にテンプレートを用意してくれる場合があります
モダンなフレームワークはこのcreate-projectを使用してプロジェクトを生成してくれる場合が多いです。
例えば、laravel, cake3, bearsunday, auraなどです。

laravelの場合は以下のコマンドでプロジェクトを作成できます

composer create-project --prefer-dist laravel/laravel blog

require

composer require <package>[:<tag>]

composerを使ってライブラリやパッケージをインストールします
インストールされたライブラリの情報はcomposer.jsonに記載され、実際に何をインストールしたかの情報がcomposer.lockに記載されます
composerを使っている場合はなるべくcomposer requireを使用するようにしましょう

オプションとして--devをつけると、開発環境専用のパッケージとしてインストールすることができます。
これは、composer.jsonの中で、require-devの項目に追加されるということです

install

composer install

composer.jsonに記載されている内容、もしくはcomposer.lockに記載されている内容に従って、パッケージをインストールします
プロジェクトのメンバーは、このコマンドを使用することによって、パッケージの依存性を解決することができます。
パッケージが更新されたら、再度このコマンドを打つといいでしょう

update

composer update

composer.lockを無視してパッケージをcomposer.jsonを元にインストールします
現在の依存性を全部最新化したい時とかに使いますが、通常余り使う機会はないように思います。

remove

composer remove <package>

requireの逆で、パッケージを取り除きます
一応入れてみたけど、やっぱり使わないライブラリとかが出てきたら、こいつで取り除くといいでしょう。
なんのために使うかわからないライブラリやパッケージがあるのは、あまり気持ちの良いものではないので

dump-autoload

composer dump-autoload

先に述べた名前空間を吐き出させるコマンドです。
composer.jsonにautoloadの項目を追加した場合はこのコマンドを使ってオートローダを刷新しておくと良いでしょう

まとめ

composerを使うと、適宜見つけてきたパッケージを特に苦労することなく導入でき、本番適用やメンバーとの共有時もcomposer install一発で解決することができます。
コードのメンテも外部ライブラリをcomposerに任せられるので、自分たちの書いたものだけに集中できるというものです

そんなわけで、やっぱりcomposer使った開発は楽です
composerも名前空間もないコードをメンテすると、つくづくそう思います

参考

composer
laravel installation
cake quick start
BEAR.Sunday quick start
Aura quick start