役立つ&分かりやすいチュートリアルの登場

Symfonyも先日1.0RC1がリリースされてようやく脱ベータになりそうな予感。
ほとんど存在しなかった日本語のチュートリアルも有志の方々によってずいぶん整備され、敷居が低くなってきていると思う。
とりわけデータベース周りについては、今回発見した
symfony入門(2):掲示板アプリケーション作成でsymfonyを理解しよう(前篇)
が役に立ちそう。(CodeZineへの無料ユーザー登録が必要です)

クラス図

現在Symfonyを学習する中で利用しているメソッドについてまとめてみる。今後も加筆していきます。
sfActionクラス

メソッド 意味
getRequestParameter(A[, B]) Aのキーの値を取得して返す。もしBが設定されているのであれば、Bと値が一致しているかどうかをboolean型で返す。

Criteriaオブジェクト(データベースからの抽出条件を指定するためのクラス)

メソッド 意味
add(<テーブル名>Peer::<大文字フィールド名>, 値[, Criteria::<比較演算子記述(LIKE, EQUAL等)>]) データの抽出条件を設定。第3引数省略時はEQUALに同じ
addAnd(Criteriaオブジェクト) 条件をandで追加
addOr(Criteriaオブジェクト) 条件をorで追加
addAscendingOrder(<テーブル名>Peer::<大文字フィールド名>) 対象となるフィールドで昇順にソート
addDescendingOrder(<テーブル名>Peer::<大文字フィールド名>) 対象となるフィールドで降順にソート
addGroupByColumn(<テーブル名>Peer::<大文字フィールド名>) 対象となるフィールドでグループ化

※CriteriaオブジェクトについてはCodeZineより引用、一部加筆

Symfonyでデータベースに接続する

久しぶりにSymfonyをやってみました。今回はかなり重要なデータベースの操作についてです。
まずスキーマを作成します。これはデータベースを操作するためのクラスを生成するために必要です。手動で作成するか、既存のデータベースから作成することも出来ます。今回は既存のデータベースから生成する方法を選択します。この場合には、config/propel.iniに接続情報を登録しておく必要があります。
symfony propel-build-schema
を実行すると以下のようなエラーがでました。

