[Composer] PHPのパッケージ管理にComposerを使う | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

今までPHPの外部ライブラリを使う場合はPEARを使ってたんですが、最近は廃れてきて変わってComposerというパッケージ管理ツールが主流となっているようなのでその使い方のメモです。


PEARの場合、root権限が必要だったりするので導入の障壁が高かったんですが、Composerの場合は一般ユーザーでパッケージを導入できるので、ユーザー環境ごとに異なるパッケージやバージョンなどを使うといったメリットがあったりします。



Composerをインストールする


とりあえずインストール方法は、下記のコマンドを叩きます。


$ curl -sS https://getcomposer.org/installer | php

社内環境などプロキシを介してインターネット接続する必要がある場合は、環境変数のHTTP(S)_PROXYをセットしておきましょう。


export HTTP_PROXY=http://proxy.example.com:8080
export HTTPS_PROXY=http://proxy.example.com:8080

下記のようにPHPのエラーが出た場合はメッセージのとおり、detect_unicodeオプションをOFFにセットしなおします。


#!/usr/bin/env php
Some settings on your machine make Composer unable to work properly.
Make sure that you fix the issues listed below and run this script again:

The detect_unicode setting must be disabled.
Add the following to the end of your `php.ini`:
    detect_unicode = Off

The php.ini used by your command-line PHP is: /usr/local/lib/php.ini
If you can not modify the ini file, you can also run `php -d option=value` to modify ini values on the fly. You can use -d multiple 

times.


まぁ、php.ini自体rootじゃないと触れないじゃんって環境の人は、下記のように実行することでもComposerのインストールが可能です。


$ curl -sS https://getcomposer.org/installer | php -d detect_unicode=Off
#!/usr/bin/env php
All settings correct for using Composer
Downloading...

Composer successfully installed to: /home/foo/composer.phar
Use it: php composer.phar


が、このやり方をとってしまうとcomposer実行時に毎回detect_unicodeオプションを指定しないといけないので、素直にphp.iniを変更したほうがよさそうです。

オプションなしで実行すると下記のようにエラーが出て実行できません。


$ composer
????

先ほどのダウンロードのメッセージが表示されたらインストールは完了で、実行ディレクトリにcomposer.pharというファイルが保存されています。


あとは、PATHが通っている適当なディレクトリへ(名前が少し長いのでお好みで変更して)保存しておきます。


# mv composer.phar /usr/local/bin/composer

Composerが動くかどうかは一度実行してみましょう。


$ composer 
   ______
  / ____/___  ____ ___  ____  ____  ________  _____
 / /   / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__  )  __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
                    /_/
Composer version 1.0-dev (1d8f05f1dd0e390f253f79ea86cd505178360019) 2015-02-11 11:31:57

Usage:
 [options] command [arguments]

Options:
 --help (-h)           Display this help message.
 --quiet (-q)          Do not output any message.
 --verbose (-v|vv|vvv) Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug.
 --version (-V)        Display this application version.
 --ansi                Force ANSI output.
 --no-ansi             Disable ANSI output.
 --no-interaction (-n) Do not ask any interactive question.
 --profile             Display timing and memory usage information
 --working-dir (-d)    If specified, use the given directory as working directory.

Available commands:
 about            Short information about Composer
 archive          Create an archive of this composer package
 browse           Opens the package's repository URL or homepage in your browser.
 clear-cache      Clears composer's internal package cache.
 clearcache       Clears composer's internal package cache.
 config           Set config options
 create-project   Create new project from a package into given directory.
 depends          Shows which packages depend on the given package
 diagnose         Diagnoses the system to identify common errors.
 dump-autoload    Dumps the autoloader
 dumpautoload     Dumps the autoloader
 global           Allows running commands in the global composer dir ($COMPOSER_HOME).
 help             Displays help for a command
 home             Opens the package's repository URL or homepage in your browser.
 info             Show information about packages
 init             Creates a basic composer.json file in current directory.
 install          Installs the project dependencies from the composer.lock file if present, or falls back on the composer.json.
 licenses         Show information about licenses of dependencies
 list             Lists commands
 remove           Removes a package from the require or require-dev
 require          Adds required packages to your composer.json and installs them
 run-script       Run the scripts defined in composer.json.
 search           Search for packages
 self-update      Updates composer.phar to the latest version.
 selfupdate       Updates composer.phar to the latest version.
 show             Show information about packages
 status           Show a list of locally modified packages
 update           Updates your dependencies to the latest version according to composer.json, and updates the composer.lock file.
 validate         Validates a composer.json


Composerの使い方


PEARの場合はパッケージ名を直接指定してインストールしますが、Composerの場合はJSONファイルに必要なパッケージのリストを定義して管理します。
インストールしたいパッケージは、下記のサイトから見つけることができますが、全てではないので使いたいパッケージがComposerに対応しているかは個別に確認していくほうがよさそうです。


https://packagist.org/


今回はPEARの時にも使っていたPHP_CodeSniffer をインストールしてみたいと思います。

