Home > PHP

SymfonyでHello world!を作ってみる

2011.11.17 1:29
 伝統的に「Hello World!」ということになってしまいますが。Symfonyもやはりそれでもって学習するのがいかと思います。ここでやるべきことは、意味はとにかくよくわからないまでもひと通り体験しておくべきものとして、
  • バンドルの作成と設定
  • ルーティングの設定
  • コントローラーの設定
  • URLアクセス
ということになります。
 概念的な話でいいますと、
  • バンドル=モジュールの作成
  • ルーティング=行き先とパスの作成
  • コントローラー=入力->出力
です。

バンドルとは?

 Symfonyフレームワークのその中核はこのバンドルにあります。フレームワークがフレームワークとして機能するときその内容のコアはこのバンドルで作成します。アプリの5W1H は、ここで作成されます。というのは、このバンドルという概念はいわゆるモジュールやプラグインという概念にほぼ等しいということです。国際宇宙ステーションと同様に、それだけで最低限機能する宇宙ステーションの柱となるエネルギーの供給と通路。これが宇宙ステーションの本体でありフレームワークです。しかしそれだけでは勿論ステーションとしての機能がなされないので、モジュールを追加してゆきます。生活のための住居モジュール、宇宙で様々な実験をするための実験施設ノジュール、ステーションで働く人の健康管理をするための病院モジュール、そんなものがその最低限の宇宙ステーションに随時組み込まれて大きくなります。Symfonyも同様に、バンドル=モジュールを追加してゆくことによって大きくなります。1つの機能を付け加える際にバンドルを1つ作るということになります。

バンドルの作成

 ここでは、Hello World!をやってみます。なぜなら初心者はHello worldに決まっているからです。
 バンドルを作るのはコマンド一発なので簡単です。以下のコマンドを実行するだけです。しかし、予めSymfonyのあるディレクトリに移動しておく必要があるかもしれません。
$ php app/console generate:bundle --namespace=Acme/HelloBundle --format=yml
コマンドを実行するとYESだのNOだのいろいろ聞いてくるのですが、全部ENTERでもってそのまま突き進んでください。Symfonyは何も答えなくともきちんと処理してくれます。しかしフレームワークなのでルールがあります。
$ php app/console generate:bundle --namespace=<名前空間>/<バンドル名> --format=<フォーマットタイプ>
というルールになっています。
 名前空間は知っての通りバンドル機能を1つの塊として名前空間で分けます。これは自分が欲する機能別に名前空間を指定することができることを意味していると同時に、実際にディレクトリ別にコードを分割することで実装します。
 バンドル名は、習慣的に<バンドル名>Bundleという名前がよいです。ですからHelloBundleということになっています。
 フォーマットはバンドル作成の際に必要な設定ファイルのタイプを指定します。yml php xmlが指定できますが、ymlが一番簡単だしSymfonyもymlがいいと言っているので初心者はymlにすべきです。

 さて、You can now start using the generated code! というところでバンドル作成が成功したことになります。

バンドルの設定

 バンドルが作成されたらバンドルの設定をいくつかしなくてはなりません。しかしその前にバンドルはどこにあるのでしょう?それは上記ですでに述べたように名前空間で実装されています。
src/Acme/HelloBundle
src/<名前空間>/<バンドル名>
というディレクトリにバンドルのスケルトンが作成されている筈です。バンドルは名前空間が実際のディレクトリとして各ディレクトリごとに格納されます。通常といいますか、PHPもまた、名前空間と実際のディレクトリはバラバラで構わないのですが、Symfonyはフレームワークとして名前空間と実際のディレクトリ構造を全く同じにしています。この方がわかりやすいんです。

 先ほどの宇宙ステーションのようにこのバンドルはどこかでステーションと接続しないと意味がありません。つまりバンドルにお互いに行き来できる通路が必要なわけです。この通路は2つ必要です。それは、
  • 名前空間の登録 [app/autoload.php]
  • カーネルへ登録 [app/AppKernel.php]
という2つの作業です。
 実際はバンドル作成時のコマンド(app/console generate:bundle)で自動的に登録されています。自動的に登録されているというはやや語弊がありますが、名前空間の登録は実はしなくてもいいのです。なぜなら、この名前空間はどこからともなく自動的に読み込まれるように設計されているからです。ですがカーネルの登録は自動的にホントに登録されています。結局のところどちらもしなくてもよいのですが、フレームワークの意味として把握していた方が得策でしょう。

 さて、名前空間の登録はしなくてよいといいましたが、ここは初心者として明示的に登録してみましょう。
app/autoload.phpというファイルに登録します。このファイルは、Symfonyが走る時に自動的に読み込まれます。requireとかincludeとかを全く気にしないで、この先どんどんコードを書いてゆけるという安心極まりない機能を有しています。
$loader = new UniversalClassLoader();
$loader->registerNamespaces(array(
    'Symfony'          => array(__DIR__.'/../vendor/symfony/src', __DIR__.'/../vendor/bundles'),
    ...その他の名前空間...
    'Metadata'         => __DIR__.'/../vendor/metadata/src',
    'Acme'         => __DIR__.'/../src',
));
$loader->registerPrefixes(array(...

16行目辺りが名前空間登録の尻になっている筈です。すでに登録されている名前空間があります。そのリストの最後に明示的に先ほど作成したバンドルを書き加えます。ここでの登録はあくまでのバンドルにまつわる「名前空間」の登録なので、バンドルが配置されているディレクトリを名前空間としたAcmeだけを登録します。この名前空間に後から追加するバンドルの場合は、この中に含まれてしまいますのでここでの作業は不要になります。(というか、元々不要ではあるのですが...)

 カーネルの登録は、app/AppKernel.phpというファイルに登録されています。見てみましょう。
class AppKernel extends Kernel
{
    public function registerBundles()
    {
        $bundles = array(
           ...すでに登録されているBundleがいっぱい
            new JMS\SecurityExtraBundle\JMSSecurityExtraBundle(),
            new Acme\HelloBundle\AcmeHelloBundle(),
        );
21行目辺りにすでに登録されているのがわかります。これは、バンドルが正しく機能しない時に役にたつと思います。もしかしたら、ここに登録されていないかもしれないからです。作成したバンドルがカーネルに登録されているかどうか一応確認してみるのが得策です。

 これでバンドルの作成は終わりです。

バンドル作成の本家のページ
http://docs.symfony.gr.jp/sf2-blog-tutorial/03-create-bundle.html







プロフィール



  • Name :: 山上オサム ♂(39)
  • Hobby :: 武術
  • Work :: Web Designer