PHP Warning: include_once(phing/Phing.php): failed to open stream: No such file or directory in /usr/share/pear/pake/tasks/pakePhingTask.class.php on line 11
PHP Warning: include_once(): Failed opening ‘phing/Phing.php’ for inclusion (include_path=’/var/www/zaiteku.jp/lib:/var/www/zaiteku.jp/apps//lib::/usr/share/pear/symfony/vendor:/usr/share/pear/../lib:/usr/share/pear/lib:.:/usr/share/pear’) in /usr/share/pear/pake/tasks/pakePhingTask.class.php on line 11
ERROR: symfony – You must install Phing to use this task. (pear install http://phing.info/pear/phing-current.tgz)

どうやらphingというのが入っていないためのようでしたので、以下を実行してインストールします。
pear channel-discover pear.phing.info
pear install phing/phing
そうした上で、再度
symfony propel-build-schema
を実行したところ、またエラーが出ました。どうやらXMLを生成する際にDOMを利用しているらしく、php-domというパッケージをインストールする必要があります。

PHP Fatal error: Class ‘DOMDocument’ not found in /usr/share/pear/symfony/vendor/propel-generator/classes/propel/phing/PropelCreoleTransformTask.php on line 273

yum php-dom
今度は、依存性のエラーに悩まされました。どうやらphp-domは5.1.6-3.3.fc6を要求しているけれども、アップグレードすると既存のパッケージphp-gdなどが5.1.6-3.1.fc6が必要でインストールできないとわがままを言っている。

Error: Missing Dependency: php = 5.1.6-3.1.fc6 is needed by package php-gd
Error: Missing Dependency: php = 5.1.6-3.1.fc6 is needed by package php-pdo

そこで、同時にアップグレードしてあげた上で、
yum update php php-gd php-pgsql php-pdo
再度yum install php-domを実行するとうまくいった。
次に
symfony propel-build-model
でモデルを生成し、
symfony propel-generate-crud (appname) (modulename) (databasename)
で簡易アクセスツールを生成しました。
そうすると
index.php/modulename
でアクセスできるはずが500エラー。
デバッグモードで起動すると
[PropelException]
No connection params set for propel
というエラーが発生していて表示できないらしい。
ここでどうやって良いのかかなり悩んだが、http://www.symfony-project.com/askeet/2 のドキュメントを見つけることが出来、config/databases.ymlを編集すればよいことがわかった。
実際に起動できるようになると、かなり簡単に操作できることがわかって悩んだ甲斐がありました。
あまりのドキュメントの少なさに途方にくれ、もうすこしでphp-cakeに浮気しそうになりました。もう少し頑張ってみようと思います。

include_metas()が正しくエンコードを処理できない問題

metaタグに関連するデータを出力する関数include_metas()はUTF-8以外のエンコードでは正しく処理されない不具合があるようだ。たとえば、Shift-JISでは以下のように変換されてしまう。

将来→・cent;来
株式→株・reg;
開発→開・shy;

EUC-JPでもこの問題は確認していて、不具合の理由を調べてみたいと思う。

view.yml

テンプレートの属性を制御するview.ymlは(init-appで指定した名前)/config/view.ymlとmodules/(module_name)/config/view.ymlが存在しており、後者のview.ymlは前者のview.ymlを継承しているので、変更される箇所だけを指定すればよい。
view.yml内のスペースの数はview.yml内の親子の関係を示しているので、スペースの数は非常に重要となる。
たとえば、has_layoutとmetasは兄弟関係にあるので、

default:
metas:
 title: タイトル
has_layout: on
layout: layout_hogehoge

は正しくレイアウトが適用されるが

default:
metas:
 title: タイトル

 has_layout: on
 layout: layout_hogehoge

はhas_layout, layoutがmetasのこの関係になってしまうので、正しく動作しない。僕はこれで一度ハマったので、注意していただきたい。
※なお、上記はそのままコピーしないでください。スペース2つが全角スペースになっています。

Symfonyのテンプレートにコメントする方法

Analyticsによるアクセス解析をしていたら意外に「symfony テンプレート コメント」というキーワードで来てもらっている人が多いことに気づく。そこで、Symfonyのテンプレートにコメントする方法について考える。
SymfonyのテンプレートはPHPそのものなので、方法としては、

<?php
/*****
ここにコメントするとか
*****/
//こうやってコメントするとか
?>

が使えると思う。ただ、Smartyのコメントのように{* *}が利用できないことは、テンプレートを実際に変更すると思われるデザイナーの人にコメントを見せられないということが問題になってくるかもしれない。(つまりテンプレートファイルをDreamWeaverなどのオーサリングソフトで処理してしまうと「?」マークになってしまってコメントが出ないからだ)
なにか良い方法があれば、追記していきたいと思う。また、知っている方がいらっしゃれば是非コメントを頂きたい。

Oops! There was an internal server error.

このエラーが出た場合には、デバッグ用のプログラムを起動させて詳細エラーを出力したほうが良いだろう。デフォルトの場合、front_dev.phpになっているので、(symfonyプロジェクトURL)/index.php/(module)/(action)/を、(symfonyプロジェクトURL)/front_dev.php/(module)/(action)/とすればよい。初歩的なエラーとしては、
・cacheディレクトリに書き込み権限がない(init-projectコマンドで実行した場合にはchmodによって適切な権限が設定されるがWindows環境では動作しないのでこの問題が起こる)
などが考えられる。

テンプレートを変更

Symfonyにて意図的にテンプレートを変更する方法はあるのだろうか?Mojavi+Smartyと同じようにreturnで変更できることがわかったのでいかのとおり示してみる。

class yesnoActions extends sfActions
{
 public function executeQuestion()
 {
  //ここで呼ばれるテンプレートはQuestionSuccess.phpだがreturnすることで変更できる
  return ‘Result’; //こうすることでQuestionResult.phpを呼ぶことができる。
 }
 //バリデーションからエラーが発生した場合でもSuccessテンプレートを呼ぶ
 public function handleErrorConfirm()
 {
  //テンプレートを共通化する
  return sfView::SUCCESS;
 }
}

プロジェクトの作成

hogehogeプロジェクトをfrontendアプリケーションとして生成する場合。生成したいディレクトリ内で以下を実行します。

symfony init-project hogehoge
symfony init-app frontend

なお、SymfonyはPHP5で動作するので.phpのマッピングがPHP5になっていることが前提です。
次にパーミッション設定をします。
cacheディレクトリへ書き込みを行いますので、cacheディレクトリにApacheユーザーまたはNETWORKユーザー(IISの場合)に書き込み権限を付与します。
また、トップページを描画するには、apps/frontend/modules/defaultに以下のファイルを配置します。

actions/actions.class.php
templates/indexSuccess.php

設定項目
apps/frontend/config/view.yml タイトル類
apps/frontend/config/settings.yml
IISだと.htaccessによるrewriteが利かないので、以下の設定を行う。

prod:
.settings:
no_script_name: on

prod:
.settings:
no_script_name: off

にする。

Congratulations!
If you see this page, it means that the creation of your symfony project on this system was successful.
You can now create your model and customize default templates.

となればOK!プロジェクトの作成を開始しよう。