モノノフ日記

普通の日記です

Jobeet - 1日目: プロジェクトを始めましょう

Day 1: Starting up the Project (1_2) - Symfony

最初の方は適当に訳しました。実践に入るところあたりからはCLIやコード中心に書いてます。ファイルパスはサイトとは合わせずに自分の環境をベースにしてます。環境はmacbookでやってます。初日なので張り切りすぎました。たぶん明日からはもう少し手を抜きますw

イントロダクション

symfonyフレームワークは3年間OSSとして開発され、すばらしい特性とドキュメントのおかげで今では最も人気のあるフレームワークの1つになっています。この良き傾向は早くから見られていました。
2005年の12月、symfonyの最初のオフィシャルリリースがあったすぐ後、我々は「Askeet tutorial」を発表しました。それは24つのチュートリアルから構成され、12/1からクリスマスの間で1日ずつ公開されました。
このチュートリアルはフレームワーク初心者へ勧めるのに非常に有用なツールです。たくさんの開発者がaskeetのおかげでsymfonyを学習でき、多くの会社で未だ主なトレーニング素材としてaskeetを使っています。
我々は今symfony1.2のリリースで祝杯をあげていて、askeetチュートリアルは古くなったように思います。なので、別の新たなチュートリアルを始めることにしました。

Jobeetへようこそ、2008年版カレンダーチュートリアルの登場です!

チャレンジ

我々は再度チュートリアルを行います。週末を含めた毎日、新しいチュートリアルを公開します。各チュートリアルは約1時間ほどで終わる程度であり、全てやり終えると実際のWebアプリのコーディングでsymfonyを学習できるチャンスになるでしょう。
1日は24時間であり、その期間の長さは開発者がsymfonyの基本を学習するのに必要なものだと考えています。
我々は毎日アプリケーションに新しい要素を追加し、symfonyのWeb開発の良い手本となるだけでなくsymfonyの新しい機能性がWeb開発の利点となっていることを紹介していきます。
askeetでは、21日目は「get-a-symfony-guru-for-a-day」でした。我々はノープランで、コミュニティへaskeetへ追加する要素を提案しなければならなかった。21日目は良い成功例で、コミュニティがアプリケーションに検索エンジンが必要であることを決定しました。そして我々は実装しました。21日目のチュートリアルはaskeetチュートリアルの中で人気のある1つの章です。
Jobeetでは、21日目に「design day」と題し祝うつもりです。4日目の後、Jobeetの公式サイトのデザインを開始するために必要なHTMLとCSSの情報を持つことになるでしょう。それで、もしあなたがデザイナーとして働いているか、あなたの会社がデザインを担当するところであれば、Jobeetのデザインに貢献することができます。21日目に、世論調査を行いコミュニティがJobeetにバンドルされるデフォルトデザインを選ぶことになるでしょう。もちろんデザインが使われれば開発者クレジットに名前がのることになり、有名になれるでしょう!

このチュートリアルは今迄のものとは違います

初期のころのPHP4を覚えていますか? それは「Belle Epoque」のようでした。PHPはWeb向けの習得しやすいファーストランゲージの1つでした。
しかし、非常に歩調の速いWebテクノロジーの進化のため、Web開発者は最新のベストなプラクティスとツールに遅れずについていくことが必要となりました。学習するためのベストな方法はブログやチュートリアルや書籍を読むことです。我々はPHP, Python, Java, Rubyで書かれた上記の参考資料をたくさん読みましたが、それらの多くはサンプルコード集でチュートリアルとしては不十分でした。
あなたはおそらく次のような注意書きを見たことがあるでしょう:
「実際のアプリケーションでは、バリデーションと適切なエラーハンドリングを追加するのを忘れないようにしてください」

「読者の練習のため、セキュリティについては考慮していません」

