Composer のグローバルインストール

<i class="fa fa-puzzle-piece"></i> 導入
=======================================
Composer は PEAR、および Pyrus に代わる新しい PHP ライブラリ管理システムです。Pyrus と同じようにプロジェクト単位で管理することもできますが、PEAR の代替としてサーバー単位で管理する場合について考えてみます。Composer のドキュメントは、[一部が日本語訳されています。]

CentOS 7 で動作確認をしています。それ例外の OS では、テキストエディタの設定方法や Composer 自体のインストール方法など、この記事の内容と手順が異なる場合があるのでご注意ください。

[一部が日本語訳されています。]: https://kohkimakimoto.github.io/getcomposer.org_doc_jp/doc/ "* これはKohki Makimotoが個人的に翻訳している記事です。"

<i class="fa fa-file-text"></i> *.json のシンタックスハイライト
===============================================================
Composer の設定ファイルは JSON 形式です。CentOS 標準の yum リポジトリで提供されているテキストエディタのうち Emacs、gedit、nano は、初期状態で JSON ファイルのシンタックスハイライトが機能しません。以下のように設定ファイルの編集などを行い、シンタックスハイライトを有効にします。

Emacs
-----
個人設定ファイルを新規作成 (または追記) し、ファイル名が `.json` で終わるファイルを java-mode で開くようにする設定を追加します。

```el:~/.emacs
;; .json ファイルを Java モードで開く
(add-to-list 'auto-mode-alist '("\\.json$" . java-mode))
```

gedit
-----
ファイル名が `.json` で終わるファイルを JavaScript ファイルとして開くようにします。

```xml:/usr/share/gtksourceview-*/language-specs/javascript.lang
                    <!--##############
                        ## 以上省略 ##
                        ##############-->

<language id="js" _name="JavaScript" version="2.0" _section="Scripts">
  <metadata>
    <property name="mimetypes">application/javascript;application/x-javascript;text/x-javascript;text/javascript;text/x-js</property>
    <property name="globs">*.js;*.node;*.json</property><!--## *.json を追加 ##-->
    <property name="line-comment-start">//</property>
    <property name="block-comment-start">/*</property>
    <property name="block-comment-end">*/</property>
  </metadata>

                    <!--##############
                        ## 以下省略 ##
                        ##############-->
```

nano
----
Arch Linux の [nano-syntax-highlighting-git] パッケージを利用します。[^nano] [^nanorc]

```sh
# JSONファイルのシンタックスハイライトを行う設定ファイルをダウンロード
sudo wget https://raw.githubusercontent.com/scopatz/nanorc/master/json.nanorc --directory-prefix=/usr/share/nano

# nanoの個人設定ファイルから読み込むようにする
echo $'\n\n'## JSON files$'\n'include "/usr/share/nano/json.nanorc" >> ~/.nanorc
```