余談ですがPHP_CodeSnifferの使い方は以前に書いた「PHP_CodeSnifferでコーディング規約に準拠しているかチェックをする 」を参照してください。


PHP_CodeSnifferをインストールするためにcomposer.jsonというファイルを作り、下記のように書いておきます。


composer.json
{
  "require": {
    "squizlabs/php_codesniffer": "dev-master"
  }
}

これでインストールを実行してみます。


$ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev)
  - Installing squizlabs/php_codesniffer (dev-master ecd984a)
    Cloning ecd984a526a6ba78967fdaaf2b313cc0dea4b60f
    Failed to download squizlabs/php_codesniffer from source: The process "git clone --no-checkout 

'https://github.com/squizlabs/PHP_CodeSniffer.git' '/home/foo/workspace/vendor/squizlabs/php_codesniffer' && cd 

'/home/foo/workspace/vendor/squizlabs/php_codesniffer' && git remote add composer 'https://github.com/squizlabs/PHP_CodeSniffer.git' 

&& git fetch composer" exceeded the timeout of 300 seconds.
    Now trying to download from dist
  - Installing squizlabs/php_codesniffer (dev-master ecd984a)
    Downloading: 100%         

Writing lock file
Generating autoload files

インストールが完了するとカレントディレクトリ内にvendorディレクトリができ、その中にダウンロードしたファイルが格納されています。
PHP_CodeSnifferの場合、インストールされるのはコマンドとなりますが、vendor/binにphpcsコマンドが格納されています。


$ ./vendor/bin/phpcs test.php

FILE: /home/foo/workspace/test.php
----------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------
 2 | ERROR | Missing file doc comment
----------------------------------------------------------------------

Time: 58ms; Memory: 6Mb


必要に応じてvendor/binにPATHをを通しておけば便利でしょう。

PHP_CodeSnifferの場合、コマンドにインストールとなるためプログラムの組み込みとか不要ですが、ライブラリ系で自前のプログラムに組み込んで使いたいといった場合、venter/autoload.phpをrequireするだけで利用が可能となります。


例としてpear/log を使って見たいと思いますが、その前にインストールを行います。

先ほどのcomposer.jsonにpear/logの情報を追記します。


{
  "require": {
    "squizlabs/php_codesniffer": "dev-master",
    "pear/log": "dev-master"
  }
}


これでinstallオプションで実行といいたいところですが実際に実行してもインストールされません。


$ composer install
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. Run 

update to update them.
Nothing to install or update
Generating autoload files


composerの設定ファイルにはcomposer.json以外にcomposer.lockというファイルがあり、こちらが優先されます。
メッセージのとおりcomposer.lockが更新されていないので特にやること無いよって言われて処理がストップしています。
そこで、更新処理を実行します。


$ composer update  
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Installation request for pear/log dev-master -> satisfiable by pear/log[dev-master].
    - pear/log dev-master requires pear/pear_exception 1.0-beta1 -> no matching package found.

Potential causes:
 - A typo in the package name
 - The package is not available in a stable-enough version according to your minimum-stability setting
   see  for more details.

Read  for further common problems.


ただ、上記のようにエラーが出てインストールされません。

メッセージの内容から依存関係があるパッケージが存在しないとあり、Packagistにも依存関係のあるパッケージの情報が記載されています。



※ 厳密に言うとこのメッセージは依存関係のエラーというよりはスタビリティに対応するパッケージ名が見つからないというものです。詳細は「[Composer] composer.jsonを読み解く 」を参照してください。


pear/logの依存関係


ってことで、その情報も追加しておきます(複数のパッケージを書く場合は、JSONの配列表記に注意)。



{
  "require": {
    "squizlabs/php_codesniffer": "dev-master",
    "pear/pear_exception": "1.0.*@dev",
    "pear/log": "dev-master"
  }
}


これでもう一度updateを実行してみます。


$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing pear/pear_exception (1.0-beta1)
    Downloading: 100%         

  - Installing pear/log (dev-master df7aa17)
    Cloning df7aa179cb596a217d6d3eb8c5e900f3a63b9dbe

pear/log suggests installing pear/db (Install optionally via your project's composer.json)
Writing lock file
Generating autoload files


だいぶ話がそれましたがこれでpear/logが新規にインストールされたので早速使ってみます。
通常なら、vendor/pear/log/Log.phpをrequireするところですが、Composerのautoload.phpをrequireすればインストールしているパッケージが利用可能になります。


<?php

require_once './vendor/autoload.php';

$console = Log::factory('console', '', 'TEST');
$console->log('Logging to the console.');

最後にパッケージの削除方法ですが、composer.jsonから不要なパッケージを削除してupdateすれば削除されます。

先ほど追加したpear/pear_exceptionおよびpear/logの行を削除してupdateをしてみます。


$ composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Removing pear/log (dev-master)
  - Removing pear/pear_exception (1.0-beta1)
Writing lock file
Generating autoload files


定義ファイルを書き換えていくやり方は少し戸惑いますが、慣れてしまえばそんな難しくもありません。

説明が長くなったので、その他の使い方などはまた別途書きたいと思います。