Technote

by sizuhiko

PHPカンファレンス2015で発表しました

2015/10/03 に行われたPHPカンファレンス2015で発表をしてきました。

スライドは以下の内容です。

PHPカンファレンスでは公募セッションは最大30分のため、すべてのページについて話すことができませんした。

セッションはじまるときにComposerの利用状況についてヒアリングしたところ、半数以上の方が「これからComposerを使う人」だったため、 入門部分を中心に解説しました。

このブログでは、スライドの共有と共に、話せなかった部分ついて(とうまくいかなかったデモも)書いておきたいと思います。

Composerと、その歴史

PHPで開発をするのに、デファクトスタンダードになったといって良いComposer。

Composerは2012年3月1日に生まれました。最初のリリース番号は1.0.0のアルファ1です。 現在も1.0-devというバージョンで日々アップデートが行われています。 2012年というのはすごい最近ですよね。たった3年前です。ではその前はどうだったのか?少しふりかえってみたいと思います。

Composerの前はどうだったのか?

PHPにはじめて拡張モジュールやライブラリの置き場所ができたのは1999年、pearという名前でした。 perlのCPANに影響を受けていて、あくまでコードリポジトリという位置づけでした。 ComposerがDependency Managementであるのとは異なります。2006年にはPHP5.3に対応したpear2とpyrusが登場しました。 しかしpearは厳密なコードレビューからオープンソースのリポジトリでありながら「誰もが自由に公開できる場所」とはいいづらいものでした。 そこで2008年にnequalが立ち上げたのがopenpearです。pearパッケージを誰もが自由に公開できるような場所となりました。リポジトリはsvnでした。 あのsotarokさんのコメントがトップページにあります「夢のような話だ」、まさにそのとおりでした。しかし時代はgit、githubになり、2012年にcomposerが生まれたのです。

Composerを正しく理解する

ComposerはDependencyManagementです。 例えばYumやAptといったパッケージ管理とは違います。pearはこちらに近かったかもしれません。 npmやbundlerといったものに影響を受けていて、プロジェクト単位で依存関係を管理します。

Composerが必須になる流れ

さてpearを使っていた中で、一番インストールしたことがあるパッケージといえば何でしたか? 私はどんなプロジェクトでも必ず必要だったのはPHPUnitではないかと思います。PHPUnitインストールしたことがありますか? pearでやるとかなり面倒なんですよね、複数バージョン入れ分けなくてはいけないなんて事はなかったですか?(地獄でしたよねw)

昨年、PHPUnitはPEARから卒業しました。スライドではそのときのSebastionBergmannのツイートを引用しました。 つい最近サルベージしたので、アイコンは当時写真だったと思うのですが、今はイラストですね(良く似ていますww)。

具体的には、csvから始まって、pearに移って、2009年にはgithubに移って、今日ではpearから卒業する、長らくありがとうという内容です。 PHPUnit3.7.0からComposrで取得可能です。

Composerより昔のやり方

例えばPHPUnitを例にとって、Composerより前はどんな方法だったか思い出してみましょう。 スライドではPHPUnitのpearを使った導入方法を掲載しました。1つ1つはもう気にしなくて良いのですが、長いですよね。 たいてい秘伝のレシピにしているか、ググってコピペするか、会社でドキュメント化しているか、そんなところだったと思います。

秘伝のレシピの場合、もちろんコマンド1つかもしれないですが、初めてプロジェクトに入った人がわかるわけではないですね。 複数バージョンを同居させるとかになると、pyrus使ったりしてもう少し違う感じにはなるかと思います。 あと、iniのインクルードパスを設定しないとファイルが読み込めなかったですよね

Composerになった(今どきの)やり方

Composerになって、初めて入れるときはrequire、他の人はinstallコマンドを実行するだけで良くなりました。 なんて簡単なんだろう、環境設定マニュアルとか必要ないレベルですよね。 composer使ったことあるひとなら、git cloneしたリポジトリにcomposer.jsonがある段階でinstallを実行するはずです。 (phpunitはrequire –devじゃないとか?いうのはそのとおりですが、今回は省略しています)

PHPで正しく開発するには

今日ではこのようにPHPでもモダンな開発をするベースが整っています。 PHPではPHP The Right Wayというページに、そのすべてがまとまっています。 もちろんComposerについても書いてあります。 PHP The Right Way は PHPerが幸せになる為の道しるべを示してくれています。 もちろん各国の有志によって翻訳されているので、すぐ読めます。かならず読んでみてください。

スライドの高速道路出口は 高速道路風標識ジェネレーター を使ってみたかっただけで、深い意味はありません。

オートローディング

PHP The Right Wayではコーディングスタイルや名前空間といったことにも言及しています。 どちらにもPSR-4という記述がありますが、PSR-4はオートロードについての標準です。現在はPSR-0を含んでいるので、PSR-0でなくPSR-4を参照するのが良いでしょう。

