イントロダクション
symfonyフレームワークはオープンソースプロジェクトとして3年間以上開発され、すばらしい機能とドキュメントのおかげで今ではもっとも人気のあるフレームワークの1つになりました。このすばらしい慣習は初期のころから続けられてきました。
2005年の12月、symfonyの最初のオフィシャルリリースがあった直後に、私たちはAskeetチュートリアルを発表しました。 それは24つのチュートリアルから構成され、12月1日からクリスマスの間に1日ずつ公開されました。
このチュートリアルはフレームワーク初心者へ勧めるのにかけがいのない教材です。 大勢の開発者がaskeetのおかげでsymfonyを学習でき、多くの会社は今でも主要なトレーニング教材としてaskeetを使っています。
symfony 1.2のリリースと共にaskeetチュートリアルは古くなってきたので、別のアドベントカレンダーのJobeetを公開することにしました。
このチュートリアルは2008年にsymfonyの公式blogで1日づつ公開され、少しずつ読み進めることができます。
チャレンジ
チュートリアルの各章は約1時間ほどで終わる程度であり、実際のWebサイトを最初から最後までコーディングすることでsymfonyを学習します。
1日1時間24日で合計1日になります。 これはsymfonyの基本を学ぶために必要な時間であると私たちは考えています。 毎日、新しい機能がアプリケーションに追加され、symfonyのWeb開発のベストプラクティスと同時に新しい機能を紹介するためにこの開発プロセスを利用します。
askeetでは、21日目は「get-a-symfony-guru-for-a-day」でした。 私たちはノープランであり、コミュニティはaskeetに追加する要素を提案しなければなりませんでした。 21日目はすばらしい成功例であり、コミュニティはアプリケーションに検索エンジンを実装することが必要だと判断しました。 そして私たちは実装しました。 21日目のチュートリアルはaskeetチュートリアルの中でもっとも人気があります。
Jobeetでは、21日目に行われたデザインコンテストの優勝者を祝福しました。 優勝したデザインはcenter{source}によるもので、このチュートリアルのデフォルトのデザインとして使用しています。 また、実際のJobeetのWebサイトでもこのデザインが採用されています。
このチュートリアルは今までのものとは違います
初期のころのPHP 4を覚えていますか? ベル・エポック(よき時代)でした。 PHPはWeb専用でもっとも習得しやすい最初の言語の1つでした。
しかし、Webテクノロジーは早く進化し、Web開発者は最新のベストプラクティスとツールについてゆくことが必要になりました。 学ぶための最良の方法はブログやチュートリアルや書籍を読むことです。 私たちはPHP、Python、Java、Ruby、Perlで書かれたたくさんの資料を読んできましたが、筆者がコードスニペットの例を提供するときにこれらの多くは不十分でした。
おそらく次のような注意書きを見たことがあるでしょう:
「実際のアプリケーションでは、バリデーションと適切なエラーハンドリングを追加するのを忘れないでください」
や
「読者の練習のため、セキュリティについては考慮していません」
や
「もちろんテストの記述は必要になります」
などです。
何ということでしょう。 これらは深刻な問題です。 これらはコードのもっとも重要な部分です。 それなのに読者は置き去りにされます。 これらの問題を考慮していないのであれば、サンプルコードは役に立ちませんし、よい出発点として使えません。 ひどいとは思いません? セキュリティやバリデーションやエラーハンドリングやテストは2・3の例を挙げると、きちんとコーディングしなければならないからです。
このチュートリアルでは、「テスト、エラーハンドリング、バリデーションコードは後で書きます」、「セキュアなアプリケーションを開発してください」といった文は見ることはいっさいありません。 なぜならsymfonyはコードそのものであり、企業向けのプロフェッショナルなアプリケーションを開発するためのベストプラクティスおよび手段でもあるからです。 symfonyは多くのコードを書かずにこれらの面を簡単に実装するために必要なすべてのツールを提供するのでこのような豪華なことができます。
symfonyではバリデーションやエラーハンドリング、セキュリティ、テストは第一級の扱いを受けます。 ですので説明にそれほどの時間はかかりません。 この点が「日常生活の」プロジェクトとしてフレームワークが使われる多くの理由の1つとなっています。
このチュートリアルで読むすべてのコードは実際のプロジェクトで使えます。 コードのスニペットをコピー&ペーストするもしくはコード全体を流用することを推奨します。
プロジェクト
設計するアプリケーションを別のblogエンジンにすることもできました。 しかし私たちはsymfonyを実用的なプロジェクトとして使うことを望んでいます。 symfonyがスタイルと少しの労力でプロ仕様のアプリケーションの開発に使えることを実証するのがゴールです。
今日は多くの作業があるので別の日のプロジェクトのコンテンツは秘密にしておきます。 でもアプリケーションの名前はもうご存知ですよね?: Jobeetです。
今日は何を?
24時間あればsymfonyでアプリケーションを開発するのに十分なので、本日はPHPコードを書きません。 しかし1行もコードを書かないにしても新規プロジェクトをブートストラップすることでsymfonyのようなフレームワークを使うことの利点を理解し始めるでしょう。
今日の目標は開発環境のセットアップとWebブラウザーでアプリケーションのページを表示させることです。 これらはsymfonyのインストールとアプリケーションの作成、Webサーバーの設定も含まれます。
前提条件
まず最初に、すでに動いているWeb開発環境を確認します。 Webサーバー(例:Apache)、データベースエンジン(MySQL、PostgreSQL、SQLite)、PHP 5.2.4以降が必要です。 コマンドラインからそれぞれ調べてください。
コマンドラインを多用するので、Unix系OSを利用する方がよいですが、Windowsシステムを稼働させていても、立派に動作します。
cmd
プロンプトでいくつかのコマンドを入力するだけです。
note
UnixシェルのコマンドはWindows環境で重宝します。
Windowsでtar
、gzip
もしくはgrep
のようなツールを使いたいなら、Cygwinをインストールします。
公式ドキュメントは少しまばらですが、よいインストールガイドがここで見つかります。
冒険好きな人はMicrosoftのWindows Services for Unixを試すのもよいでしょう。
またこのチュートリアルはsymfonyフレームワークに焦点を当てるので、PHP 5やオブジェクト指向のプログラミングの知識があることを前提とします。
symfonyのインストール
最初に、Jobeetプロジェクトに関連するファイルを格納するディレクトリを作ります:
$ mkdir -p /home/sfprojects/jobeet $ cd /home/sfprojects/jobeet
Windowsでは次の通りです:
c:\> mkdir c:\development\sfprojects\jobeet c:\> cd c:\development\sfprojects\jobeet
note
Windowsユーザーの方はsymfonyの新しいプロジェクトをスペースが含まれないパスでセットアップすることをおすすめします。
My Documents
より下の場所を含めてDocuments and Settings
ディレクトリを使うのは避けるべきです。
symfonyフレームワークのライブラリファイルを格納するディレクトリを作ります:
$ mkdir -p lib/vendor
symfony公式サイトのインストールの手引きのページでは symfonyの利用可能なすべてのバージョンの一覧と比較をしています。
このチュートリアルはsymfony 1.2に向けて書かれているので、symfony 1.2のインストールの手引きのページを参照してください。
"Source Download"セクションで、.tgz
もしくは.zip
フォーマットのアーカイブが見つかります。
アーカイブをダウンロードし、新しいlib/vendor/
ディレクトリに設置し展開します:
$ cd lib/vendor $ tar zxpf symfony-1.2.2.tgz $ mv symfony-1.2.2 symfony $ rm symfony-1.2.2.tgz
Windows環境ではzipファイルの展開はエクスプローラーで可能です。
ディレクトリの名前をsymfony
に変更すると、パスはc:\development\sfprojects\jobeet\lib\vendor\symfony
となります。
PHPの設定はディストリビューションによって大きく異なるので、PHPの設定がsymfonyの最小要件を満たすことを確認する必要があります。 コマンドラインからsymfony付属の設定チェッカースクリプトを起動します:
$ cd ../.. $ php lib/vendor/symfony/data/bin/check_configuration.php
問題があれば、修正方法のヒントが示されます。 PHPの設定が異なる可能性があるのでブラウザーからもチェッカースクリプトを実行します。 Webサーバーのディレクトリのどこかでファイルをコピーしてそのファイルにアクセスします。 後でWebのルートディレクトリからこのファイルを削除することをお忘れなく:
$ rm web/check_configuration.php
スクリプトがエラーを出力しない場合、symfonyコマンドを使ってバージョンを表示することで、symfonyが正しくインストールされていることを確認します(大文字のV
に注意):
$ php lib/vendor/symfony/data/bin/symfony -V
Windows環境では次の通りです:
c:\> cd ..\.. c:\> php lib\vendor\symfony\data\bin\symfony -V
コマンドラインツールができることに関心があれば、利用可能なオプションとタスクの一覧を表示するためにsymfony
を入力します:
$ php lib/vendor/symfony/data/bin/symfony
Windows環境では次の通りです:
c:\> php lib\vendor\symfony\data\bin\symfony
symfonyコマンドラインは開発者の最良の友です。 これはキャッシュをクリアしたりコードを生成するなど、毎日の活動の生産性を改善するたくさんのユーティリティを提供します。
プロジェクトのセットアップ
symfonyではアプリケーションはプロジェクト内で再編成された同じデータモデルを共有します。 Jobeetでは2種類の異なるアプリケーション: frontend|フロントエンドとがあります。
プロジェクトの作成
jobeet
ディレクトリから、実際にsymfonyプロジェクトを作成するためにgenerate:project
タスクを実行します:
$ php lib/vendor/symfony/data/bin/symfony generate:project jobeet
Windowsでは次の通りです:
c:\> php lib\vendor\symfony\data\bin\symfony generate:project jobeet
generate:project
タスクはsymfonyプロジェクトに必要なディレクトリとファイルのデフォルト構造を生成します:
ディレクトリ | 説明 |
---|---|
apps/ |
プロジェクトのすべてのアプリケーションを格納する |
cache/ |
フレームワークによってキャッシュされるファイル |
config/ |
プロジェクトの設定ファイル |
lib/ |
プロジェクトのライブラリとクラス |
log/ |
フレームワークのログファイル |
plugins/ |
インストールされたプラグイン |
test/ |
ユニットテストと機能テストのファイル |
web/ |
Web公開ルートディレクトリ(下記を参照) |
note
なぜsymfonyはたくさんのファイルを生成するのでしょうか? フルスタックフレームワークを使う主な利点の1つは開発作業を標準化することです。 symfonyのファイルとディレクトリのデフォルト構造のおかげで、ある程度の知識がある開発者はsymfonyプロジェクトのメンテナンスを引き継ぎできます。 ほんの数分で、引き継ぎ者はコードに飛び込むことが可能で、バグを修正し新しい機能を追加します。
タスクを実行するときに入力しなければならない文字数を短くするためにでgenerate:project
タスクはsymfony
のショートカットをJobeetプロジェクトのルートディレクトリに作りました。
これからは、symfonyプログラムへのフルパスの代わりにsymfony
ショートカットを使います。
アプリケーションの作成
今度はgenerate:app
タスクを実行してfrontendアプリケーションを生成します。
$ symfony generate:app --escaping-strategy=on --csrf-secret=Unique$ecret frontend
tip
symfonyファイルが実行可能なので、Unixのユーザーはすべての'php symfony'を'./symfony'に置き換えできます。 Windowsでは'symfony.bat'ファイルをプロジェクトにコピーして'php symfony'の代わりに'symfony'コマンドが使えます:
c:\> copy lib\vendor\symfony\data\bin\symfony.bat .
プロジェクト生成と同じように、generate:app
タスクはアプリケーションに必要なディレクトリをapps/frontend
ディレクトリ以下で生成します。
ディレクトリ | 説明 |
---|---|
config/ |
アプリケーションの設定ファイル |
lib/ |
アプリケーションのライブラリとクラス |
modules/ |
アプリケーションのコード(MVC) |
templates/ |
グローバルテンプレートファイル |
tip
場所を明らかに指示しないかぎり、すべてのsymfony
コマンドはプロジェクトのディレクトリの中で実行しなければなりません。
generate:app
タスクを呼び出す際に、セキュリティに関する2つのオプションを渡します。
--escaping-strategy
: XSSを防ぐための出力エスケープを有効にする--csrf-secret
: CSRFを防ぐためにフォーム内でのセッショントークンを有効にする
タスクにこれらの追加オプションを渡すことで、Webでもっとも広く知られる2つの脆弱性から将来の開発を守りました。 これで、私たちに代わってsymfonyは自動的にセキュリティ対策を行ってくれます。
symfonyのパス
symfonyのバージョンは下記のコマンドで取得できます。
$ symfony -V
-V
オプションはsymfonyがインストールされたディレクトリパスを表示します。
config/ProjectConfiguration.class.php
にそのパスが含まれているか確認します。
// config/ProjectConfiguration.class.php require_once '/Users/fabien/work/symfony/dev/1.2/lib/autoload/sfCoreAutoload.class.php';
ポータビリティを高めるために、symfonyがインストールされたディレクトリへの絶対パスを相対パスに変更します:
// config/ProjectConfiguration.class.php require_once dirname(__FILE__).'/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php';
これで、Jobeetプロジェクトのディレクトリをマシンの別の場所もしくは他のマシンに移動させても、きちんと動きます。
環境
web/
ディレクトリを見ると、2つのPHPファイル、index.php
とfrontend_dev.php
があります。
これらはフロントコントローラー(front controller)と呼ばれます。
アプリケーションへの全てのリクエストはこのコントローラーを通過します。
しかし1つしかアプリケーションを定義していないのに2つもコントローラーがあるのはなぜでしょうか?
これら2つのファイルは同じアプリケーションを指していますが異なる環境で動作します。 アプリケーションを開発する際、運用サーバーで直接開発する場合を除き、いくつかの環境が必要となります。
- 開発環境: 開発者が新しい要素を追加したりバグを修正するときに利用する
- テスト環境: アプリケーションの自動テストで利用する
- ステージング環境: 取引先向けにアプリケーションのテストをするときに利用する
- 運用環境: エンドユーザー向けに利用する
何によって環境を区別できるようになっているのでしょうか? たとえば開発において、デバッグ作業を楽にするためにアプリケーションはリクエストのすべての詳細内容をログに記録する必要がありますが、コードへのすべての変更が即座に反映されるようにキャッシュシステムは無効にしなければなりません。 ですので、開発環境は開発者のために最適化しなければなりません。 例外が一番よい例です。 開発者が問題を素早くデバッグできるよう手助けするために、symfonyは現在のすべてのリクエスト情報とともに、例外を直接ブラウザに表示します:
しかし運用環境では、キャッシュレイヤーを有効にし、もちろん、アプリケーションは生の例外の代わりにカスタマイズされたエラーメッセージを表示しなければなりません。 ですので運用環境はパフォーマンスとユーザーエクスペリエンスのために最適化しなければなりません。
symfonyの環境はコンフィギュレーション設定の一意的なセットです。
symfonyフレームワークは3つの環境: dev
、test
とprod
を搭載しています。
22日目において、staging
環境など新しい環境の作り方を学びます。
フロントコントローラーファイルを開くと、環境設定以外、これらの内容が同じであることがわかります:
// web/index.php <?php require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php'); $configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', false); sfContext::createInstance($configuration)->dispatch();
note
symfonyの新しい環境を定義するのは新しいフロントコントローラーを作ることと同じぐらい簡単です。 環境の設定を変更する方法を後で見ることになります。
Webサーバーのセットアップ:好ましくないやり方
上の節でJobeetプロジェクトのセットアップをしました。 もしWebサーバーのルートディレクトリの下で生成したなら、すでにWebブラウザーからアクセスできる状態です。
もちろん設定ファイルを編集しないので、迅速なセットアップができますが、config/database.yml
にブラウザーから直接アクセスできるので手抜きの悪い結果を見ることになります。
Webサイトがsymfonyで開発されたことをユーザーが知っていたら、たくさんのデリケートなファイルにアクセスが可能となってしまします。
**運用サーバーでこのセットアップ方法は絶対に実行してはなりません。 **次の節を読んでWebサーバーの適切な設定方法を学んでください。
Webサーバーのセットアップ:セキュアな方法
Web開発のよい習慣はスタイルシート、JavaScript、もしくは画像のようなWebブラウザーがアクセスする必要のあるファイルだけをWebのルートディレクトリの下に設置することです。
デフォルトでは、symfonyプロジェクトのweb
サブディレクトリにこれらのファイルを保存することをおすすめします。
このディレクトリを見ると、(css/ images/)といったwebアセットのサブディレクトリと2つのコントローラーのファイルが見つかります。 これらのフロントコントローラーはwebディレクトリの下で必要な唯一のPHPファイルです。 他のすべてのPHPファイルはブラウザーから隠匿され、セキュリティに関してこれはよい考えです。
Webサーバーのコンフィギュレーション
世界中から新しいプロジェクトにアクセスできるようにApacheのコンフィギュレーションを変更しましょう。
httpd.conf
設定ファイルを見つけて開き次のコンフィギュレーションを最後の行を追加します:
# Be sure to only have this line once in your configuration NameVirtualHost 127.0.0.1:8080 # This is the configuration for Jobeet Listen 127.0.0.1:8080 <VirtualHost 127.0.0.1:8080> DocumentRoot "/home/sfprojects/jobeet/web" DirectoryIndex index.php <Directory "/home/sfprojects/jobeet/web"> AllowOverride All Allow from All </Directory> Alias /sf /home/sfprojects/jobeet/lib/vendor/symfony/data/web/sf <Directory "/home/sfprojects/jobeet/lib/vendor/symfony/data/web/sf"> AllowOverride All Allow from All </Directory> </VirtualHost>
note
/sf
エイリアスによってsymfonyのデフォルトページとWebデバッグツールバーを適切に表示するために必要な画像とJavaScriptファイルにアクセスできるようになります。
Windowsでは、Alias
の行を次のように置き換える必要があります:
Alias /sf "c:\development\sfprojects\jobeet\lib\vendor\symfony\data\web\sf"
/home/sfprojects/jobeet/web
は次のように置き換えます:
c:\development\sfprojects\jobeet\web
この設定によってApacheはマシンのポート番号8080
をリスニングするようになるので、JobeetのWebサイトは次のURLからアクセスできるようになります:
http://~localhost~:8080/
8080
以外の好きな番号に変更できますが管理者権限を必要としない1024よりも大きな番号が望ましいです。
新しい設定をテストする
Apacheを再起動し、ブラウザーを開きhttp://localhost:8080/index.php/
もしくはhttp://jobeet.localhost/index.php/
を入力することで新しいアプリケーションにアクセスできるか確認します。
どちらのURLになるかは以前のセクションで選んだ設定によります。
note
Apacheのmod_rewrite
モジュールをインストールした場合、URLのindex.php/
部分を取り除くことができます。
これはweb/~.htaccess|.htaccess(Apache)~
ファイルで設定される書き換えルールのおかげで可能です。
開発環境のアプリケーションにもアクセスしてみることにします。 次のURLを入力します:
http://jobeet.localhost/frontend_dev.php/
Webデバッグツールバーは右上コーナーに表示され、小さなアイコンが含まれていればsf/
エイリアスの設定が正しいことがわかります。
Webデバッグツールバーは 開発環境のすべてのページに存在し異なるタブにクリックすれば多くの情報: 現在のアプリケーションの設定、現在のリクエストのログ、データベースエンジンで実行されたSQLステートメント、メモリ情報、時間の情報が得られます。
note
Windows環境のIISサーバーでsymfonyを動かしたい場合セットアップ方法が少し異なります。 関連チュートリアルで設定する方法がわかります。
Subversion
Webアプリケーションを開発するときにバージョン管理ツールを利用するのはよい習慣です。 バージョン管理ツールを利用することで次のことが可能になります:
- 安心して作業する
- 変更によって何かが壊れたときに以前のバージョンに差し戻す
- プロジェクトで複数の人が効率的に作業できる
- 連続するすべてのバージョンのアプリケーションを入手できる
この節では、Subversionの使い方を説明します。 別のソースコード管理ツールを利用しているのであれば、私たちがSubversionについて説明することを適用するのは簡単でしょう。
Subversionサーバーへの権限がありHTTPを通してアクセスできることを前提とします。
tip
自由に使えるSubversionサーバーがなければ、無料のGoogle Codeで作成するかより多くの選択肢を探すためにGoogle検索で"free subversion repository"を入力して検索します。
最初に、リポジトリサーバーでjobeet
プロジェクト用のリポジトリを作ります:
$ svnadmin create /path/to/jobeet/repository
マシンの上で、ディレクトリの基本構造を作成します:
$ svn mkdir -m "created default directory structure" http://svn.example.com/jobeet/trunk http://svn.example.com/jobeet/tags http://svn.example.com/jobeet/branches
そして空のtrunk/
ディレクトリをチェックアウトします:
$ cd /home/sfprojects/jobeet $ svn co http://svn.example.com/jobeet/trunk/ .
それから、cache/
とlog/
ディレクトリをリポジトリに置きたくないのでこれらの内容を削除します。
$ rm -rf cache/* log/*
Webサーバーが書き込みできるようにcacheとlogディレクトリに適切なレベルの書き込み権限をかならず設定してください:
$ chmod 777 cache/ log/
すべてのファイルとディレクトリをインポートします:
$ svn add *
cache/
と/log
ディレクトリに設定されたファイルをコミットしたくないので、無視リストを指定する必要があります:
$ svn propedit svn:ignore cache
SVN用に設定されたデフォルトのテキストエディターが起動します。 Subversionはこのディレクトリのすべての内容を無視しなければなりません:
*
保存して終了します。終わりました。
log/
ディレクトリ用に手順を繰り返します:
$ svn propedit svn:ignore log
そして次のコマンドを入力します:
*
最後に、これらの変更をレポジトリにコミットします:
$ svn import -m "made the initial import" . http://svn.example.com/jobeet/trunk
tip
WindowsユーザーはSubvresionのレポジトリを管理するためにすばらしい TortoiseSVN クライアントを利用できます。
note
JobeetのSVNレポジトリは毎日公開されます。
リポジトリは(http://svn.jobeet.org/
)はまだ公開されていませんが、今日のコードはコミットされタグづけされました。
release_day_01
をチェックアウトできます:
$ svn co http://svn.jobeet.org/tags/release_day_01/ jobeet/
それではまた明日
はい、今日はここまでです! symfonyについてまだ何も話していませんが、確固とした開発環境をセットアップし、Web開発のベストプラクティスを話し、コーディングを始める準備ができています。
明日は、アプリケーションが何を行うのかを明らかにしチュートリアルの間に実装する必要のある要件を話します。
note
今日もしく他の日のコードを確認したい場合、Jobeetの公式SVNリポジトリから一日分の内容ごとに入手可能です(http://svn.jobeet.org/doctrine/
)。
たとえば、release_day_01
タグをチェックアウトすれば今日のコードを入手できます:
$ svn co http://svn.jobeet.org/doctrine/tags/release_day_01/ jobeet/
This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.