JetBrainsユーザーグループ in 大阪でPhpStormの発表をしてきました #jbugj

1/30(水) 第二回 JetBrainsユーザーグループ in 大阪 でPhpStormの発表をしてきました。

JetBRAINSという会社の、主に IntelliJ IDEA とそのファミリー製品についてのお話を聞かせてもらいました。僕は、個人的にとある事情でPhpStormを使う機会に恵まれて、しばらく前から機能のいいところをツイートしてたんですが、それを今回の主催者のaa7thさんに見られていたらしいという経緯で、簡単な1セッションを持たせていただきました。

PhpStormはIntelliJ IDEAのサブセットで、IDEの基本ツールに、Web共通の機能とPHP関連だけを残して、デフォルトメニュー構成をPHPに最適化した感じのものです。

PHP IDE :: JetBrains PhpStorm

英語しかないですが、さすが毎日デイタイムで働いているメンテナがいる商用製品で、技術トレンドの追従がものすごく早いです。PHPのバージョンが上がったとき、オープンソースのIDEだと新しい文法への対応遅くて、それが待てなくてエディタを使うという人もいると思いますが、PhpStormはPHP5.3/5.4への対応が、そんじょそこらのエディタのシンタックスハイライトより早かったんじゃないかとさえ思いました。なんと次の安定バージョンには、ComposerとPHPMessのサポートが入るそうです。

今回、IntelliJ IDEAの主要ターゲット言語がJavaということもあったり、なぜかVisualStudioのプラグインの製品のユーザもいたりして、軽量言語シリーズのほうは少数派でした。いつものような濃い目のPHPあるあるネタが通じない場でしたが、なんとか無事めくり芸発表を終えることができました。ありがとうございます。

発表内容については、主催者さんのブログ、nocono のこの記事にすべてまとまっています。

第二回 JetBrainsユーザーグループ in 大阪開催しました #jbugj - ブログ・アンケート記入でIntelliJライセンスプレゼント - nocono

それぞれのセッションで印象に残ったところを。

オープニング・セッション: 渾身の「乙女心をくすぐられちゃいます」まさかの空振りw

製品紹介: コマーシャルライセンスは会社の経費で落とせる、パーソナルライセンスは個人で決済しないといけない、という違いでしかなく、会社にパーソナルを持ち込んで仕事で使ってもいい。仕事に使ってはいけないのはアカデミックライセンス。これは明確な指針だと思いました。

IDEAのデモ: コード補完で自動インポートが動いたとき、MavenXMLが勝手に書き換わって、エディタで開いたらもうJUnitが入っていたのがびっくりでした。あとキーボードショートカットステッカー。

IDEAを使った経験談: IDEに何を期待するかということで、ソースのテンプレートやコード補完などの「書く速さ」に注目してしまいがちだけど、実は作業時間のほとんどはコードを読むことに使われる。「読む速さ」で考えたとき、ナビゲーションまわりの機能が充実しているから嬉しい。禿同ですね。書くだけでいいなら、チューニングしまくったエディタとコピペには勝てませんから。

WebStorm: ごめんなさい自分の発表の後でスライドの調整してて、実はあまり集中して聞けてなかったです。Sassで色の値をセットした変数まで、エディタにその色を出してくれるとこは見てました。IDEAの売りのひとつは、けっこう大真面目に「CSSの色」ですね。

なお、こちらがイベントの開催中もっともRTされた重要なツイートとなります。

なんか見るたびに上に上がってきてもう毎回も目に入りました。結局懇親会でやっぱり「イデア」言っちゃうし、もう「マクド」と同じイントネーションで関西弁では「いであ」でOKってことで落ち着きました。「いであいかへん?」→「ええで」

似た話で細かいですが、PHPStormではなくPhpStormです。"hp"は小文字。WordpressでもWord_Pressでもなく、WordPressですよというアレと同じ感じですみません。まったくPHP系の人はうるさいですね、言語仕様には関数名の大文字小文字の区別ないくせに。すみません。

前日〜当日の朝あたり、スライドを作るためにPhpStormを触っていると、出るわ出るわのPinoco(拙作PHPフレームワーク)の問題点。自分typoしすぎやで。というわけでこんなことに。

f:id:tanakahisateru:20130201201727p:plain

一番棒が長い右端のが、イベント当日のpushですね。いやもう、リリース後の落ち着きが嘘のように立ち上がっていますね。PhpStormで触るってだけでまじで捗りすぎだから、ほんともうオープンソースライセンス版は危ないですよ。

というのも、実は僕はその日が納期の案件を抱えてて、わりと前倒しで完了してたつもりだったのですが、発表の直前にひとつ急ぎの作業が発生していました。後でもいいGitHubの黒猫とお戯れていたせいですね。で、急ぎだったので、ちょうど開いてたオープンソースライセンス版のPhpStormを使って、こっそり仕事済ませてました。git commit しただけで、FTPとgit pushを一気にやってくれるんだもの。まじ仕事が早いんだもの。

というわけで、これでもし商用版のライセンスがもらえたら、ライセンス条件違反をチャラにできて嬉しいなぁ。というのはネタで、まあエディタで追い付かなくなる仕事が来る前に、普通にパーソナルライセンス買います。はい。

Pinocoでシンプルに正しく(&ぶっちゃけで)DIを理解する

Pinocoだって実はすごいんだぞ、Pimpleになんて負けないもん、というわけで、

PHPメンターズ -> Pimpleでシンプルに正しくDIを理解する

