デジタル料理人

第4回Symfony2勉強会の個人的まとめ

(2011/06/06 更新)
色々情報を追加しました!だいたいすべてのスライドは網羅できていますー。

Contents(目次)

第1部 基礎編

第1部の基礎編は、各自PCを持ち寄って、手を動かしながらSymfony2を体験する形式でした!
(講師:上野さん(@uechoco))

スライド資料

[slideshare id=8203868&doc=symfony2workshop04basic-0-110604005802-phpapp02]

Symfony2について(概要)

利用する利点は?

Symfony2は1.4系より3倍早く、メモリ使用率は半分で済む!

なんでまだベータ版なの?

名前空間・・・

ここらへんでも参考にしてださい。

DI

・Dependency Injection
 →Javaで使われているデザインパターンの一つ(古くからある)

・DIコンテナ
 →依存性を注入する入れ物
  →外部の設定ファイルを読み込んで・・・
  →実行時に・・・
  →依存性を注入
  →(インスタンスや設定値を管理する)

・依存ってここではどんなことを?
 →クラス名や設定値がハードコーディング状態になっているような事を指している。
 →テストの時は別のクラスを用意しているのに、ハードコーディングしていると修正をしないといけなかったりするよね?

・DIコンテナのメリット
 →Lazy Load
 →テストしやすい
 →拡張しやすい

Symfony2の処理フロー

・Requestをサーバーに投げると・・・・
 →Symfony2がRequestオブジェクトを作って・・・
  →ごにょごにょして・・・
   →Responseオブジェクトを返却して・・・
    →表示!

・ごにょごにょって?
 →Kernel処理+URLのマッチング(ルーティング処理)

ワークショップで覚えたこと。

[slideshare id=8203864&doc=symfony2workshop04basic-1-110604005716-phpapp02]

なんか情報の粒度がバラバラですが、その時に感じたことなのでご勘弁。

web/app_dev.php

$kernel = new AppKernel(‘dev’, true);
Symfony2はAppKernelに環境名を与えることで動作を変えることができる。
app_dev.phpはdevモード、第2匹数はデバッグモードのONを表している。

$kernel->loadClassCache();
ソースのキャッシュを行って高速化を図っている。

$kernel->handle(Request::createFormGlobals())->send();
Symfony2は実行したあとResponseオブジェクトが帰ってくるので、それをsend()して処理を行っている。

Bundleの作成と登録

・バンドルの粒度
 →基本的に自由な粒度で作って構わない(例えばフロントエンドとバックエンドで分けるとか、アプリ機能レベルで分けるなど)
  →事例が少ないので、色々やって各自ベストプラクティスをさがしてください!

・Bundleの作成コマンド
 →Symfonyディレクトリで実行(配下にappが見える状態)

php app/console init:bundle "My\WorkshopBundle" src

作成したバンドルをAppKernelとローダーに登録する

・app/autoload.php

$loader->registerNamespaces(array(
    'Symfony'          => array(__DIR__.'/../vendor/symfony/src', __DIR__.'/../vendor/bundles'),
    'Sensio'           => __DIR__.'/../vendor/bundles',
    'JMS'              => __DIR__.'/../vendor/bundles',
    'Doctrine\\Common' => __DIR__.'/../vendor/doctrine-common/lib',
    'Doctrine\\DBAL'   => __DIR__.'/../vendor/doctrine-dbal/lib',
    'Doctrine'         => __DIR__.'/../vendor/doctrine/lib',
    'Monolog'          => __DIR__.'/../vendor/monolog/src',
    'Assetic'          => __DIR__.'/../vendor/assetic/src',
    'Metadata'         => __DIR__.'/../vendor/metadata/src',
    'Acme'             => __DIR__.'/../src',
    /* この下に以下1行を追加 */
    'My'               => __DIR__.'/../src',	// これが追加した行
));