オートロードとComposerの関係について

PHPでクラスをオートロードするには、_autoloadを実装して、クラスが見つからないときに指示してあげるか、splautoload_registerで予めクラスのパスを登録しておくという2通りのやり方があります。

「ちなみにこの方法でオートロードを実装したことがある人はいますか?」という問いにはどなたも手があがりませんでした。これはそのとおりだと思います。Composer以前ではほぼ気にする人はいなかったでしょう。

もしフレームワークを使ってアプリケーションを実装している人は、フレームワークがオートロードの仕組みを用意してくれていたりするので、より意識しないかなと思います。

デモ

本番ではうまくいかなかったのですが、こちらで解説します。(カンファレンスあるあるですね)

インストール

スライドの内容を参考にcomposerをインストールします。 composerはプロジェクトのローカルでなく、パスの通っているところに配置してください。 Right Wayにも書いてあります。 Windowsを利用の方は公式ドキュメントを参照ください。

GitHubのリポジトリからソースコードを取得します。

git clone git@github.com:sizuhiko/phpcon2015_demo.git

プロジェクト情報の入力

まずcomposer initコマンドでプロジェクト情報を入力します。 requireやrequire-devは必要ないので、noを入力すれば大丈夫です。

インストールコマンドの実行

initコマンドを実行したら、composer installコマンドを実行します。最初は何もありません。 vendorディレクトリが生成されるはずです。

実行してみる

php -S localhost:8000 src/router.php というコマンドを実行します。 ブラウザからサンプルページを実行してください。

Welcome to PHP と表示されるはずです。

次にSay\Helloクラスを実行してみます。/helloにアクセスします。

Fatal error: Class 'Say\Hello' not found in /phpcon2015_demo/src/router.php on line 19

というエラーが表示されるはずです。 ソースコードでは以下のように指定していますが、オートロードが定義されていないのでクラスは見つかりません。

use Say\Hello;

そこで、composer.jsonを編集して、以下のようにrequireの下に追記します。

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

変更を保存したら、composer dumpautoload というコマンドを実行します。

再度Say\Helloクラスを実行してみます。/helloにアクセスします。 すると、ブラウザに

Hello

と表示されるはずです。 今度は/emojiにアクセスします。 先ほどと同じようなエラーが表示されるので、composer.jsonを編集します。

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

変更を保存したら、composer dumpautoload というコマンドを実行します。

再度Write/Emojiクラスを実行してみます。/emojiにアクセスします。 すると、ブラウザに

(^o^)

と表示されるはずです。

このようにオートロードについて自分で記述しなくても、名前空間の宣言をcomposer.jsonでおこなうと自動的にクラスをロードしてくれるようになります。

More Tips

この先は解説できなかった部分なので補足します。

リポジトリ管理

これについては第94回 PHP勉強会@東京〜PHPカンファレンス2015開催直前スペシャル〜で話しました。スタジオアルカナのレポートに詳しいログが残っていますので、そちらを参照ください。

スクリプト

Composerの強力な機能にスクリプト(フック)の実行があります。 installupdateなどcomposerのコマンド実行前と実行後に、スクリプトを実行できます。

  • pre-install-cmd
  • post-install-cmd

のようなイベント名です。 実行できるスクリプトは通常のCLIとPHPのクラスです。

例えば composer.json で以下のように記述します。

    "post-install-cmd": [
        "MyVendor\\MyClass::warmCache",
        "phpunit -c app/"
    ],

より詳しい情報は公式サイトを参照して欲しいのですが、これの使い方は2つ考えられます。

1つ目は、すでに存在するライブラリに対するプロキシとしたい場合です。 公開されているライブラリをForkしたり、コピーしてくることなく、独自の変更を加えたい場合や、ライブラリをインストールした後で独自のconfigを追加したい場合など、社内で複数のプロジェクトにまたがって同じカスタマイズをしたい場合は有効です。それぞれのプロジェクトではプロキシしたcomposer.jsonのあるリポジトリを指定するだけで、元のライブラリを修正することなく、同じようにカスタマイズ状態を利用できます。

2つ目は、フレームワークやライブラリを作った場合です。現在多くのフレームワークはアプリケーションテンプレートとして、composer create-projectに対応したスケルトンを用意しています。何もなければそれを取得すれば良いのですが、もちろんcreate-projectコマンドにもフックポイントが用意されているので、install後には環境設定ファイルなどがコピーされるようになっています。

まとめ

このようにComposerはpearでできていたパッケージ(コードリポジトリ)管理から、より多くの機能を持って、現在のアプリケーション開発になくてはならないものとなっています。

このセッションでComposerを使うようになってくれる人が増えることを期待してまとめとしたいと思います。

おまけ

LTのスライドも公開します。