をPinocoで理解してみようというネタをやります。先にこれを見ておいてください。

あ、「Pinocoってなんやねん、あっちょんぶりけかよ」って思った人すみません。Pinocoは拙作のマイクロフレームワークです。いわゆるオレオレの一種ですが、オレオレにしてはかなりよくできたほうだと思います。RESTなAPIを作る他のと比べて、どっちかといえばWebサイトを作るほうが強い感じのヤツ。

https://github.com/tanakahisateru/pinoco

で、DIですよ。依存性注入ですよ。楽しんご的なアレじゃないですよ。オブジェクト指向ですよ。
Pinocoの第一印象はみんな「プレーンPHPっぽいね」で、それはそれで狙い通りなんだけど、いかんせん、そのせいで「この子、やればデキる子...」というのがわかってもらえないかわいそうな所があります。まあ作者がドキュメントを書かずにソース読んで一人で使ってるからダメなんですけどね。

以前、Pinocoで遅延評価がおいしいという話を、Pinoco0.4はクロージャですごくなる - なんたらノート 第二期 に書いています。Pinoco_Vars を PHP5.3 で使うと、遅延評価でいろいろやるとき超クールとかそんな話です。しかもこれがランタイム依存なしで、単独で使えるクラスだからこれだけ使ってもいいよ、とかそのあたりに言及しました。今回、これ前提でいくので、事前に読んでおくとわかりやすいですよ。

じゃ、やりましょう。

まず、PHPメンターズのお題を引用:

アプリケーションからニュースレターを送信する機能を実装しているとします。ニュースレターを送信するという責務を持つニュースレタークラスと、具体的にメールシステムを使ってメッセージの送信を行う責務を持つメール送信インフラクラスの2つに着目しましょう。

あくまで説明用のサンプルモデルなので、細かい設計の是非は論じません。ニュースレターオブジェクトの送信メソッドを呼び出すと、メール送信インフラを使ってニュースレターが送信されることとします。

というわけで、こっちでも全く同じことをやりましょう。メールを送るためのインフラになるクラスを作りますね。

おまけで、同じインターフェースの別のメーラー実装も書きました。

じゃあつぎ、こいつらをPimpleではなくPinocoで依存性として管理するにはどうするか。

だいたい似たようなもんですね。

Pinoco_VarsはDIコンテナのために設計されたわけではなく、汎用的なオブジェクトとして使うためにあります。なので、ただの代入はインスタンスへのプロパティアクセスになっちゃいます。遅延評価されるプロパティ専用のメソッドを使うあたりが、ちょっと見た目、DI専用に作られたPimpleより愚直な感じですが、まあ問題ない範囲ですよ。

さて、ここからがDIを理解しましょうという話になります。ここまでは、あくまで「DIコンテナの使い方」の話。

PHPメンターズ版と違って、まず先に答えをいうと、次のコードはDIがうまくできなくなるダメな設計です。

ここまでは、何も問題ないように思えます。コンテナで管理してるのは、まだあくまで、メール送信をするインフラのほうで、アプリケーション固有の機能は独自に new して使っています。NewsletterTransfer::send() の中で完結して動くようにベタに書いた、という段階ですね。これでも一応、単体テストは通るだろうからTDDしてもいいでしょう。

これだけのコードをカタカタと書いてる時間があれば、みなさんそろそろ、

「ニュースレター送信はメール送信インフラに依存してるじゃん」

という本質に気付くと思います。イエース、そのとおり。

「じゃあさ、NewsletterTransferのほうもDIコンテナに入れようぜ」... カタカタカタ

おやおやおや〜、慌ててそんなことしていいのかな〜?

「あ、そうだ、SendmailMailer を EchoMailer にすり替えたほうがテストしやすいじゃん、オレ頭いい〜。えーと、スタブって言うんだけっけ? こういうの。」... カタカタカタ

はい、ここ、「依存性」の「注入」じゃないですね。こういう編集作業をした時点で、依存性を手動でセットしているということになります。

単にDIコンテナと呼ばれるものを使うってことがDIなんじゃない。みたいなことを、「(ご)」←こんな感じのアイコンの偉い人が、PHPカンファレンスで言ってました。せっかく入れ替え差し替えでうまくできるオブジェクト指向なのに、その差し替えをロジック中に残したら意味ないですね。

で、このまま慌ててリファクタせずに作業を進めるとどうなるでしょうか?


「ステージングに入りまーす。本番モードようそろ〜」

_人人人人人人人人人人人人人人人人人_
> 突然の NewsletterTransfer 修正 <
 ̄^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄

「ごめんなさい、モジュールのコードをフリーズしたというのは嘘でした」

一同「エー」


はいこれが依存性を注入しなかった代償です。
おっと、さらに焦った文系PG上がりのプロマネからこんな案が...

...こんなとこ辞めてやるフラグへまた一歩ですね。あるあるすぎますね。いったどれだけの、そして何年の間、 ->testmailer が偽り続けるのだろうか...


ちゃんとDIしましょう。まず、依存関係に対して、正直に正しくクラスを設計します。

大きな問題の1つは、NewsletterTransferクラスをパッと見て、具体的にどのクラスに依存しているのか、関連を持っているのか分からなくなっていることです。

というわけで、関係をちゃんとすると、

$container が $mailer になり、assert が消えてタイプヒントだけになりました。