・app/AppKernel.php

    public function registerBundles()
    {
        $bundles = array(
            new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
            new Symfony\Bundle\SecurityBundle\SecurityBundle(),
            new Symfony\Bundle\TwigBundle\TwigBundle(),
            new Symfony\Bundle\MonologBundle\MonologBundle(),
            new Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle(),
            new Symfony\Bundle\DoctrineBundle\DoctrineBundle(),
            new Symfony\Bundle\AsseticBundle\AsseticBundle(),
            new Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle(),
	    new JMS\SecurityExtraBundle\JMSSecurityExtraBundle(),
	    /* この下に以下1行を追加 */
	    new My\WorkshopBundle\MyWorkshopBundle()	// これが追加した行
        );

        if (in_array($this->getEnvironment(), array('dev', 'test'))) {
            $bundles[] = new Acme\DemoBundle\AcmeDemoBundle();
            $bundles[] = new Symfony\Bundle\WebProfilerBundle\WebProfilerBundle();
            $bundles[] = new Symfony\Bundle\WebConfiguratorBundle\SymfonyWebConfiguratorBundle();
        }

        return $bundles;
    }

ルーティングへ登録

・app/config/routing.yml

workshop:
        prefix: /workshop
        resource: "@MyWorkshopBundle/Resources/config/routing.yml"
Twigについて

・テンプレート出力時に{{value|raw}}とかけばHTMLエスケープはされない
・テンプレートが継承できるのが特徴
 →Symfony内でもすでにベースから継承されている。
   →継承はPHPの継承と同じ感じでできる(変数の再設定など)

感想

とりあえずBundleの作成と登録、Twigを使ってページ表示までがワークショップで行ったところです。

事前にブログチュートリアルあたりを触っていたので、そこまで戸惑うことなく出来てよかったですね。
でもやっぱりSymfonyらしいなぁと思うのはページ作成までに時間がかかるところ。
単純にinit:bundleしただけではコード生成までで、それを登録するために3ファイルを更新するというのは、良し悪しかなと思いますねー。

個人的にはテンプレートエンジンTwigの威力に驚きました!
継承ができるテンプレートってどういうことだ?と思ってたんですが、単純にテンプレートを複数に分けるより強力でした。
これで速度がそこまで変わらないのであれば、使いやすいテンプレートエンジンだなぁと思います。
Smarty3もいいですけどね。両方いいところがありそうです。

あと、これよりもっと深いチュートリアルはユーザー会のページがいい感じです。
(下にURLがあります。)

なんか関連がありそうなURLたち

Symfony2を読み解くためのキーワード & Behat入門

[slideshare id=8204454&doc=symfony2-behat-bdd-4-110604023813-phpapp01]

はじめに・・・読み解くためのキーワード

 →これはSymfony2に限った概念ではない。Software全般の概念。

今日から始めるBDD(Symfony2編)

はじめに

今日はWebアプリケーションのテスト駆動開発入門の話です。

テスト書いていますか!?

・そもそもテスト開発手法におけるテストとは?
 →テスト駆動開発のテスト
  →こっちだよ!
 →ソフトウェア品質テストのテスト(いわゆるQA)
  →今日はこっちの話ではないです。
  
・テスト駆動開発のテスト=開発手法の視点
・ソフトウェア品質テストのテスト=品質管理の視点

・TDDについてもっと知りたい場合・・・・
  →テスト駆動開発入門(Kent Beck)を読むといいよ。

ところで駆動って何!?Driven?

・開発のためにテスト書くなんて面倒なんじゃ・・・?
  →そこでBehat!

■Behatの特徴
・自然言語に近い構文
 →英語がわからなくても書ける。
・組み込みステップ
 →Webテスト系をスムーズに記述可能
・テスト内容が分かりやすい
 →メンテナンス性が高い

 

BDDについて

・BDD=振る舞い舞駆動開発
 →PHPUnitでもBDDはできる
・BehatのBDDは「シナリオBDD」である
 →最大の違いは「読みやすいDSLによるテストの記述と実行」にある!
  →ユビキタス言語との親和性

Behatについて
フィーチャ: ボウリングをプレイする

シナリオ:スペアがある場合は得点が加算される
  もし プレイヤーが5ピン倒す
  かつ プレイヤーが5ピン倒す
  かつ プレイヤーが3ピン倒す
 ならば スコアが16であること