[nano-syntax-highlighting-git]: https://aur.archlinux.org/packages/nano-syntax-highlighting-git/ "nanoのシンタックスハイライト機能を強化する"
[^nano]: [nano (日本語) - ArchWiki](https://wiki.archlinux.org/index.php/Nano_%28%E6%97%A5%E6%9C%AC%E8%AA%9E%29#.E3.82.B7.E3.83.B3.E3.82.BF.E3.83.83.E3.82.AF.E3.82.B9.E3.83.8F.E3.82.A4.E3.83.A9.E3.82.A4.E3.83.88)
[^nanorc]: [37.nanoエディタの設定ファイル、nanorcをいじる | Linuxゲリラ戦記](http://www.garunimo.com/program/linux/linux37.xhtml)

<i class="fa fa-download"></i> インストール
===========================================
CentOS において EPEL リポジトリをインストールしていなければ、`sudo yum install epel-release` を実行してインストールしておきます。[^remi]

```sh
# Composer のインストール
sudo yum install composer
```

EPEL リポジトリのGPG公開鍵を取り込んでも良いか訊ねられた場合、Fingerprintが https://getfedora.org/ja/keys/ の指紋と大文字小文字無視で一致するか確認します。

[Windowsへのインストール]には、インストーラーが利用できます。

[^remi]: remiリポジトリ (`remi-release`) をインストール済みであれば、EPELリポジトリも依存関係でインストールされているはずです。

[yum-plugin-priorities]: https://wiki.centos.org/PackageManagement/Yum/Priorities "Many people find the priorities plugin to be a useful tool if properly configured, and used with an understanding of the functionality and a recognition of the limitations and potential issues. It can be used in conjunction with the 'exclude' and/or 'includepkg' options, as well as the 'enabled=0' option to disable a repo by default. This can let you choose which packages a less important repo will supersede those of a more important one."
[Windowsへのインストール]: https://kohkimakimoto.github.io/getcomposer.org_doc_jp/doc/00-intro.html#windows- "これはComposerをあなたのマシンにセットアップする最も簡単な方法です。"

<span id="-sudo-の設定" class="fragment"></span><i class="fa fa-home"></i> home の設定 [^home]
==============================================================================================
`composer` コマンドを実行したときの作業ディレクトリ (composer.json が置かれているディレクトリ) は、通常、カレントディレクトリになります。`composer global init` のようにコマンドラインオプションの最初に `global` を挟むと、`composer global config home` で参照できる home 設定オプションの値が作業ディレクトリとなります。

home 設定オプションの値は、COMPOSER_HOME 環境変数によって変更可能です。ここでは、`sudo` コマンドによってroot権限で実行するときのみ、同環境変数にPEARディレクトリのパスを設定します。

`pear` コマンドが存在しない場合 (php-pear パッケージをインストールしていない場合など) は、`$(pear config-get php_dir)` の代わりに、`/usr/share/pear` のような絶対パスを記述します。

```sh
# suders から読み込むファイルの作成
echo COMPOSER_HOME=$(pear config-get php_dir) | sudo tee /root/.sudo_env
```

sudo の設定変更には、`visudo` コマンドを使用してください。既定のテキストエディタは Vim なので、それ以外のエディタを使用する場合は `sudo EDITOR=emacs visudo` のようにします。

```ini:/etc/sudoers
                        ##############
                        ## 以上省略 ##
                        ##############

# 変身対象ユーザがrootの場合のみ設定する変数が含まれるファイルの指定
Defaults>root env_file = /root/.sudo_env
## ↑この行を追加 ##
```

[^home]: [COMPOSER_HOME | Command-line interface / Commands — Composer](https://getcomposer.org/doc/03-cli.md#composer-home)

<i class="fa fa-cog"></i> 初期設定
==================================
ミラーサイトを設定し[^mirror] [^mirror-allowed]、`composer` コマンドを高速化するプラグインを導入しておきます[^prestissimo]。

```sh
# Packagistのミラーサイトを設定
sudo composer global config repositories.packagist composer https://packagist.jp

# Composerの通信を並列化するプラグインのインストール
sudo composer global require hirak/prestissimo
```

[^mirror]: [packagist.orgのミラーサーバを立ててcomposer updateを18倍速くする #packagist - Qiita](//qiita.com/Hiraku/items/51961aa49f7a2922011d)
[^mirror-allowed]: [HirakuさんはTwitterを使っています: "中の人の許可が取れたので、packagist.jp は合法になりました"](https://twitter.com/Hiraku/status/685973192326791169)
[^prestissimo]: [composerを速くするプラグイン・prestissimoを作った: Architect Note](http://blog.tojiru.net/article/432944706.html)

Windowsの場合
-------------
hirak/prestissimo は [cURLサポート機能] に依存しています。Windowsでこの機能を利用するには、次のように [curl.cainfoディレクティブ] にCA証明書リストのパスを設定する必要があります。CA証明書リストがない場合は [Git] をインストールしておきます。[^curl]

```ini:%ProgramFiles%/php/php.ini
                        ;;;;;;;;;;;;;;
                        ;; 以上省略 ;;
                        ;;;;;;;;;;;;;;

[curl]
; A default value for the CURLOPT_CAINFO option. This is required to be an
; absolute path.
curl.cainfo = C:/Program Files/Git/usr/share/pki/ca-trust-source/ca-bundle.trust.crt
;; ↑ curl.cainfo のコメントアウトを外し、値をCA証明書へのパスに

                        ;;;;;;;;;;;;;;
                        ;; 以下省略 ;;
                        ;;;;;;;;;;;;;;
```

[^curl]: [Windows版PHPのcurlの証明書 - Qiita](//qiita.com/iakio/items/71536dc5e615f03433a0 "Windows版のPHPでcurlを使った時に、CA証明書がないというエラーが発生する場合がある。")
[cURLサポート機能]: https://secure.php.net/manual/book.curl.php "多くの異なったプロトコルで様々なサーバーと接続し、 通信することが可能になります。"
[curl.cainfoディレクティブ]: https://secure.php.net/manual/curl.configuration.php#ini.curl.cainfo "CURLOPT_CAINFO オプションのデフォルト値。 絶対パスで指定する必要があります。"
[Git]: https://git-scm.com/downloads

<i class="fa fa-archive"></i> パッケージのインストール
======================================================
以下のようにして、必要なライブラリやツールの依存関係を定義し、インストールすることができます。

```sh
# パッケージのインストール
sudo composer global require zendframework/zend-db zendframework/zend-eventmanager esperecyan/url
# 開発環境でのみ利用するパッケージのインストール
sudo composer global require phpunit/phpunit apigen/apigen --dev
```

パッケージに含まれるコマンドは `sudo composer global config bin-dir --absolute` でパスを取得できるディレクトリにインストールされます。

<i class="fa fa-leaf"></i> PEAR ライブラリのインストール
========================================================
PEAR、および PEAR2 のライブラリは、Composer で管理することができます。ここでは、PEAR の公式リポジトリに置かれているライブラリをインストールする方法について考えてみます。

<i class="fa fa-sitemap"></i> PEAR 公式リポジトリを追加する
-----------------------------------------------------------
まずは、お手軽ですがおすすめできない方法を紹介します。

```sh
# リポジトリの追加
sudo composer global config repositories.pear pear https://pear.php.net

# pear/net_ipv6 をインストールしてみる
sudo composer global require pear-pear.php.net/Net_IPv6
```

PEAR リポジトリの構造上、パッケージの一覧を取得するのに非常に時間がかかります。そのため、この方法でライブラリをインストールすると、各種 composer コマンドの実行が極めて遅くなります。

```sh
# リポジトリの削除
sudo composer global config --unset repositories.pear

# pear/net_ipv6 の削除
sudo composer global remove pear-pear.php.net/Net_IPv6
```

<i class="fa">🐘</i> Packagist からインストール
-----------------------------------------------
ほとんどのPEARライブラリは、[GitHub上のリポジトリ] に composer.json が用意されています。その一部は Packagist にも登録されています。[Packagistに登録されているライブラリ] は、リポジトリを追加せずにインストールできます。

```sh
# pear/archive_tar をインストールしてみる
sudo composer global require pear/archive_tar
```

[GitHub上のリポジトリ]: https://github.com/pear "PEAR - PHP Extension and Application Repository"
[Packagistに登録されているライブラリ]: https://packagist.org/packages/pear/ "Packages from pear | Packagist"

### 開発版のインストール
Packagistに登録されているPEARライブラリでも、対応するリポジトリで [バージョン番号のように見えるタグ] が付けられていない場合があります。そういったライブラリの最新版を追うためには、以下のように開発版としてインストールする必要があります。

```sh
# pear/services_w3c_htmlvalidator の開発版をインストール
sudo composer global require pear/services_w3c_htmlvalidator:@dev
```

[バージョン番号のように見えるタグ]: https://getcomposer.org/doc/02-libraries.md#tags "「X.Y.Z」か「vX.Y.Z」に一致し、オプションで接尾辞として -patch (-p)、-alpha (-a)、-beta (-b)、-RC のいずれかが続きます。接尾辞に数字を付けることも可能です。"

<i class="fa fa-github"></i> GitHub からインストール
----------------------------------------------------
Packagist に登録されていないパッケージは、以下のように GitHub 上のリポジトリを追加してインストールします。Gitがインストールされていない場合は、`sudo yum install git` を実行してインストールしておく必要があります。

```sh
# pear/net_smartirc のGitリポジトリを追加
sudo composer global config repositories.pear/net_smartirc git https://github.com/pear/Net_SmartIRC.git

# pear/net_smartirc をインストール
sudo composer global require pear/net_smartirc
```

<span id="依存性の解決に失敗するとき" class="fragment"></span><i class="fa fa-times-circle" aria-hidden="true"></i> 依存性の解決に失敗するとき
----------------------------------------------------------------------------------------------------------------------------------------------
インストールしようとしたパッケージの依存しているパッケージが開発版であるために、インストールに失敗する場合があります。

```
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - pear/net_ipv6 dev-topics/test-for-pr5 requires pear/pear * -> satisfiable by pear/pear[dev-master] but these conflict with your requirements or minimum-stability.
    - pear/net_ipv6 dev-master requires pear/pear * -> satisfiable by pear/pear[dev-master] but these conflict with your requirements or minimum-stability.
    - Installation request for pear/net_ipv6 @dev -> satisfiable by pear/net_ipv6[dev-master, dev-topics/test-for-pr5].
```

上のエラーメッセージの `requires pear/pear *` から、安定版の pear/pear が存在しないことがわかります。

```sh
# pear/net_ipv6 のGitリポジトリを追加
sudo composer global config repositories.pear/net_ipv6 git https://github.com/pear/Net_IPv6.git

# pear/net_ipv6 の開発版と依存している pear/pear の開発版をインストール
sudo composer global require pear/net_ipv6:@dev pear/pear:@dev
```

<span id="実行時に例外が発生するとき" class="fragment"></span><i class="fa fa-exclamation-triangle" aria-hidden="true"></i> 実行時に例外が発生するとき
------------------------------------------------------------------------------------------------------------------------------------------------------
`Fatal error: require_once(): Failed opening required 'HTTP/Request2.php' in /usr/share/pear/vendor/pear/services_w3c_htmlvalidator/Services/W3C/HTMLValidator.php on line 20` のような例外が発生する場合があります。

```javascript:composer.json
                     /* ##############
                        ## 以上省略 ##
                        ############## */

    "type": "library",
    "require": {
        "pear/pear_exception": "*"
    },
    "require-dev": {
        "phpunit/phpunit": "*"
    }
}
```

```xml:package.xml
                    <!--##############
                        ## 以上省略 ##
                        ##############-->

 <dependencies>
  <required>
   <php>
    <min>5.1.6</min>
   </php>
   <pearinstaller>
    <min>1.5.4</min>
   </pearinstaller>
   <package>
    <name>HTTP_Request2</name>
    <channel>pear.php.net</channel>
    <min>0.2.0</min>
   </package>
  </required>
 </dependencies>

                    <!--##############
                        ## 以下省略 ##
                        ##############-->
```

[pear/services_w3c_htmlvalidator] の composer.json と package.xml を比較してみると、実際に依存しているのは pear/pear_exception ではなく pear/http_request2 であることがわかります。[composer.jsonのrequreキー]の記入漏れです。[^require-http_request2]

```sh
# pear/services_w3c_htmlvalidator が依存している pear/http_request2 をインストール
sudo composer global require pear/http_request2
```
[^require-http_request2]: この問題は[topics/composer-for-pearブランチで修正されている]のですが、まだ既定のブランチに取り込まれていません。

[pear/services_w3c_htmlvalidator]: https://github.com/pear/Services_W3C_HTMLValidator/ "W3C Markup Validation Service へのオブジェクト指向のインターフェース。"
[composer.jsonのrequreキー]: https://getcomposer.org/doc/04-schema.md#require "リストのパッケージは、このパッケージに必要とされます。これらの要件を満たさない限り、パッケージはインストールされません。"
[topics/composer-for-pearブランチで修正されている]: https://github.com/pear/Services_W3C_HTMLValidator/commit/a4b533e016ba18f3e2323ce2dd266e59900f3b9c "Enhancement: composer setup"

<i class="fa fa-arrow-circle-right"></i> 参考ページ・脚注
=========================================================