「もちろんテストの記述は必要になります」
などです。
これらの点は深刻な問題です。おそらくコードの最も重要な一部分です。そして読者はほっておかれます。これらの懸念点について何の考慮もないのでサンプルは役に立ちません。良い出発点としては使えないでしょう。それはひどいことです。なぜならセキュリティやバリデーションやエラーハンドリングやテストは2~3例を挙げると、丁寧なコーディングとなるからです。
このチュートリアルでは、我々が書いたテストコードやエラーハンドリング、バリデーションコードのステートメントを見ることはないですが、我々はセキュアなアプリケーションを開発しています。symfonyを使うことでベストプラクティスでエンタープライズ向けのプロフェッショナルなアプリケーションの開発が可能です。symfonyが提供する全ての機能はたくさんのコードを書くことなしに簡単に利用できるようにしていきます。
バリデーションやエラーハンドリング、セキュリティ、テストはsymfonyでは主要クラスです。だから説明は非常に長くなります。この点が「real life」プロジェクトとしてフレームワークが使われる多くの理由の1つとなっています。

プロジェクト

デザインされていたアプリケーションはもう1つのブログエンジンでした。しかし我々はsymfonyを実用的なプロジェクトとして使いたかった。symfonyがスタイルと少しの努力でプロ仕様のアプリケーションの開発に使えるように見せるのがデモンストレーションのゴールです。
我々は別の日のプロジェクトコンテンツは秘密にするようにします。しかしながらアプリケーションの名前はもう知ってますよね?: Jobeetです。

今日は何を?

24時間というのはsymfonyでアプリケーションを開発するにはたくさんの時間となりますので、本日はPHPコードは書きません。しかし1行もコードを書かないにしても新規プロジェクトのブートストラップをすることでsymfonyのようなフレームワークを使うことの利点を理解し始めることができるでしょう。
今日の目標は開発環境のセットアップとWebブラウザでアプリケーションのページを表示させることです。これらはsymfonyのインストールとアプリケーションの作成、Webサーバの設定も含まれます。

前提条件

まず第一に、すでに動いているWeb開発環境をチェックします。Webサーバ(例:Apache)、データベースエンジン(MySQL, PostgreSQL, SQLite)、PHP5.2.4以降が必要です。コマンドラインから各々調べてください。
またこのチュートリアルはsymfonyフレームワークにフォーカスしたものになるので、PHP5やOOPの知識は持っているものと仮定してすすめます。

symfonyのインストール

まずJobeetプロジェクトのディレクトリを作ります。

$ mkdir -p ~/work/jobeet/
$ cd ~/work/jobeet

PEARからsymfony1.2をインストールします。

$ sudo pear channel-discover pear.symfony-project.com
$ sudo pear install symfony/symfony-1.2.0 

正常にインストールされているかバージョンの確認をします。

$ symfony -V
symfony version 1.2.0 (/opt/local/lib/php/symfony)

プロジェクトのセットアップ

symfonyではアプリケーションはプロジェクト内で再編成された同じデータモデルを共有します。Jobeetでは2種類の異ったアプリケーションを持ちます: frontendとbackendです。

プロジェクトの作成

jobeetディレクトリ内でgenerate:projectタスクを実行するとsymfonyプロジェクトが生成されます。

$ symfony generate:project jobeet

generate:projectタスクはsymfonyプロジェクトに必要なファイルやディレクトリを生成します。

アプリケーションの作成

今度はgenerate:appタスクを実行してfrontendアプリケーションを生成します。

$ symfony generate:app --escaping-strategy=on --csrf-secret=Unique$ecret frontend

project生成と同じように、generate:appタスクはapps/frontendディレクトリ以下にアプリケーションに必要なディレクトリを生成します。
generate:appタスクを実行する際、2つのセキュリティに関するオプションを渡しています。

--escaping-strategy
XSSを防ぐための出力エスケープを有効にします
--csrf-secret
CSRFを防ぐためにフォーム内でのセッショントークンを有効にします
symfonyのパス