ステップの種類

・組み込みステップ
・カスタムステップ
 →独自のルールで実行できる。
  behat:test:bundle –steps バンドル(–lang=jaにすれば日本語)

・ステップの一覧(=レシピ)を見ながらざっくりとしたシナリオを記述していける。
 (Webアプリケーションの場合)

・組み込みステップの場所はMink内にある。
  →カスタムステップを作る際にはここを参考にする

テストファーストについて

結論:慣れろ!慣れるしかない!

・まずはテストを書くことになれる
 →例)Echoデバッグをテストコードで行う。
・テストファーストは「スキル」。できるようになっておくべし。

Behatを応用して

 ・Redmineなどのチケットに対してフィーチャーを書く。
   →通るまで頑張る

 

質問

 ・日本語のLanguageファイルはデフォルトで用意されている?
   →用意されています。
    →Cucumberと同じ?
     →若干英語が変わっているので、少し違います。

感想

BDDは個人的にも気になっていたテスト方法だったので、参考になりました!
javascriptではjasmineというのがBDDフレームワークなんですが、
BehatはそれのPHP版というところでしょうか。Symfony使うならこれを使ってみたいですねー。

テストコードが日本語であることで、テストコードを俯瞰してみた時の分かりやすさは格段と違うなぁ。

Symfony2のフォームフレームワーク

[slideshare id=8203873&doc=random-110604005907-phpapp02]

フォームフレームワークとは

入力フォームとオブジェクトをマッピングするためのフレームワーク

Symfony1.x系のフォーム
  • 入力データのマッピング・バリデーション・データベースへの保存を行う
  • DoctrineなどORMごとにFormクラスの拡張が用意されている。
  • Formが複雑になると極端に扱いづらくなる
Symfony2のフォーム
  • Formコンポーネントとして提供
  • 入力データのマッピングのみを行う
  • バリデーションなどは別コンポーネントで行う
  • ORMに関係なく、どんなオブジェクトでもOK。

Formコンポーネント

・コンポーネント格納場所:vendor/symfony/src/Component/Form/

・作成したいフォームごとにAbstractTypeを継承したクラスを作成する。
 →クラス内に buildForm(FormBuilerインスタンス、オプション配列)を書く。
  インスタンスにフォームの要素をadd()する。
   →フォームがすべてこれで完成する。
・フォームタイプすでにかなりの量が提供されている。

・FormFactory:FormBuilderからFormオブジェクトを作成するときに、依存などを解決するために存在。
・Formのレンダリング:createView()を呼び出して、FormViewオブジェクトをViewにrender()で渡すことでレンダリングしている。

Validatorコンポーネント

■FormTypeGuesser
 →DoctorineやValidatorのマッピング情報から動的にFormTypeを判別する。
  →例えばValidatonにEmailを指定すれば、勝手にEmailTypeが選択される

■DataTransformer
 →オブジェクトのデータをフォームに出力する際とその逆の時にデータの変換を行う。
  →例えばTrue/falseを”1″ or “” に変換するなど(ロジック側ではBoolだけど、View側は0/1)

■FormTypeの継承
 →FormTypeにGetParent()を実装して親となるFormTypeを返すことで継承可能となる。

複雑なフォームの扱い方

・EmbedFormを使う(Formオブジェクトの中に別のFormオブジェクトを組み込む機能)
・注意として、Formの定義とオブジェクトの定義が一致していないとマッピングはできない。
 →オブジェクトは何でもいいので、複雑なフォームの場合はデータを受け取るオブジェクトを専用に用意して、それに対してValidationを作ればOK。

まとめ

質問

・エラー文言を日本語にしたり、表示のカスタマイズとかしたい
・バリデーションの管理はyamlでやるの基本は?
 →annotationとかもあるんだけど、yamlが一番ベストプラクティスだと思います。
・バッチ処理とかはForm使わないけど、Validatorは使いたい。できる?
 →できます。Validator単体利用可能。

感想

