こんにちは、小俣です。Symfony1.4にはだいぶ慣れてきた今日この頃、近々登場するらしいSymfony2が速いとかすごいとか噂されているので、乗り遅れないよう情報を仕入れておかねば!ということで、先日ちょうど弊社オフィスを会場に開催されたSymfony2勉強会に参加してみました。そのとき仕入れた情報をご紹介しようと思います。
はじめに:Symfony2は1.x系と内部構造が異なるので戸惑う
Symfony1.xに慣れている方にとっては、初めのうちはディレクトリ構造が違いすぎて何処に何があるのか混乱しがちです。私も何度も迷子になりました。少しずつ慣れていくしかありませんが。。。下記にSymfony2の特徴をいくつか紹介してみます。
Symfony2はすべてBundleで構成されている
Symfony2では、新しい概念がいくつか導入されていて、まずはBundle(直訳:束)の理解が必要です。Bundleとはそれ自体が1つのfeature(機能)を成していて、HogeBundleディレクトリにはHogeBundle.phpとController(/HogeController.php)とResources(/configと/views)とTestsがあります。configではroutingの設定ができ、viewsにはテンプレートを置きます。このようにBundleごとにソースがまとまっているため、機能を追加したり削除するときにBundleごと追加したり削除すればよいので、どの機能があるのかないのか視覚的に分かりやすく、また友達とBundleをshareするのも簡単!とのことです。
routingやlayoutをBundleごとにカスタマイズできる
app/views/layout.phpをBundle内のlayout.phpで継承しているので、Bundleごとにlayoutに違いを出したりするときに便利のようです。また、routingもBundleごとに設定できるようになっています。
DIコンテナを理解せずしてSymfony2の内部構造は理解できない
Symfony2では、DIコンテナ(Dependency Injection Container)が非常に重要な役割を果たしていて、シンプルなYAMLやXMLで設定できるコンフィグレーションシステムの裏には、すごい内部構造が隠されているようです。典型的なプロジェクトにおいては、DIコンテナには触ることはないでしょうとドキュメントに書いてありますが、知っておいた方がExtensionを扱うときにスムーズのようです。
それ以外のSynfony1.xからの変更点や違いについては、勉強会でLTもされていたアシアル小川さんの記事をご参照ください。
Symfony2を動かしてみよう
まず、Symfony2を動かすには、PHP5.3.2以上が必要です。その準備ができたらhttps://github.com/symfony/symfony-sandboxからSymfony2のsandboxをゲットし、cacheとlogsの権限を777に変えて、ブラウザからアクセスできるようにします(Apacheで公開するなど)。そこまでできたらsandbox/web/check.phpで動作環境のチェックもしておきましょう。
※ちなみに以下のレッスンの内容は、ワークショップで行われた内容を元に、自分でいろいろ内容を変えてしまっていますので参考程度にしてください。
レッスン1:HelloBundleのHelloControllerにtestActionを追加してみよう
まず、あらかじめ用意されているHelloBundleがどこかというと
sandbox/src/Application/HelloBundle
その中に
HelloBundle/
└ Controller/
└ HelloController.php
└ HelloBundle.php
└ Resources/
└ config/
└ routing.yml(設定により.xml .phpも可)
└ views/
└ layout.php(設定により.twigも可)
└ Hello/
└ index.php(設定により.twigも可)
└ Tests/
└ Controller/
└ HelloControllerTest.php
があります。
これをこのまま動かすと、app.php/hello/hogeだと「Hello hoge!」と表示されます。
ではまず、HelloController.phpを下記にように変更します(testAction追加と同時に、indexActionから$nameを取り除いています)。
# HelloController.php
public function indexAction()
{
return $this->render('HelloBundle:Hello:index.php');
}
public function testAction()
{
return $this->render('HelloBundle:Hello:test.php', array('time' => date('H:i:s')));
}
続いて下記のようにテンプレートを追加します。
# views/Hello/test.php
ただいまの時刻:<?php echo $time ?>
そして最後にrouting追加。
# config/routing.yml
test:
pattern: /hello/test
defaults: { _controller: HelloBundle:Hello:test }
hello:
pattern: /hello ← /:nameを外しました
defaults: { _controller: HelloBundle:Hello:index }
app_dev.php/Hello/test(dev)
app.php/Hello/test(prod)
で表示の確認をしてみてください。
「ただいまの時刻:H:i:s」と表示される単純なものです。
devで見てみると、デバッグツールバーが表示されています。その説明はしないのですが、いろいろいじってみてください。
ちなみにドキュメントによると、単純なテンプレートでは$this->render()よりも$this->createResponse();を使うことで数ミリ秒の時間をセーブできるとのこと。
レッスン2:共通メニューを作って、layoutに入れてみよう
ダミーの共通メニューを作って、layoutに入れてみます。
# views/menu.php
メニュー1<br />
メニュー2<br />
メニュー3<br />
を作って、layout.phpで
# views/layout.php
<?php echo $view->render('HelloBundle::menu.php') ?>
を追記します。
これでメニューが表示されるようになります。
レッスン3:テンプレート側から指定アクションの結果を引いて表示してみよう
テンプレートで、別アクションの結果を表示することができるんです!これは便利じゃないでしょうか。
# views/Hello/index.php
<?php $name ?> ← $nameを使ってないので削除
<?php echo $view['actions']->render('HelloBundle:Hello:test') ?> 追記
これで、Hello/testの結果がHello/indexでも表示されます。
レッスン4:Edge Side Includes を試してみよう
ESI(Edge Side Includes)は、簡単に言うとWEBページをパーツごとにキャッシュして、更新が必要な箇所だけキャッシュの更新ができる技術です。これによりWebコンテンツ配信の高速化が可能になるとのことで、Symfony2もそれに対応しています。
これを使うと、レイアウト部分のキャッシュは30分毎に更新、コンテンツ部分のキャッシュは3秒毎に更新、という風にキャッシュの更新頻度を分けられる!とのことで、ワクワクしながら私も試してみたのですが、残念なことに私の環境ではうまくいかなかったので、皆さん頑張ってみてください!
ちなみに、$this->render()の結果をすぐにreturnせずに、キャッシュ制御してから返すようにします。
# HelloController.php
$response = $this->render('HelloBundle:Hello:index.php');
$response->setSharedMaxAge(30); ←ここでキャッシュ制御
return $response;
また、AppKernelをAppCacheでラップしたり、テンプレートでの書き方も変えたりする必要があるのですが、その辺の細かい
設定方法などの詳細はスライドとドキュメントをご参照ください。
最後に
最後に余談となりますが、勉強会に行くのが初めてでドキドキの私でしたが、隣に座っていた@uechocoさんがいろいろ優しく教えてくれたので、安心して参加できました。その節はありがとうございました。
ちなみに、この勉強会に参加されてた@chobi_eさんが今、同じチームの仲間となって働いているんです!これをご覧になっている方で、ソーシャルアプリにご興味ある方は、ぜひ一緒に働きましょ〜。
第1回 Symfony2 勉強会レポート