symfonyのバージョンは下記コマンドで取得できます。

$ symfony -V
  • Vオプションはsymfonyがインストールされたディレクトリパスを表示します。config/ProjectConfiguration.class.phpにそのパスが含まれているか確認します。
<?php
require_once '/opt/local/lib/php/symfony/autoload/sfCoreAutoload.class.php';

環境について

web/ディレクトリを見ると、2つのPHPファイルindex.phpとfrontend_dev.phpがあります。これらはフロントコントローラと呼ばれます。アプリケーションへの全てのリクエストはこのコントローラを通ります。しかしなぜ1つしかアプリケーションを定義していないのに2つもコントローラがあるのでしょう?
これら2つのファイルは同じアプリケーションを指していますが異なった環境で動作します。アプリケーションを開発する際、本番サーバで直接開発する場合を除き、いくつかの環境を指定できます。

開発環境
開発者が新しい要素を追加したりバグFixをするときに利用
テスト環境
アプリケーションの自動テストで利用
ステージング環境
取引先向けにアプリケーションのテストをするときに利用
本番環境
エンドユーザ向けに利用

環境ごとにユニークになっているのか?開発環境では、デバッグが容易でリクエストに対する詳細なログも見れます。ブラウザ上でエラーチェックできます。キャッシュは利用しないのでコードの変更が即時反映されます。なので、開発者向けに最適化されています。
本番環境では生の例外エラーの代わりにカスタマイズされたエラーメッセージを表示し、キャッシュ機能は当然有効になっています。よって本番環境はユーザ向けにパフォーマンスが最適化されています。

symfonyの環境はconfiguration設定で行います。それらはdev, test, prodの3つです。
フロントコントローラファイルを見ると環境設定が確認できます。

<?php

require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');

$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', false);
sfContext::createInstance($configuration)->dispatch();

Webサーバのセットアップ:ひどい方法

上の節でJobeetプロジェクトのセットアップをしました。もしWebサーバのルートディレクトリ下で生成したなら、既にWebブラウザからアクセスできる状態です。
もちろん非常に素早いセットアップで設定もいりませんが、config/database.ymlにブラウザから直接アクセスできるのでひどい結果になるのは目にみえて理解できます。
本番サーバでこのセットアップは絶対にしてはいけません。次のセクションを読んで適切なWebサーバの設定方法を学んでください。

Webサーバのセットアップ:セキュアな方法

symfonyプロジェクト内のwebディレクトリ下だけを公開するのをデフォルトにしましょう。

Webサーバの設定

/etc/hostsにjobeet.localhostという名前を追加します。

127.0.0.1	localhost askeet.localhost jobeet.localhost
255.255.255.255	broadcasthost

Apacheのルートディレクトリにjobeetプロジェクトのwebディレクトリへのシンボリックリンクを作成します。

$ sudo ln -s ~/work/jobeet/web /opt/local/apache2/htdocs/jobeet

httpd-vhosts.confを編集します。

#
# Use name-based virtual hosting.
#
NameVirtualHost *:80

<VirtualHost *:80>
    ServerAdmin jobeet@gmail.com
    DocumentRoot "/opt/local/apache2/htdocs/jobeet/"
    ServerName jobeet.localhost
    DirectoryIndex index.php
    Alias /sf "/opt/local/lib/php/data/symfony/web/sf"
    <Directory "/opt/local/apache2/htdocs/jobeet/">
        AllowOverride All
        Allow from All
    </Directory>
    <Directory "/opt/local/lib/php/data/symfony/web/sf">
        AllowOverride All
        Allow from All
    </Directory>
    ErrorLog "logs/jobeet.localhost-error_log"
    CustomLog "logs/jobeet.localhost-access_log" common
</VirtualHost>
新しい設定のテスト

http://jobeet.localhost が閲覧できるかチェックします。
f:id:Kiske:20081203075226p:image