Symfony2 と戯れてみた (その1)

Symfony2はsandbox版が配布されていますが、実際に自分でアプリケーションやバンドルを作成するにはどうするのか試してみました。
sandboxをとってきて試すだけであればhttp://symfony-reloaded.org/codeからどうぞ。以下はGitHubからソースコードを取得し、コマンドを使って雛形まで作ってみます。

ただし、公式のマニュアルにはこれらの手順については何も書かれていませんのであくまでも私が推測で試した結果です。また動きが怪しかったりしてますが、まだプレビュー版ですので安定していないかったりバグがあるのはよくあることです。この点をご理解の上お読みください。_(_ _)_

Symfony2のソースをとってくる

ここではGitHubからcloneしてきます。symfony-sandoxをclonseしてきます。
symfonyそのもののリポジトリもありますが、sandboxに比べてファイルがインストーラーのファイルなどが足らないようで、コアな部分のみで構成されているようですね。

$ cd /usr/local/src
$ git clone git://github.com/symfony/symfony-sandbox.git sf2.git
$ cd sf2.git
$ ls
LICENSE	README create_sandbox.sh hello src web

helloはサンプルのアプリケーション、srcは実際のソース群、webはwebサーバーで公開するディレクトリになります。

mydemoアプリケーションを作成する

symfonyコマンドはSymfony2では src/vendor/symfony/src/Symfony/Framework/WebBundle/Resource/bin/symfony.phpにありました。
なので、init:applicationでmydemoアプリケーションを作成します。まずはhelpでコマンドを確認してみます。

$ php src/vendor/symfony/src/Symfony/Framework/WebBundle/Resources/bin/symfony.php help init:application
Usage:
 Symfony init:application [--yaml] name path web_path

Arguments:
 name      The application name
 path      The path to the application
 web_path  The path to the public web root

Options:
 --yaml Use YAML for configuration files

pathはアプリケーションを作成するパス、web_pathは公開ディレクトリを指定するようです。もともと用意されているhelloアプリケーションと同じ場所にmydemoを作成し、webディレクトリは同じ場所にするので、基底となるディレクトリで以下のように実行しました。

$ pwd
/usr/local/src/sf2.git
$ php src/vendor/symfony/src/Symfony/Framework/WebBundle/Resources/bin/symfony.php init:application mydemo ./mydemo ./web

これでmydemoアプリケーションのディレクトリとwebディレクトリにコントローラーが作成されました。

$ tree mydemo
mydemo
|-- cache
|-- config
|   |-- config.xml
|   |-- config_dev.xml
|   |-- config_prod.xml
|   `-- routing.xml
|-- console
|-- logs
`-- mydemoKernel.php

$ tree web
web
|-- check.php
|-- index.php
|-- index_dev.php
|-- mydemo.php
`-- mydemo_dev.php

設定ファイルがxmlになっています。さきほどのinit:applicaitonで--yamlを指定すればyaml形式で設定ファイルができるのですが、この後の作業で何故かエラーになります。まぁまだ開発中ですし。

追記: 「XML形式を推奨している」ということでは無いと思います。xmlでもyamlでも同じように設定が行えるようになる予定です。ORMでDoctrineとPropelを使えるのと同じことだと推測しています。

とりえあずこのアプリケーションにアクセスしてみます。まずは、もともとあるapacheでwebディレクトリが表示できるようにシンボリックリンクを貼りました。ローカル環境はmacで、公開ディレクトリはホームディレクトリ直下のSitesだったので以下のように実行。

$ ln -s /usr/local/src/sf2.git/web $HOME/Sites/sf2


あとは、ブラウザでアクセスすると無事Congratulationの画面が!

また、アプリケーションを作るために使ったinit:applicationコマンドですが、パスを指定できるといっても現在のところ完全に自分の好きな場所に作成しても動きません。相対パスが指定されている箇所があってそこでエラーになります。もちろん、パスを直せば大丈夫ですが面倒なので今回は素直に動く場所にインストールしました。

mydemoのバンドルを作成する

Symfony2からはプラグインやモジュールなどはバンドルと呼ばれる単位になるようです。
次にmydemoのバンドルを作ります。さきほど作成されたmydemoディレクトリにmydemo用にconsoleファイルがあるので、このファイルを通してコマンドを実行するようです。引数でバンドルを作成するnamespaceを指定します。
sandboxのルールと同じで./src/Bundle/MydemoBundleという場所に作成したいのでBundle\MydemoBundleと指定します。

$ php ./mydemo/console init:bundle "Bundle\MydemoBundle"

これで、以下のファイルが作成されました。

$ tree src/Bundle/MydemoBundle
src/Bundle/MydemoBundle
|-- Bundle.php
|-- Controller
|   `-- DefaultController.php
|-- Model
`-- Resources
    |-- config
    |   `-- routing.xml
    `-- views
        `-- Default
            `-- index.php

このようにアプリケーションのディレクトリと別のディレクトリにバンドルを作成するのは、プラグインなどのように複数のアプリケーションでバンドルを共有したい場合などを考慮してのことだと思います。実際に各アプリケーションごとに利用するバンドルを複数指定できます。

今回のmydemoアプリケーションが作成したバンドルを利用できるように登録しておきます。

$ vim mydemo/mydemoKernel.php
<?php
  public function registerBundles()
  {
    return array(
      new Symfony\Foundation\Bundle\KernelBundle(),
      new Symfony\Framework\WebBundle\Bundle(),

      // enable third-party bundles
      new Symfony\Framework\ZendBundle\Bundle(),
      new Symfony\Framework\DoctrineBundle\Bundle(),
      new Symfony\Framework\SwiftmailerBundle\Bundle(),

      // register your bundles here
      new Bundle\MydemoBundle\Bundle(), // 追加
    );
  }

次にバンドルのルーティングを変更します。アプリケーションディレクトリのconfig/routing.xmlになります。
ここでWebBundleを参照しているのを先ほど作成したMydemoBundleに変更します。

$ vim mydemo/config/routing.xml
  <route id="homepage" pattern="/">
    <default key="_bundle">MydemoBundle</default>
    <default key="_controller">Default</default>
    <default key="_action">index</default>
  </route>

これで再度アクセスします。


おー。ちゃんとルーティングが変更されましたね。

感想

やはりというかsymfony1系とは全くの別モノです。アプリケーションごとにKernelが存在しBundleを変更することでコアでもバンドル(プラグイン)でも何でも拡張できます。
そして、バンドル単位で作成することで再利用性は格段に向上しました。なぜなら普通に作成したバンドルは他のアプリケーションでもそのまま登録すれば利用できるからです。
つまり、意識しなくてもプラグインを常に開発するというイメージでしょうか。symfony1系やCakePHPのように"拡張のためにプラグインで作る"必要がないということですね。
こういった点からもバンドルという概念を理解することが第一歩のようです。