NewsletterTransfer が本当に依存しているものだけ、DIコンテナから取り出して、個々に与えましょう。コンテナまるごと与えて好きにしろというのは、間違いだったのです。こうすることで、どのメール送信インフラを使うかを切り替える権限は、オブジェクトの設計から、DIの設定の方に逃がすことができました。

こういう部分部分のまとまりの良さを、OOP用語で凝集度といいます。一般的に、凝集度が高いほうが、テストも保守もレビューもしやすいです。

こうしちゃうと、たしかに、外から依存性を注入しないといけないので、すぐには動かせないかもしれません。でも、個々の部品から全体へのアクセス権を奪うことで、各実装が好き勝手できないようになります。どのモジュールが何に依存するのかという関係が、いつの間にか誰にも知られずに変わってる、なんて、ちょっとしたホラーですよね。現場ではよくありますが。

それにほら、システムのコンテナを渡してしまうのは、みんな大嫌いな、あのグローバル変数と同じことですよね。いつでもなんでもグローバル変数という、あのプログラムセンスを許せないなら、それと同じ意味のことをやっちゃダメ。

なぜグローバル変数がダメなのかは、いつどこで書き換えられるかわからない、ということ以外に、仕様を変えたいのに誰が使っているかわからない、というのも問題でしょ。スコープが閉じてなくて広すぎ、っていう問題。


以上、Pinocoでちゃんと動いてますよという証明のために、リポジトリ作りました。

https://github.com/tanakahisateru/pinoco-as-di-sample

ComposerがあるとPinocoを入れるのに便利ですが、なくてもエラーメッセージでだいたいわかります。PHPUnit

phpunit --bootstrap bootstrap.php test/NewsletterTransferTest.php

してみるといいと思いますよ。phpunit.xml が面倒で書いていません、ごめんなさい。

FirefoxでUser-Agentを変えるとき必須の拡張

FirefoxにはUser-Agentを切り替える拡張がいっぱいありますね。本体の開発ツールに「レスポンシブビュー」なんてあるので、あとは拡張でUA切り替えを使えば、かなりいい線でスマートフォンの真似ができそうです。

でも...

けっこう多くのUA切り替え拡張で、サーバに送信するときのUAは変更できても、いざJavaScriptでnavigator.userAgentを取ると、まだFirefoxのまんまだったりします。

そこでこの拡張もいっしょに!

User-Agent JS Fixer

https://addons.mozilla.org/ja/firefox/addon/user-agent-js-fixer/

サーバに送信したUAの値を取り、レスポンスを受けたとき、それをそのまま、navigator.userAgentにセットしてくれます。で、JavaScriptから見てもUAがちゃんと切り替わってくれます。

サーバ側でUAを使ってレスポンスのビュー切り替える以外にも、最近では、サーバではレスポンシブなページで済ませ、JSを使ってデバイス判別をしたりする場合が増えてきました。それがなかなか、全ブラウザ共通でいけるので、キャッシュが効いて良い感じだったりするんですね。そういうとき、JSから見たUAが送信したものと違ってると困る。

というわけで、クロスデバイスなサイトを作る人には、この拡張必須だなと思いました。

いま流行りの退職エントリを書いてみた

11月20日を以って、7年勤務した株式会社ループを退職しました。

Flashのゲームあたりから始まって、Javaの派遣だったり、古き良き(?)PHP4だったり、Directorだったりドット絵アニメーションだったりPSG音源ふうの作曲だったり、オンライン決済システムに突如Pythonを推してみたり、サーバサイド手出しできない縛りのJavaScriptで四苦八苦したり、PHPフレームワークを作ってみたり。いっぱいやりました。

