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

久方ぶりに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`としてやることで、`vendor/autoload.php`に設定を加える事ができます

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

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

```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 init`か`composer 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](https://getcomposer.org/)
[laravel installation](https://laravel.com/docs/5.2)
[cake quick start](http://book.cakephp.org/3.0/en/quickstart.html)
[BEAR.Sunday quick start](https://bearsunday.github.io/manuals/1.0/en/quick-start.html)
[Aura quick start](http://auraphp.com/framework/2.x/en/)