すんません、あんまりSymfony今まで触ったことなかったんで正直きちんと理解は出来なかったです・・・(汗
でも、Formが使いやすくなったというのは認識。Webアプリケーションはフォーム必須ですからねぇ。
CakePHPを触ったりしていたから、オブジェクトを渡して処理する流れが新鮮・・・。

PHPマイクロフレームワーク Silex

[slideshare id=8204780&doc=silex-bigenner-110604032757-phpapp02]

□Silexを使いたくなる8つのポイントをご紹介。

その1:Silexを理解すればSymfony2を理解できる!

・Microframework
 →RubyのSinatoraから派生しているフレームワークの一種
  →ほぼ派生フレームワークはすべて同じような記述方法なので、1個覚えれば他にも使えるよ
・Silex=火打石の事。
・たったの8行でWebアプリが出来る!
 →Require
 →Newする
 →ルーティングを決める
 →Run()する。

Symfony2を覚えるためにはSilexを使うといいよ!
 →SilexはSymfony2のコンポーネントだから。

・ほぼすべてが共通
 →ClassLoader
 →HttpFoundation(Webアプリの基本、Request,Response)
 →HttpKernel(フレームワークの中枢)
 →Routing
 →EventDispatcher

その2:方向性がはっきりしている!

・全部同じだったらSymfonyと同じでは・・・?
 →CLIのツールは作るつもりはない
 →CLIに必要なものを生成するような機能も作るつもりはない
 →XMLやYAMLなど外部設定fがいるを必須とするような機能も作るつもりはない
 →PHPっぽくない機能も使わない
 →多くのコードを追加して実装するような機能も作るつもりはない

その3:PHP5.3をフル活用しています

・逆に言うとPHP5.3を理解していないと面白みも理解出来ないかも。
 →PHAR(PHP5.2以降)※読みは「ふぁー」らしい。
 →名前空間
 →無名関数(closure)

・PHAR
 →PHARアーカイブは複数のファイルをひとつにまとめるための便利な仕組み。
 →ライブラリはPHARを読みこむだけ

require_once __DIR__.'/silex.phar';
#Silexのバージョン確認
php silex.pear version

#Silex自身のアップデート処理
php silex.phar update

updateはサーバーに問い合わせて自分自身のバージョンを勝手に上書き更新する。
ただし!
 ・–enable-zend-multibyteが入っていると真っ白。
 ・PHPのバージョンによってはPhar−Stubにバグがあるとか

・ルーティングに一致する処理は無名関数で記述

その4:Silexのアプリケーション自身が無名関数を利用したDIコンテナ

・$app = new Silex\Application();
 →詳しくはPIMPLE(無名関数を使ったマイクロDIコンテナ)を見るといいよ(Fabienさん謹製)

・$app[“key”] に値を指定すれば使えるよ。

・共有オブジェクト

$app['some_service'] = $app->share(function(){
  return new Service();
  });

 →何回よばれても同じServiceインスタンスを呼び出せる。

・ルーティングごとに処理を実装

$app->get("/hello/{name}",function($name){
   //
 }
 // useを使うと自分自身を受け取れる
 $app->post("/hello",funtion() use ($app){
    $name = $app['request']->get('name');
    return 'Hello '.$name;
}

・assert()はパラメーターの条件を定義する
 ->assert(‘id’,’\d+’);
・value()はパラメーターのデフォルト値
 ->value(‘id’,1);

・パラメーターを変換
 →convert()
  ex: ->convert(‘id’,function($id){return (int)$id;});

その5:Extensionできる

・追加機能をExtensionで拡張可能。
・register()で登録すればOK。
・標準のExtensionでDoctrine(ORMではなく、DBAだけ)やTwig、Validatorなどなどもうすでにある。
・非公式のエクステンションはもっといっぱいあるよ!
 →mongo接続とかもある。

・TwigのExtensionを追加する場合・・・

register(new TwigExtension(),array(
  'twig.path' => __DIR__.'/views',
  'twig.class_path' => __DIR__.'/vendor/twig/xxx'
));

→$app[‘twig’] はTwigオブジェクト自身になるよ

その6:アプリの外部ファイル化

・アプリケーションの実行ファイルを複数に分けることもできる。
 →外部ファイルの最後はrun()じゃなくて、$appを返すようにする!
・index.phpには$app->mount(‘/hoge’,$blog/*とってきたインスタンス名*/)をする

その7:使いやすい日本語ドキュメント!

・Silex ユーザーガイド(http://silex-users-jp.phper.jp/)
 →CodeIgniterのユーザーガイドをオマージュ。

その8:簡単にTDDを体感できます。

・PHPUnitで書かれたコア機能、テストコードを実行できます。(Fabienさんなので、テストは抜かりない)

質問

・プロダクションレベルでも使える?
 →使えると思います。すでにリードデベロッパーのFabienが「もう必要な機能はすべて揃った」と言っているし・・・。
  →コア機能の変更はもうもはやないと思いますよ。

感想

個人的には今回一番惹かれた話でしたねー。簡単なアプリとか作るならこれで十分な気がします。
Extensionもありますし、自分でExtensionも簡単に書けると話していました。
RubyとかPerlのマイクロフレームワーク触ってみたかったけどPHPでイイのないなぁと思ってたんでナイスタイミング!
個人的にはこのマイクロフレームワークとjavascirptを使って簡単に開発できるようになるんじゃねぇか思ってます。
(もしくはサンプル・モック作成に使えそう)

Symfony2 でよりよいソフトウェアを作るために

[slideshare id=8228893&doc=symfony2-110606213252-phpapp01]

■Piece Framework
 ・PHPのアプリケーションフレームワーク(OSS)
  →TestRunnerやAPPフレームワーク、MakeGoodを提供

□良いソフトウェアとは?

・”ソフトウェアの核心はドメインに関係した問題をユーザーのために解決する能力である。”
 (エリック・エヴァンスのドメイン駆動設計)

・”Build you App,not your Tools.” (The Symfony2 Book)

【Symfony2の特徴 by @iteman】
・バンドル
・Configuration
・サービスコンテナ(DIコンテナ)
・機能テスト
 などなど・・・

■バンドル
 ・モジュールシステムの構成単位(Symfony2の世界における)
 ・Featureの提供単位
 ・クラス、コントローラー、Webリソースなどを束ねたもの
 ・外部モジュールとの統合レイヤ
  (例えば単体のDoctorineをまとめるためのものとして)
 ・セマンティックコンフィグレーションの提供
 ・他のバンドル拡張の提供
  (例えばテンプレートエンジンにTwig/Smarty/PHPの機能を付与する)
 ・自身のバンドルの拡張ポイントの提供
  (これをDIコンテナが実現している)

■既存のモジュールシステムを考えてみる

・PEARパッケージ
・Phar
・Debianパッケージ
・OSGiバンドル(Eclipse機能拡張の仕組み)などなど・・・

たくさんのモジュールシステムが存在。すべて似ているようで似ていないようで。
(PEARは依存関係を定義できる、Pharはまとめただけ、DebianはWebサーバなどの機能抽象化)

■バンドル設計の原則

・高い凝集度と低い結合度
 →一般的なモジュール設計の原則

・パッケージ設計の原則
 →アジャイルソフトウェア開発の奥義にもある「再利用、リリース等価」などの6つの原則
・ドメインの概念
 →ドメイン設計に記述してある

■サービスコンテナ(Dependency Injection)
 ・依存関係の逆転の原則(アジャイルソフトウェア開発の奥義より)
 ・コンポーネント間の疎結合化
 ・テスタビリティの工場
 ・コンポーネント構成知識の保存と可視化

【依存関係の逆転】
・Client→Server
 Clientに依存している。

・Client←Server Interface→Server
 インターフェースを提供することでClientとの依存関係は逆転する
 
【セマンティックコンフィグレーション】
 →yamlなどで簡単に設定できるコンフィグレーションファイル

【ドメイン特化言語】
・DSL
・問題空間の言語
・ドメインに特化した記法を持つ言語
 ・コンフィギュレーションDSL:YAML
 ・式DSL、グラフィカルDSL
  →言語ワークベンチ
  →Lexer/Parser Generators
  
【テスト】
・テストの対象
 →ユーザーから見たWebアプリの機能
 →機能に対するユースケースの粒度
  →ルーティングやページフロー、入力・出力、バリデーションなど。
 
【独立したドメインオブジェクト】
・Pure PHPオブジェクト
・バリデーションやORMからの高い独立性が保たれている。(Symfonyは依存性がない)
  →フレームワークからの影響を最小化

☆なぜフレームワークを使うのか?
 →Symfony2の動作に振り回されることなく、ソフトウェアの核心だけを作れるようになるので。
  =ドメイン駆動設計

■ドメイン駆動設計の要点

・ドメインモデルは、ドメイン知識を深めながら反復的に進化させていく。
・ドメインモデルが開発者とドメイン知識を持つ人(専門家)とのあいだの共通言語となるようにする
 →ユビキタス言語(利用者と開発者が同じワードでやり取りする)
  http://capsctrl.que.jp/kdmsnr/wiki/bliki/?UbiquitousLanguage
  
  
■ドメイン駆動設計を行うには?
 →アジャイルプロセス
 →テスト駆動開発
 →SOLID(単一責任の原則とかとか・・・)
 →ビヘイビア駆動開発
 →リファクタリング
 →オブジェクト指向、アスペクト指向
 →関数プログラミング、メタプログラミング・・・・
 

■まとめ
DDD+TDD=アメージング!

感想

Symfonyとかフレームワーク、言語という次元の話ではない「ドメイン駆動設計」というおはなしでした。
正直勉強不足だ・・・!とかなり痛感。「良いソフトウェアとは?」という問いは深いですね。
とりあえず、「Symfony2に振り回されるのは@fivestrだけで十分」という事はわかりました(笑)
あと、DDD+TDD=アメージング!

LTまとめ

LTはタイトルと資料をまとめておきます。

はじめてのSymfony2(@Kiskeさん)
資料:http://www.slideshare.net/tmitsu/symfony2-8203825
Symfony2でMongoDBと仲良くする方法(@madapajaさん)
資料
PHPUnitのMockObjectの紹介(@hnwさん)
資料:http://www.slideshare.net/hnw/phpunitmockobject-8203941
モテるPHP女子力を磨くための4つの心得「Symfony1.4を使えない女をアピールせよ」(@yuchimiriさん)
資料:http://www.slideshare.net/yuchimiri/php4-symfony14

他の方々まとめ

他の参加者の方々もまとめを書いています!#symfony2studyで見つけたものをここに書いておきます。

写真

@HIROCASTさんが写真をFacebookにあげてありましたので、ここにURL置いておきます。
バッチリ写ってるのは気にしない・・・!

第4回Symfony2勉強会

参加してみた感想。

まずは運営した日本Symfonyユーザー会の皆さんお疲れ様でした!楽しかったです!
初めて懇親会とかまさかその後のMidnightまで参加することになるとは思わなかった(笑)
でも参加してみてよかったなぁと思いました。

まず、自分の技術力の無さを再確認したところですね。上を見ればいろんな人たちがいっぱいいるなぁと。
スゴイ人達がどんなことを今考えているんだろう?という事が聞けたりして面白かったです!

はじめてLTとかセッションで話してる人たちと話できたなぁ。凄い刺激になりました。
お昼はひょんなことから@itemanさんとご飯食べながら話できましたし、よかった!

なんだろ、純粋にプログラミングであったり、設計であったり、いわゆる「開発」という行為が好きな人たちが集まると
話もすごい面白いですねー。深夜までそんな話が出来るとは思わなかった(笑)

やっぱりみんな「意欲」がすごかった。開発者って「意欲」が無いとダメだと思うんですよね。
より良くしていこう!みたいな気持ちが無いと、フレームワークもできないし、オープンソースなんて文化はできないし。
そういう所に携われるようになれたらいいなぁと思いました。

とりあえず、しばらくはsilexを使って色々なんかできないかなー思ってます。
お話させてもらった、@_nishigoriさんとか@madapajaさん@shishi4twさんなどなどいっぱい居すぎて書けない・・・!
ありがとーございましたー。

もっと勉強して他の勉強会参加しよっと!

モバイルバージョンを終了