思えば時間の使い方の自由が効く職場で、夜が遅いのはありましたが、そのかわり、いろいろなオープンソースのプロジェクトに、好き勝手に翻訳やパッチを送る時間を取ることもできました。まあ、自分が勝手にそうしていただけで、顰蹙買ってた可能性は高いです (^^;

7年も働いたんですが、勤続年数はこれでも社内で最短なんです。居心地がよすぎるんじゃないかと外の人に言われました。たしかに会社組織特有のプレッシャーはなかったですね。開発しながら顧客に直接接するストレスへの耐性が強ければ、いい就労環境だと思いました。ただ自分は、もっと会社の枠を外れてやりたかったので、外に出たんですけどね。

というわけで、僕もいま流行りの退職エントリを書くことができました。やっぱ流行には乗らなきゃですよね。

ただいま絶賛失業者です。事件に巻き込まれると「たなかひさてる(無職)」ってなっちゃうので、危ないことでなければ、面白いお誘いなんでもウェルカムです。いまのうちなら、平日の昼間にオフィスに遊びに来いがOKです。これまでだと営業活動になるか気を使う必要があったのが、何の得にならなくても遊びに行けますんで。ただし、めっちゃ交通費がかかるところには、経費が出ないのでなかなか...w

PHPMatsuri2012 (本編)

http://d.hatena.ne.jp/tanakahisateru/20121106/1352213410
の、続きです。

じゃあいよいよ本編。個人的にここポイントじゃないかと思ったことが、ろくでもない日記に混じって出てきます。

当日は10:00すぎ入りでした。誰かみたいに場所を間違えかけていた人にはそっちじゃないよとTwitterで言ったりしながら、ウコンの力で会場へ。朝イチのトイレで豚の背脂の臭いがしたのはナイショです。

開場が10:00でオープニングセッションが13:00開始というのは、すごくいいアイデアだと思いました。それだけ時間があれば、本編が始まるまでに、久しぶりに会った人と挨拶したり、初参加の人は場に慣れたりできますね。だいたいみなさん「この電源いいですか」で会話が始まる感じで、オープニングまでにはすっかりみんなの緊張感が取れていたと思いました。

作業環境を確保してネタの仕込みをやりはじめ、で、お昼になって、開会式がまだだというのに、その場でつるんだ連中とお昼ごはんに行くなどします。お昼はうどんと白ごはんが人気でした。

到着したてですぐにこってりはちょっと、なのか、昨晩飲み過ぎたせいかは人によりますが。


おうどんおいしゅうございました。オープニングはスポンサー紹介とかLT大会の賞品紹介とかみんな気軽に声をかけましょうとか。司会が指示を出したときの動きの良さは、PHPerのすごいところですね。「隣の人と話してみましょう」→ササッ→「はいでは前に注目してください」→ササッ。まじ優秀。

そのあとのセッションですが...

正直いうと、実はセッションを1つしか聴講していません。考えていたネタがうまくいきそうにないのと、すでに実績があったというのを知って、もうこうなったらと、あの資料を作るのに費やしました。

唯一聞いたのは、郡山さんの「DIS IS IT?」です。PHPへのdisりについて真剣に分析するという内容。

超良かった!

まず何がすごいって、Rubyコンテンツ産業振興センターでMatzのPHP否定発言を引用して始まります。有名企業からRubyへの寄せ書きとか、壁にいっぱい飾ってあるそんな場所で、ですよ。

ざっくり印象に残った流れはこうです。

PHPの中で一番嫌われているのは一貫性のなさ。それは成長期にいろんな言語の血を混ぜたから。ところで、複数の異なる語源を混ぜた、一貫性のない言語は他にもある。それは英語だ。エスペラント語は国際言語にならなかった。

だいたい「一貫性の欠如ってdisってる人の発言に一貫性がない」じゃないか。

PHPを嫌う人は何を否定しているのか、それは、本当の設計思想から個人の嗜好まで段階がある。設計思想について言うのは難しいので、多くの人は表面の好き嫌いでdisっている。ここがあの言語っぽくない、こっちはあの言語っぽくない、と、自分の好きなものと似ていないことを間違いだと言っている。

いきなり新たな正義を完璧だと押し付けてもうまくいかない。Unixのコマンド体系、あれは今どきひどいからPlan9に行こうとしたけど失敗した。綺麗にすることは、生活を変えるほどすごくはないから、人は今ので十分だと言う。ひどいところには蓋を作ってかぶせればいい。

「十分に機能すること」「レイヤー可能だということ」が大事。本当の進歩には漸進的な発展が必要だ。いまPHPerどもにジェネレーターは不要、なんていう声があるけど、昔はclassが不要、名前空間が不要とさえ言われた。で、結果どうか。今のPHPは当時とは確実に変わってきている。

最も強い者が生き残るのではない、
最も賢い者が生き残るのでもない、
唯一生き残るのは変化する者である --ダーウィン--

パチパチパチパチ〜

泣けますね。いやもう脱帽ですよ。経験が長い人はすごいですが、経験の前にバックグラウンドがある人は、いうことが違います。郡山さん、ウェブ以前はゲームプログラマーだったそうで。なるほどですね。


えーと


えーと

お弁当とか出ました。

えーと


すみません、あと全部、闇に吸い込まれました。

それはまた闇編(また分けて書くのか、いや、書けるのか)に。

闇の時間のあと、何を思ったか、1:30AMごろから、昨日食べたラーメンをもう一度、闇チャンピオンと食べに行くことになりました。夜中にタクシー飛ばしてゴー。
ちなみに、->find('all') で満点を出したあのチャンピオンを闇にけしかけたのは、私かもしれません。

でまあ、そのあと何を思ったか、歩いて帰ろうとしちゃいまして。夜中の2:00台に中洲から博多駅は、さすがにきつかったですね。主催の人が「近所にはサウナもあります」って言ってたのを思い出して、もうカプセル泊まろうってことになりました。会場に戻って最寄りのそれっぽいところへタクシー。カプセルハッカソーンとか言いながらまあ呑気に構えていたわけです。

ところが... まさかのカプセルホテル満室

「予約されましたか」
って、カプセルに予約要るんですか、博多...

しょうがないのでまた中洲へ。タクシーの運転手も「あそこならカプセルがいっぱいありますしね〜」と。ところが...

「予約されましたか」

え... ここも? あそこも、どこもかしこも...


東京大阪の皆さん、福岡では、カプセルホテルというのは宿が取れないときに飛び込むものではなく、予約して行くものだそうです。知らなかったですねー。やられましたねー。

そしてまた会場へタクシー。このタクシー代、全部合わせたら普通にホテル取れたんじゃないかと言われました。あとの祭りとはこのことですね。

しょうがないので会場で完全に寝巻きに着替えて、限界まで開発。意外と会場に泊まる人でパジャマ持ち込みが少なかったですね。少なかった...ですよ。

...えっと、正直言います。

自分しかいませんでした。

みんな、次の日に少しでも疲れを残さないよう、せめてジーンズはジャージに、上はなるべくソフトで襟のない服になったほうがいいと思いますよー。賛同者募集。

にしても、そんな時間からだともうぜんぜんダメですね。1行に1こtypo余裕です。Bootstrapさえ入れば... 白くなる空... あとは椅子を並べて横に...

ほどなく朝になって、ここCoderDojo(子供向けプログラミングハンズオン)始まるからと追い出され、ヘロヘロでまたウコンを補充。LT大会の間、自分の時間までに発表内容を完成に持って行こう。40人ぐらいエントリーするんだし余裕、って思ってたら...

2番 @tanakahisateru

rand() の神は死んだ。


ちなみに発表したMarkdownパーサはこちらです。

https://github.com/tanakahisateru/js-markdown-extra

デモはほぼ

https://github.com/tanakahisateru/yii-bootstrap-tutorial

まんまです。


もはや何の大会なんだかわからないぐらい、多種多様なデモが楽しかったです。
社名を出して変態と呼ばれるデモを連発する某社とか、県下2位のボディビルダーがAzureに生デプロイとか、大阪から自転車を持ち込んでサイクリングしてたPHPerの話とかもう、なんですかねこれ、とりあえずロックですね。

一昨年はパソコンを忘れて一晩中会場を徘徊し、去年はイケメンの田中さん発言で参加した田中どもを翻弄した、あの伝説の人が、事前準備の大事さを説明する名言を残しました。

反省します。でも遊ばないのは無理ですよね。ちゃんとネタを固めてから行くようにしましょう。


いよいよファイナル、海外ゲストのダスティンが素晴らしいプレゼンをしてくれました。

これについては、@remore さんが解説と翻訳を書いてくださっています。

http://rimuru.lunanet.gr.jp/notes/post/2955/

偉大なコントリビュータも最初はみんな小さなことからだった、みたいなことを言ってたときの、49枚目がすごく印象的でした。Fixed few typoって書いて、コミットいっぱいぶら下がってる絵です。

こういうのから参加し始めるって、シャイな日本人にとっては抵抗あるんですよねーと思います。コミットいっぱいぶら下げて Few typo でも、やっちゃダメってことはないんですよね。メンテナが忙しくて無視されるかもしれないけど、意味がないなんてことはない。

今回、はじめてコアの人に会って「あ I am あんまり can't speak English」って言ってたようなひとに、プルリクエスト用のブランチを教えたのですが、CakePHPの翻訳をプルリクエストしたら目の前で即マージされる、というドラマがありました。英語ができることが本質ではない、本質はコードだ、という、素敵なエピソードだと思います。


さて僕は、今回は究極の豚骨を見つけられたので、次回はもっと余裕を作って、味噌ラーメンと海鮮丼を極めたいです。

あと、次に行く方へアドバイス。前泊もいいけど、後泊もきっちり取って、次の日を観光に使うといいですよ。発表も終わって、気兼ねなく当日の夜飲むことができます。僕は今回、翌朝幼稚園に送っていくという重要なミッションのために、帰らざるをえませんでした。残念でなりません。

もし運が良ければ、スタッフ打ち上げに合流できて、残酷な天使のテーゼを完璧に歌い上げるCakePHPのコアデベロッパーを見ることができるかもしれませんし。


そんなのコミュニティに長年いる人の内輪ウケなんでしょ、なんて思ったら大間違いです。いいですか、PHPMatsuriは今回含めてもたった3回しか行われていません。このイベントでしか顔を合わせない人もいっぱいいます。さらに言うと、僕なんて、去年会った人の顔を忘れてたぐらいのレベルです。

まだ参加したことがない方へ。PHPMatsuriは、いちど飛び込んでしまえば、なんだこの最初っからフレンドリーなコミュニティは、と驚くでしょう。いや俺が好きなのはあの言語だ、PHPerなんて所詮...とみなさんが嫌うような、闇った感じの(=アン・リーダブル)PHPコードを書くような人は(たぶん)いません。むしろ、楽しみながら、PHPの本当のポテンシャルを知ることができるイベントだと思います。

-- あなたはまだ、本当のPHPを知らない --

おしまい。

PHPMatsuri2012 (前夜編)

こんばんは、イケメンじゃなかったほうの田中です。

PHPMatsuriでした。行きましたよ。去年はホーム大阪での開催にもかかわらず、運動会事情でホテル代含みで全額払って1日で帰るという悔しい思いをしたので、今年はそのリベンジを果たしにいざ福岡の地へ。

あ、普通にためになるレポートはみなさん素晴らしいエントリを書いてくださっているので、togatterを参照する (http://togetter.com/li/402628) なりするといいと思います。これはあくまで個人的な日記です。すごく個人的にPHPコミュニティスゲェなことを書きたいと思います。

PHPはロックですね。

まず今年の開催場所ですよ。福岡です。博多です。観光地じゃないですか。もうこれ遊ぶ気満々じゃないですか。そして会場は

Ruby・コンテンツ産業振興センター

これはロックですよね。ボーダレスですね。

でまあ、某アシアルの社員でおかしなTシャツを着ている人が、前日に同じ会場で何か勉強会をやってて懇親会があるよと言うので、そんじゃあまあ景気付けにそれを理由に前日軽く飲むかーと思って有給使って前泊で予定しました。

Google Maps カタカタ Ruby何とかセンター カタカタ...

「ここかー、駅から5分ってそれどこの不動産レートですかって話よねー、まあ歩いて行けないこともない距離だなー」

「近くのホテルは...おお、ここ近くて安い、ここにしよう」ポチっと

と、その直後、なにかおかしいことに気づいた。あれ? 東側? 西側じゃないの?

なんと、博多にはRubyのコンテンツのセンター が2つあったのです!

バッチリ遠い方の近くに宿を取ってしまいました。皆さん、博多駅の近くで勉強会があるときは気をつけましょう。Rubyセンターは2つあります。片方は総合庁舎内の施設なのでGoogleの地図に出て来ません。


まあ仕方がないのでまずはその遠い宿へ。新しいMacbookを抱えて新大阪駅から新幹線に乗る前に本屋に寄りました。暇だったので、みんなこの本を買って行きましょうってツイートするときの写真を撮るために。

で、ふとTwitterを開くと、ちょうど公式アカウントからの告知が!

そのとき、本屋の平積み台の一番目立つところにあったのはまさにあの本...

もうこんなの、やるしかないじゃないですか。

エントリー!

お褒めの言葉、ありがとうございます。


さてさて、ゆるゆると新幹線移動っと...移動しながら作業したりまとめたりできるからねー。
と、思っていたのですが、そこでまた大きなミスを犯していたことに気づきました。

大阪から西に向かう新幹線には電波が届かない!

大坂〜東京間の感覚でいたらダメなんですね。新神戸から先、駅以外ほぼトンネルor人が住んでない場所。ほとんど都市部を通りません。ああっ、岡山...ツーツーツー、広島なら...ツーツーツー、そんなこんなで、電波が生きているわずかな隙間を見つけては、


「40秒で git push しな!」

って感じの状態でした。

九州方面へ行かれる方は、中国地方をナメてはいけません。ソフトバンクやイー・モバイルではあの地形には太刀打ちできないと、肝に銘じておいたほうがいいでしょう。


博多に到着、バス乗り間違えて昼間の歓楽街を歩いたり、Macbook Air を持って行ったらホテルのインターネット無料サービスが有線オンリーだったり、なんてトラブルもありながら、ところでアシアルさん、何時からだろう? って聞いてみたら、ぜんぜん最初から参加できそうな時間じゃないですか。

「ATNDで受け付けてますよ」

はい、開始1.5時間前にエントリー。

そうそう、Monacaは思ったよりずっといい開発環境でした。Webブラウザで動くIDEがかっこいいのと、実機テストにフルビルドが要らないのが特徴の、最初っからサーバ側ビルドを指向したPhoneGapって感じでした。告知告知。おかしなTシャツの人さん、ワークショップのデモで起こるバグはきっとnullチェックが原因だよって指摘したりして遊びました。

というわけで、いぇーい、前日から懇親会だー!
まあ、このあと軽く福岡の人と飲んで今夜はぐっすり... と、そこへ。

「田中さん田中さん、僕ですよ、わかりますか」

と、背の高い人とwidthの大きい人と半袖の人と物静かな外人が... えーっと、どっかで会ったことありますよね、そうですね、そりゃそうですよ、去年のPHPMatsuriのスタッフですよ。

なぜか、HTML5なスマホアプリの懇親会にPHPerの島ができました。まあそこまではよかった。

次に、PHPカンファレンス関西で5分で3回同じLTをした伝説のあの人物が合流するわけですよ。まだまあ、それはいいですよ。

とある猫のアイコンの人がその合流の流れをTwitterで察知して、いいなあ行こうかなって言います。ちょっとそれに気づくのが遅れたわけですよ。気づいたらもう、リプする前に、すでに来ちゃってるわけですよ。

しかも、ビール大好きなあのCakePHPの外人を連れて。

「いや〜、なんか見たことある外人が街を歩いてたから」

たいへんなことになってきました。

終電が近づいて地元の人が徐々に帰っていきますね。で、前泊してるPHPerは帰らなくてもいいわけですね。残ってるメンツがほぼ福岡以外のPHPerなわけです。さらに、店を出たらいつの間にか、海外からのゲスト参加のCakePHPコア開発者がもう一人増えてるんですよ。

前日からどんだけリッチな交流会ですかと。

二次会行きますね。完全に前夜祭ですね。残った焼酎ボトルとかテイクアウトしてますね。ロックすぎますね。

さらにさらに、まだ残ってくれてる貴重な地元の方に超美味いラーメン屋を教えてもらって、三次会まで行きます。時間は3:00AM。一部の人はもう一軒ラーメン屋行ったそうですが、おかしなことに、遠くなってしまったはずの自分のホテルの近くまで進出してきてたので、僕はホテルに戻りました。

レガシーコードのダウンロードと、BEAR.Sundayのmatsuriブランチのクローンをしなければなりません。

ちなみに、まだMatsuriは始まっていません。

始まる前からなんだこの濃さは。


三次会までいたのは、ある意味個人的には正解でした。そこで神レベルの豚骨に出会いましたからね。もうこれで、博多でやるべきマイミッションがひとつ達成されました。
まあ、このラーメン屋が、後々いろいろ重要になってきますが...

このあたりで、いったんエントリを分けることにしましょう。本編に続く。

HomebrewでPHP環境 現時点でのまとめ

MacでHomebrewを使ってPHPの開発環境を作るまとめです。

HomebrewはMacPortsより圧倒的にコンパクトなのがメリットです。MacPortsPHPをインストールすると、/opt/localに、Apacheを含め、すごい量のパッケージをインストールされます。PHPのビルドにApacheのライブラリが必要で、さらに、Apacheのビルドには...という具合。これだと、容量あたりの単価がかかるSSD搭載のMac bookがかわいそうですね。HomebrewのPHPは、MacOSApacheがあるのを知っているので、依存が浅くて軽いです。

MAMP.appがあるじゃないかという人はちょっと待った。あのパッケージ構造、httpd.confとphp.iniとmy.iniがどこにあるかすごくわかりにくいんですよね。そのうえ、使っている拡張の最新バージョン追従が個別にできないのは辛いです。

何よりHomebrewがいいのは、php54とphp53という個別のパッケージがあること。FuelPHPの仕事とBEAR.Sundayの趣味プロを同時にやりたいというとき、サクッと切り替えたり、php53を使っているときにphp54-xdebugのアップデートをしたり。

じゃあ、やり方いきますよ。

まずHomebrewのインストール

>Homebrew — MacPorts driving you to drink? Try Homebrew!

$ ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)"

/usr/local/binにbrewコマンドができるので、シェルでパスを通しておきましょう。パッケージに含まれるコマンドはここに入ってきます。

うまくいったか環境チェックするにはこう。

$ brew doctor

あ、ちなみに最新のXCodeが要るのでMac AppStoreで調達しておいてくださいね。

実はMacについてくるApacheにはPHP5.3が付いてきます。Homebrewは「Macに最初から入っているものは含まない」というポリシーを守っていて、PHPは既存ソフト扱いなんだそうです。でも、アップデートされないわ、バージョン固定だわ、Xdebugは使えないわ、MySQLのドライバ入ってないわ、なんてPHPは使いたくないですよね。

そんなある日(2012年の4月ごろだったかな)、HomebrewにTapという機能が導入されました。外部のFormula(パッケージの定義)集を追加/管理するコマンドです。

https://github.com/mxcl/homebrew/wiki/Homebrew-0.9

これでオリジナルのFormulaと混ぜることなく、GitHubにある外部のFormulaセットを追加することが可能になります。たったこれだけ。

$ brew tap homebrew/dupes
$ brew tap josegonzalez/homebrew-php

削除は brew untap コマンドです。

事前に homebrew/dupes を追加しているのは、その一部に homebrew-php が依存しているためです。

さてこれで準備OKなのでお待ちかねPHPをインストール。

まずはどんなインストールオプションがあるかを確認します。

$ brew options php53
--without-bz2
	Build without bz2 support
--with-tidy
	Include Tidy support
--with-fpm
	Enable building of the fpm SAPI executable (implies --without-apache)
--with-cgi
	Enable building of the CGI executable (implies --without-apache)
--with-gmp
	Include GMP support
--with-intl
	Include internationalization support
--with-unixodbc
	Include unixODBC support
--without-pear
	Build without PEAR
--with-mssql
	Include MSSQL-DB support
--with-mysql
	Include MySQL support
--with-suhosin
	Include Suhosin patch
--with-mariadb
	Include MariaDB support
--32-bit
	Build 32-bit only.
--with-homebrew-openssl
	Include OpenSSL support via Homebrew
--with-pgsql
	Include PostgreSQL support
--with-imap
	Include IMAP extension
--without-apache
	Build without shared Apache 2.0 Handler module
--with-libmysql
	Include (old-style) libmysql support

intlがないとSymfonyに怒られるのでオン、あと、MySQLPostgreSQLのドライバも入れましょう。

$ brew install php53 --with-intl --with-mysql --with-pgsql

まだMySQLPostgreSQLをインストールしていない場合、MySQLPostgreSQLのインストールが始まります。分けてやってもいいのですが、記事を書くのが面倒なので依存を一気に入れちゃおうと...

やってみたらドライバだけはインストールされましたが、MySQL等の本体は別途インストールしないとだめでした。勝手に依存を入れるわけではなくなったようです。

インストール中にいろいろメッセージが出てきますが、まあ、最初はスルーしておきましょう。最後に出てくるPHPの設定ガイドだけしっかり見て下さい。

For 10.5 and Apache:
    Apache needs to run in 32-bit mode. You can either force Apache to start
    in 32-bit mode or you can thin the Apache executable.

To enable PHP in Apache add the following to httpd.conf and restart Apache:
    LoadModule php5_module    /usr/local/Cellar/php53/5.3.16/libexec/apache2/libphp5.so

The php.ini file can be found in:
    /usr/local/etc/php/5.3/php.ini

☆☆☆☆ PEAR ☆☆☆☆

If pear complains about permissions, 'Fix' the default PEAR permissions and config:
    chmod -R ug+w /usr/local/Cellar/php53/5.3.16/lib/php
    pear config-set php_ini /usr/local/etc/php/5.3/php.ini

☆☆☆☆ Extensions ☆☆☆☆

If you are having issues with custom extension compiling, ensure that this php is
in your PATH:
    PATH="$(brew --prefix josegonzalez/php/php53)/bin:$PATH"

Extensions will never be compiled against this homebrew-php PHP. Please install them
using --with-homebrew-php to enable compiling against this php.

☆☆☆☆ FPM ☆☆☆☆

If you have installed the formula with --with-fpm, to launch php-fpm on startup:
    * If this is your first install:
        mkdir -p ~/Library/LaunchAgents
        cp /usr/local/Cellar/php53/5.3.16/homebrew-php.josegonzalez.php53.plist ~/Library/LaunchAgents/
        launchctl load -w ~/Library/LaunchAgents/homebrew-php.josegonzalez.php53.plist

    * If this is an upgrade and you already have the homebrew-php.josegonzalez.php53.plist loaded:
        launchctl unload -w ~/Library/LaunchAgents/homebrew-php.josegonzalez.php53.plist
        cp /usr/local/Cellar/php53/5.3.16/homebrew-php.josegonzalez.php53.plist ~/Library/LaunchAgents/
        launchctl load -w ~/Library/LaunchAgents/homebrew-php.josegonzalez.php53.plist

Mountain Lion comes with php-fpm pre-installed, to ensure you are using the brew version you need to make sure /usr/local/sbin is before /usr/sbin in your PATH:

  PATH="/usr/local/sbin:$PATH"

You may also need to edit the plist to use the correct "UserName".

Please note that the plist was called 'org.php-fpm.plist' in old versions
of this formula.

php.ini は /usr/local/etc/php/5.3/php.ini です。5.4 だとこれが php/5.4/php.ini になります。

Apache にロードするには /etc/apache2/httpd.conf あたりにこんな感じで追加します。Apacheは homebrew/dups でビルドしてもいいですね。今は簡単に MacOS の標準に入れておきましょう。

#LoadModule php5_module libexec/apache2/libphp5.so
LoadModule php5_module    /usr/local/Cellar/php53/5.3.16/libexec/apache2/libphp5.so

PEARを使うために、手動でこんな操作が必要らしいのでやっておきましょう。パーミッションが書き込みできないようになってて、pear がうまくいかないのです。忘れるとマジでハマります。

$ chmod -R ug+w /usr/local/Cellar/php53/5.3.16/lib/php
$ pear config-set php_ini /usr/local/etc/php/5.3/php.ini

え、こんなの全部憶えられない? って、エディタにコピーなんかしとかなくても大丈夫ですよ。コマンドでもう一度表示させることができるので、設定が済んだら忘れていいですよ。

$ brew info php53

ほら。

これで、MySQLPostgreSQLの設定も確認できます。一括でインストールして読み飛ばしてもいいよというのはそういう意味。

$ brew info mysql
$ brew info postgresql

Hello Worldやるぶんには使わないので、あとでこれ見て勝手にやっといてください。

$ php -r 'echo "Hello World\n";'

はいこんにちは。

あと、開発するなら必須な拡張をいくつかインストール。何はなくとも、XdebugとAPCは要りますよね。

$ brew install php53-xdebug --with-homebrew-php
$ brew install php53-apc --with-homebrew-php

おしりの --with-homebrew-php がポイントです。これを付けないと、MacOSのデフォルトのPHPをリンクしてしまったり、5.4用の拡張なのにカレントの5.3をリンクしたり、という現象が起こりかねません。これを指定することで、必ず、Homebrewのphp53をリンクするようになります。(php-build等で勝手インストールしたランタイムとリンクしたい人のために、デフォルトは遠慮してるそうです)

追記ここから

$ brew install php53-xdebug
$ brew install php53-apc

2012-10-08から、オプションの指定が逆になったようです。--without-homebrew-php で、homebrewのPHPをできるだけ避けてビルドするようにし、何も指定しなければhomebrewの対応するバージョンのPHPを使うのがデフォルトになっています。なのでオプションに注意しなくてもOKです。

ここまで

あ、ちなみにこれ、今日やっと正常に動作したホットな機能です。ここ修正されたのが、このエントリを書いてる動機です。

https://github.com/josegonzalez/homebrew-php/issues/151
https://github.com/josegonzalez/homebrew-php/issues/297

XdebugとAPCのインストールが済むと、便利なことに、/usr/local/etc/php/5.3/conf.d/ext-xdebug.ini と /usr/local/etc/php/5.3/conf.d/ext-apc.ini ができました。とりあえず初期設定のまま使うぶんには、 php.ini の修正はしなくていいです。

ふー、あともう一歩、PEARで開発に必須なものを入れます。

$ pear config-set auto_discover 1
$ pear install pear.phpunit.de/PHPUnit
$ pear install PhpDocumentor
$ pear install pear.phing.info/phing

まあこれぐらいあればまずはいいでしょう。パーミッションでハマらないように。

PEARでツールをインストールしたときは、もうひとつハマりどころがあります。インストールが成功してもすぐにはコマンドが使えないんですよね。Homebrewでインストールしたコマンドの正体は、/usr/local/binの中に置かれたシンボリックリンクなんですが、PEARを初めて使う前にもう、それ済んじゃってますよね。というわけで、シンボリックリンクを作り直します。

$ brew unlink php53
Unlinking /usr/local/Cellar/php53/5.3.16... ?? links removed
$ brew link php53
Linking /usr/local/Cellar/php53/5.3.16... ?? symlinks created

完了。phpunit も phing も使えるようになりました。

じゃあ、php54 も同じ要領でインストールしましょう。できますよね、3が4になるだけですよ。

〜時間がかかるのでこちらに出来上がったものがございます〜

5.3と5.4の切り替えは、Cellerに直接パスを通してやるのもいいけど、

# export PATH="$(brew --prefix josegonzalez/php/php53)/bin:$PATH"
export PATH="$(brew --prefix josegonzalez/php/php54)/bin:$PATH"

Homebrewのbinにあるリンクを再設定する方法だと、 .bash_profile を編集する必要もなくてラクラクです。

5.4 -> 5.3

$ brew unlink php54
$ brew link php53

5.3 -> 5.4

$ brew unlink php53
$ brew link php54

仕事中にこっそり裏でビルトインサーバとかBEAR.Sundayとかぐへへ...

そうそう、定期的にパッケージの更新は、やったほうがいいですよ。

$ brew update
$ brew outdated
$ brew upgrade

$ brew unlink php53; brew link php54
$ pear list-upgrades
$ pear upgrade

$ brew unlink php54; brew link php53
$ pear list-upgrades
$ pear upgrade