[PHP] Composer: インストール

PHPに関する記事を読むと「Composerからインストールして」というワードが多いので設定してみることにした。

Composer は node の npm や ruby の bundler にあたる管理ツール。
参考サイト

インストール

さっそくMacにインストールします。

% curl -sS https://getcomposer.org/installer | php
#!/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
A php.ini file does not exist. You will have to create one.
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 がないとか。
どこにあるの?

% php --info | grep php.ini
Configuration File (php.ini) Path => /etc

php.ini.default というだけあったので、これをcpして/etcに作れば良さそうなのだが、php.netと置き場所が違うのが気になる。
Homebrewで入れた方が良いのかな?と思ってHomebrewでPHP環境 現時点でのまとめを読んでそのまま閉じる。
zendでいれたPHPでいけるんじゃないかと思いつく。

% /usr/local/zend/bin/php -ini | grep php.ini
Configuration File (php.ini) Path => /usr/local/zend/etc
Loaded Configuration File => /usr/local/zend/etc/php.ini

いけそうなので実行。

% curl -sS https://getcomposer.org/installer | /usr/local/zend/bin/php
#!/usr/bin/env php
All settings correct for using Composer
Downloading...
Composer successfully installed to: /Users/***/composer.phar
Use it: php composer.phar

実行したディレクトリにcomposer.pharがダウンロードされました。
1ファイルなんですね。
ちなみにこんなスマートな方法がありました。
オプションを後ろに付ければいいみたいです。

% curl -s getcomposer.org/installer | php -d detect_unicode=Off

参考サイト

  • Install Composer for PHP with detect_unicode = Off as a php.ini file does not exist « Andrew Kirkpatrick
    バスの通っているディレクトリに移動。
    短い名前で使えるようにシンボリックリンクをつくる。
    単純にファイル名を替えてしまっても良いのだろうか?

    ダウンロードされるのは、composer のバイナリーファイルだそう。
    使いやすいようにコマンド名に変えて、ローカルのパスの通っているディレクトリに移動します。
% mv ./composer.phar ~/bin/composer

Composerの使い方

どんなものかすぐに動かして確かめてみたいので、ShellWrap というunixコマンドを使えるツールを試してみることにします。

{
  "require": {
    "mrrio/shellwrap": "0.*"
  }
}

インストールします。

% composer install
Loading composer repositories with package information
Installing dependencies
  - Installing mrrio/shellwrap (0.2.0)
    Cloning 0.2.0
Writing lock file
Generating autoload files

このような形でダウンロードされました。

.
├── composer.json
├── composer.lock
└── vendor
    ├── autoload.php
    ├── composer
    │   ├── ClassLoader.php
    │   ├── autoload_classmap.php
    │   ├── autoload_namespaces.php
    │   ├── autoload_real.php
    │   └── installed.json
    └── mrrio
        └── shellwrap
            ├── LICENSE
            ├── README.md
            ├── ShellWrap.php
            ├── composer.json
            ├── example.php
            └── tests
                └── main.php

ちなみに composer.json を編集し、"mrrio/shellwrap": "0.*" を削除、下記を実行すると

% composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Removing mrrio/shellwrap (0.2.0)
Generating autoload files
.
├── composer.json
└── vendor
    ├── autoload.php
    └── composer
        ├── ClassLoader.php
        ├── autoload_classmap.php
        ├── autoload_namespaces.php
        ├── autoload_real.php
        └── installed.json

管理されています。
## パッケージを使ってみる
Composer が作ってくれる autoload.php を require すると、管理しているパッケージをまるっと使えるようになるらしいです。
```php:test.php
<?php
// require_once 'vendor/mrrio/shellwrap/ShellWrap.php';
require 'vendor/autoload.php';
use MrRio\ShellWrap as sh;
// List all files in current dir
echo sh::ls();

実行。autoloadできていないっぽい。

% php test.php
PHP Fatal error:  Class 'MrRio\ShellWrap' not found in /Users/<あなたの名前>/test/test.php on line 8
Fatal error: Class 'MrRio\ShellWrap' not found in /Users/<あなたの名前>/test/test.php on line 8

ためしに <code>require_once 'vendor/mrrio/shellwrap/ShellWrap.php';</code> といれかえると実行できた。

% php test.php
composer.json
composer.lock
test.php
vendor

なぜかわからない。
追記(2013/07/18)
PSR-0 に従っているpackageは、autoloadできるということのようですね。
[Zend_Loader – ファイル・クラスのインポートについて調べる | deadwood](https://www.d-wood.com/blog/2013/07/18_4310.html)
## パッケージを使ってみる(再)
気を取り直してComposerのドキュメントにのっているmonologを試すことにする。
Composer が作ってくれる autoload.php を require_once すると、管理しているパッケージをまるっと使えるようになるらしいです。

composer.json
{
  "require": {
    "mrrio/shellwrap": "0.*",
    "monolog/monolog": "1.0.*"
  }
}

% composer update
Loading composer repositories with package information
Updating dependencies (including require-dev)
– Installing monolog/monolog (1.0.2)
Loading from cache
Writing lock file
Generating autoload files

```php:monolog.php
<?php
require 'vendor/autoload.php';
$log = new Monolog\Logger('name');
$log->pushHandler(new Monolog\Handler\StreamHandler('app.log', Monolog\Logger::WARNING));
$log->addWarning('Foo');

できているっぽい。

% php monolog.php
% cat app.log
[2013-06-16 21:56:01] name.WARNING: Foo [] []

うまくいったのかいかないのか。シックリこないけれども、これでよいのかな。
おそらく autoload に対応していないパッケージもあるということだと思うんですが、どこで見分けるんだろうか。