- 前提条件
- Symfony とは
- インストール
- Hello World
- ディレクトリ構造を変更したい場合
- phpdoc
- フロントコントローラ、モジュール、アクション、ビュー
- 設定ファイル
- ヘルパー
- 認証とセッション管理
- プラグイン
- 開発手順
- メモ(未分類)
前提条件
ここで説明する内容は、以下の環境で動作確認を行っている。
- Fedora Core 7
- Apache/2.2.4
- PHP 5.2.2
- PostgreSQL 8.2.4-1.fc7
- symfony 1.0.6
Symfony とは
PHP5用のWebアプリケーションフレームワーク。
インストール
# pear channel-discover pear.symfony-project.com # pear install symfony/symfony
あとは、↓ここを参照
Hello World
プロジェクトの作成
$ mkdir /home/naka/Work/symfony/myproject $ cd /home/naka/Work/symfony/myproject $ symfony init-project myproject
以下のようなディレクトリが自動的に作られる。
[naka@localhost myproject]$ ls -l 合計 48 drwxr-xr-x 2 naka naka 4096 2007-08-10 13:03 apps/ drwxr-xr-x 2 naka naka 4096 2007-08-10 13:03 batch/ drwxrwxrwx 2 naka naka 4096 2007-08-10 13:03 cache/ drwxr-xr-x 2 naka naka 4096 2007-08-10 13:03 config/ drwxr-xr-x 4 naka naka 4096 2007-08-10 13:03 data/ drwxr-xr-x 2 naka naka 4096 2007-08-10 13:03 doc/ drwxr-xr-x 3 naka naka 4096 2007-08-10 13:03 lib/ drwxrwxrwx 2 naka naka 4096 2007-08-10 13:03 log/ drwxr-xr-x 2 naka naka 4096 2007-08-10 13:03 plugins/ -rwxrwxrwx 1 naka naka 389 2007-08-10 13:03 symfony* drwxr-xr-x 5 naka naka 4096 2007-08-10 13:03 test/ drwxr-xr-x 6 naka naka 4096 2007-08-10 13:03 web/
アプリケーションの作成
$ cd /home/naka/Work/symfony/myproject/ $ symfony init-app myapp
appsディレクトリの下に以下のようなディレクトリが自動的に作られる。
drwxr-xr-x 7 naka naka 4096 2007-08-10 13:06 myapp/
Webサーバの設定
symfonyアプリケーションを公開するために、PATHエイリアスやディレクトリの設定を行う。
DocumentRoot の設定をいじりたいので、VirtualHostに書く。
<VirtualHost *:80> ServerAdmin invalid@example.com DocumentRoot "/home/naka/Work/symfony/myproject/web" ServerName symfony.example.com ErrorLog logs/symfony.example.com-error_log CustomLog logs/symfony.example.com-access_log common DirectoryIndex index.php
Alias /sf /usr/share/pear/data/symfony/web/sf <Directory " /usr/share/pear/data/symfony/web/sf"> AllowOverride All Allow from All </Directory>
<Directory " /home/naka/Work/symfony/myproject/web"> AllowOverride All Allow from All </Directory> </VirtualHost>
クライアント側の Hostsに、
192.168.10.128 symfony.example.com
サーバ側の Hostsに、
127.0.0.1 symfony.example.com
と書いておく。
これで、http://symfony.example.com/index.php にアクセスすると、
Congratulations! You have successfully created your symfony project.
のメッセージが表示される。これで、Symfonyによる雛型が完成。
モジュールのセットアップ
$ cd /home/naka/Work/symfony/myproject $ symfony init-module myapp mymodule
これで、いくつかのモジュールが自動的に作成される。
[naka@localhost myproject]$ ls -l apps/myapp/modules/ 合計 4 drwxr-xr-x 7 naka naka 4096 2007-08-10 13:32 mymodule/ [naka@localhost myproject]$ ls -l apps/myapp/modules/mymodule/ 合計 20 drwxr-xr-x 2 naka naka 4096 2007-08-10 13:32 actions/ drwxr-xr-x 2 naka naka 4096 2007-08-10 13:32 config/ drwxr-xr-x 2 naka naka 4096 2007-08-10 13:32 lib/ drwxr-xr-x 2 naka naka 4096 2007-08-10 13:32 templates/ drwxr-xr-x 2 naka naka 4096 2007-08-10 13:32 validate/
デフォルトページの設定
indexSuccess.php
$ cd /home/naka/Work/symfony/myproject/apps/myapp/modules/mymodule/templates/ $ vi indexSuccess.php
hello world!
actions.class.php
$ cd /home/naka/Work/symfony/myproject/apps/myapp/modules/mymodule/actions/ $ vi actions.class.php
<?php class mymoduleActions extends sfActions { public function executeIndex() { } } ?>
# $this->forward() を消す(コメントアウトでもよい)
確認
http://symfony.example.com/index.php/mymodule
「hello world!」と表示されればOK。
ディレクトリ構造を変更したい場合
そのまま使用することが推奨されているが、変更することは可能。
デフォルト値は、
/usr/share/pear/data/symfony/config/constants.php
で定義されており、これを変更する場合は、プロジェクト内のconfigで上書きする。
/home/naka/Work/symfony/myproject/apps/myapp/config/config.php
SF_ROOT_DIR は、index.php などのコントローラ内でも定義されているので、
書き換える必要がある。
phpdoc
モジュールは必ず phpdocに合わせた形で生成する。これにより、自動的にドキュメントが生成されるようになる。
フロントコントローラ、モジュール、アクション、ビュー
http://symfony.example.com/index.php/mymodule/myaction
フロントコントローラ「index.php」は、モジュール「mymodule」と「myaction」を受け取り、適切な処理を実行する。
INFO_PATH?指定方法は「ルーティング」と呼ばれる。詳細はここ。
モジュールの作成
これは、hello world のところで書いた通り。別のモジュールを作成したい場合は、
$ cd /home/naka/Work/symfony/myproject $ symfony init-module myapp mymodule2
アクションの作成
1つのファイルに複数のアクションを定義する場合の命名規則
// mymodule/actions/action.class.php
class mymoduleActions extends sfActions { public function executeIndex() { }
public function executeRegister() { } }
アクションごとにクラスファイルを作成する場合の命名規則
// mymodule/actions/indexAction.class.php
class indexAction extends sfActions { public function execute() { } }
各々の処理の実行「前」に、共通の処理を実行する場合
以下のメソッドを入れておく。
public preExecute() { }
各々の処理の実行後に、共通の処理を実行する場合
以下のメソッドを入れておく。
public postExecute() { }
リダイレクトとフォワード
// リダイレクト $this->redirect('/mymodule2/index'); $this->redirect('http://www.example.com/');
// フォワード $this->forward('mymodule2', 'index');
ページ内へ値を出力する
$this は、現在のページオブジェクト?を意味すると考える。
たとえば、
$this->setVar('str', 'hello world'); // または $this->str = 'hello world';
とすると、ビューの中に、
<?php echo $str ?>
と書かれていれば、そこに埋め込まれる。
アクションの結果からビューを決定する
実行されるメソッドからの戻り値で、対応するビューが決定される。
- 成功
return sfView::SUCCESS;
- エラー
return sfView::ERROR;
- 特定のビューへ
return 'MyResult';
- ビューは無い。(どんなレスポンスになる?)
return sfView::NONE;
- ヘッダだけを返す
return sfView::HEADER_ONLY;
- ビューは無いが、変数を返す。
return sfView::RENDER_VAR;
アクションクラス内のexecute以外のメソッド
共通コードは、まとめる。
protected function hoge() { }
ビューの作成
view.yml
このファイルは、レイアウトファイルに埋め込まれるパラメータ定義を記述する(METAタグやタイトルなど)。
apps/shop/config/view.yml ここにある。
apps/shop/modules/main/config/view.yml に書くと、モジュール main の設定が上書きされる。
layout.php
/home/naka/Work/symfony/demosite/apps/shop/templates/layout.php これがデフォルトのレイアウト。
これが全ての画面のベースとして使用される。アクションからの出力は、
<?php echo $sf_data->getRaw('sf_content') ?>
こんな風にしてページ内に埋め込まれる。
アクションクラスの中で、
$this->setLayout("hoge");
とすると、hoge.php がレイアウトとして使用される。
<?php echo $sf_data->getRaw('sf_content') ?>
このようにしてページ内に出力される。
レイアウトを全く使用しない場合は、
textplain: none
または
$this->setLayout(false);
とする。
設定ファイル
環境ごとに設定を変える(settings.yml)
まず、設定のデフォルト値として、
/usr/share/pear/data/symfony/config/settings.yml このファイルが使用される。
製品、開発、テスト、カスタム、全て、において、設定を変える場合には、以下のようにする。
/home/naka/Work/symfony/demosite/shop/config/settings.yml を修正する。
# 製品 prod:
# 開発 dev:
# テスト test:
# カスタム hoge:
# 全てに共通 all:
設定されている値は、SfConfigクラスで管理されている。
これは、アクションのメソッド内に以下のように書くことで確認できる。
$config = sfConfig::getAll(); while(list($key, $val) = each($config)){ echo $key . " => " . $val . "<br>"; } return sfView::NONE;
SfConfigクラスにコード内からアクセスすることで、設定値を操作できる。
sfConfig::set('key', $val); $param = sfConfig::get('key');
パラメータ名は、以下の規則で決められている。
- sf_ (apps/shop/config/settings.yml)(アプリケーションの環境に関する設定)
- app_ (apps/shop/config/app.yml)(アプリケーション固有の設定)
- mod_(module名)_ (apps/shop/modules/main/config/module.yml)(モジュールごとの設定)
上に示したファイルパスはユーザが設定する場合のパス名であり、
デフォルト値は、/usr/share/pear/data/symfony/config/ の下にある。
以下に設定ファイルの例を示す。
# app.yml all: a: b: 123
この場合、以下のように取得できる。
echo sfConfig::get('app_a_b');
しかし、次のように書かれている場合、
# app.yml
all:
a: b: c: d: e: hoge
echo sfConfig::get('app_a_b_c_d_e'); // ×
これでは取得できない。階層は b までで、それ以下は配列として格納される。以下のようにすると「hoge」が取得できる。
$conf = sfConfig::get('app_a_b');
foreach ($conf as $c){ foreach ($c as $d){ foreach ($d as $e){ echo $e; } } }
yml ファイルは、PHPとしてパースされるので、PHPのコードとして記述することもできる。
<?php return array( 'all' => array( 'a' => array( 'b' => array( 'c' => array( 'd' => array( 'e' => 'hoge' ) ) ) ) ) ); ?>
これは、以下の設定ファイルと同じである。
all:
a: b: c: d: e: hoge
自動的に読み込んで定義するクラスを配置するパス(autoload.yml)
autoload.yml に書かれたパスにあるクラスファイルは自動的に読み込まれる。
このファイルは、/usr/share/pear/data/symfony/config/autoload.yml にある。
ユーザが独自に定義するクラスは以下のディレクトリに配置しておく。
- demosite/lib/
- demosite/lib/model
- demosite/apps/shop/lib/
- demosite/apps/shop/modules/main/lib
php.ini の上書きとチェック(php.yml)
php.ini の設定を上書きすることができる。
/usr/share/pear/data/symfony/config/php.yml
set: hoge : off
check: foo : off
set のところに書かれた「hoge」は上書きされる。
check のところに書かれた「foo」は、off でない場合は、例外が発生する。
モジュールの設定(module.yml)
/home/naka/Work/symfony/demosite/apps/shop/modules/main/config に置く。
アクセス制限の設定(security.yml)
/home/naka/Work/symfony/demosite/apps/shop/config/security.yml に置く。
以下のような感じで記述する。詳細は「アクセス制御」のところで。
upload: is_secure: on credentials: member
生成モジュールの設定(generator.yml)
?
入力値のバリデーション(validate.yml)
「バリデーション」のところで説明。
http://develop.ddo.jp/symfony/book/jp/1.0/configuration_practice.html#validate に書かれている内容と、試した内容が違うので、要確認。
ビューの設定(view.yml)
「ビューの作成」のところで説明済み。
ファイル構造の設定(config.php)
// symfony directories $sf_symfony_lib_dir = '/usr/share/pear/symfony'; $sf_symfony_data_dir = '/usr/share/pear/data/symfony';
プロジェクトを別の環境でも使用する可能性がある場合は、ここを書き換える必要がある。
なお、この設定は、/usr/share/pear/data/symfony/config/constants.php での設定内容を上書きする。
ヘルパー
- url_for()
- link_to()
- link_to(image_tab('hoge'), 'main/index?hoge=aaa')
- link_to('hoge', '@hoge') (routing.yml 内にルール hoge がある場合)
- link_to('hoge', 'main/index?hoge=aaa', 'post=true') (POSTで送信するフォーム形式でレンダリングされる)
- link_to(image_tab('hoge'),'main/index?hoge=aaa', 'confirm=OK?')
- link_to(image_tab('hoge'),'main/index?hoge=aaa', 'popup=true')
- link_to(image_tab('hoge'),'main/index?hoge=aaa', Array('popup' => Array(.....))) (ウィンドウを開く)
- link_to(image_tab('hoge'),'main/index', Array('query_string' => 'hoge=aaa')) (PATH_INFOでなくQueryStringを使う)
- button_to(image_tab('hoge'), 'main/index?hoge=aaa')
- image_tag('hoge.png', Array('size' => '200x100'))
- javascript_include_tag('hoge') (/js/ パスと 拡張子は省略できる)
- 'absotule=true' (絶対パスで出力する)
認証とセッション管理
actionクラス内からの $this->getUser()
var_dump($user);
とすると、object(myUser)#16 (8) { ... と表示される。
myUserクラスは /usr/naka/Work/symfony/demosite/apps/shop/lib/の下に配置されており、以下のような継承となっている。
myUser ← myBasicSecurityUser ← sfUser + sfSecurityUserインタフェース
myUserクラスで使用できるメソッドは以下の通り。
// sfBasicSecurityUserクラス public function clearCredentials() public function listCredentials() public function removeCredential($credential) public function addCredential($credential) public function addCredentials() public function hasCredential($credentials, $useAnd = true) public function isAuthenticated() public function setAuthenticated($authenticated) public function setTimedOut() public function isTimedOut() public function getLastRequestTime() public function initialize($context, $parameters = null) public function shutdown()
// sfUserクラス public function getContext() public function setCulture($culture) public function getCulture() public function getParameterHolder() public function getAttributeHolder() public function getAttribute($name, $default = null, $ns = null) public function hasAttribute($name, $ns = null) public function setAttribute($name, $value, $ns = null) public function getParameter($name, $default = null, $ns = null) public function hasParameter($name, $ns = null) public function setParameter($name, $value, $ns = null) public function shutdown()
// sfSecurityUserインタフェース public function addCredential($credential); public function clearCredentials(); public function hasCredential($credential); public function isAuthenticated(); public function removeCredential($credential); public function setAuthenticated($authenticated);
credentials
意味は、「証明書、証明物」。ロールのようなもの。
使い方は以下の通り。
- addCredential($c) (credentialを追加)
- addCredentials($c1, $c2) (credentialを複数追加)
- hasCredential($c) (credentialを持っているか?)
- removeCredential($c) (credentialを取り除く)
- clearCredentials() (すべてのcredentialを取り除く)
アクセス制限
上記の credential を使う。
モジュールの設定ファイル、/home/naka/Work/symfony/demosite/apps/shop/module/security.yml (デフォルトでは無いので作る)に、例えば以下のように記述する。
Commit: is_secure: on credentials: admin
すると、Commitメソッドの実行は、credential「admin」を持つユーザしか実行できなくなる。ちなみに、AND, OR も使える。
credentials: [ admin, superuser ] # AND credentials: [[ admin, superuser ]] # OR credentials: [[ admin, superuser ], owner] # (adnin or superuser) and owner
もし、未認証ユーザがアクセスすると($user->setAuthenticated(true) されていない。isAuthenticated() == false)、demosite/apps/shop/config/settings.yml に指定したモジュール/アクションに飛ばされる。
login_module: main login_action: index
認証済みであっても、credentialがadminでない場合(hasCredential('admin') == false)は、settings.yml で指定したモジュール/アクションに飛ばされる。
secure_module: main secure_action: index
セッション変数
sfUserクラスがセッション管理のために使用される。
actionクラス内からは、$this->getUser() で取得できる。
テンプレート内では、$sf_user 変数を使う。
セッション変数は以下のメソッドで設定・取得できる。
- setAttribute('hoge','aaa')
- getAttribute('hoge')
セッション変数内には、どのような形式(文字列、配列、連想配列、オブジェクト)でも格納することができる。
その他のセッション変数用メソッドは以下のようなものがある。
- hasAttribute('hoge'); // hoge があるか?
- getAttributeHolder()->remove('hoge'); // hogeを取り除く
1リクエスト内で値を受け渡す(forward()とか?)
sfRequestクラス内の、getAttribute(), setAttribute(), などを使う。このクラス内にもパラメータホルダー?がある。
セッションクラスの拡張
セッションクラスは、factories.yml 内の user: のところで定義されている(デフォルトは、class: myUser)
。myUserクラスは、demosite/apps/shop/lib の下に置かれている。デフォルトは、空になっており、これを拡張することができる。
全く別のクラスを使用したい場合には、factories.yml の user: のところを変更する必要がある。
セッションのタイムアウト
demosite/apps/shop/config/settings.yml で以下のように記述する。(数値は秒)
default: .settings: timeout: 1800
セッション管理機構
PHPのセッション管理機能をそのまま使用している(当然か)。
/usr/share/pear/data/symfony/config/php.yml で、session.auto_start を off に設定している。
セッションIDの再発行
Symfonyでは、ログインに成功したタイミングでセッションIDが再発行されない。
再発行するには、通常のPHPのアプリケーションと同じように、以下のようにする。
session_regenerate_id();
session.auto_start
php.ini や /usr/share/pear/data/symfony/config/php.yml(こっちが優先)に、session_auto_start の設定がある。デフォルトでは off となっているが、myUserクラスを取得した段階で、セッションが開始されるので、auto_startしているのと、それほど違いはないのかもしれない。
セッション管理は、デフォルトでは、/usr/share/pear/symfony/storage/sfSessionStorage.class.php が使われる。これは、/usr/share/pear/data/symfony/config/factories.yml で、定義されている。
$this->getUse()したとき、sfBasicSecurityUserクラスがイニシャライズされ、そこに、
$storage = $this->getContext()->getStorage();
というコードがある。ここで、新規にstorageが生成される場合は、セッションIDが発行される
sfSessionStorageクラスについて、まだコードが読みきれていないので、ここまで。
プラグイン
ショッピングカート
symfony book 記載の方法ではうまくいかなかったが、↓こんな感じでうまくいった。
プロジェクトのルートディレクトリで実行する。
$ symfony plugin-install http://plugins.symfony-project.com/sfShoppingCartPlugin
すると、
demosite/plugins/sfShoppingCartPlugin
が生成される。
開発手順
準備
プロジェクトとアプリケーションを作成しておく。
$ symfony init-project demosite $ symfony init-app shop
データベースまわり
DBを作る
とりあえず PostgreSQL で、demodb というDBを作成。ID/PWは、postgres, postgres。
postgresのパスワードは以下のようにして変更。
myproject=# alter user postgres with password 'postgres';
セキュリティの観点からの考察は置いといて、とりあえず以下のように設定。
/var/lib/pgsql/data/postgresql.conf で、
listten_addresses = 'localhost' port = 5432
/var/lib/pgsql/data/pg_hba.conf で、
# host all all 127.0.0.1/32 ident sameuser # host all all ::1/128 ident sameuser host all all 127.0.0.1/32 password
(identによる認証をコメントアウトして、パスワード認証を追加)
synfonyからDBを使えるようにする (database.xml、proepl.ini)
/home/naka/Work/symfony/demosite/config/database.yml
ここに以下のように書く。(demodb は、作成したDB名)
all: propel: class: sfPropelDatabase param: phptype: pgsql host: localhost database: demodb username: postgres password: postgres
/home/naka/Work/symfony/demosite/config/propel.ini
デフォルトでは
propel.database = mysql propel.database.createUrl = mysql://localhost/ propel.database.url = mysql://localhost/demodb
と書かれている部分を、以下のように書き換える。(demodb は、作成したDB名)
propel.database = pgsql propel.database.createUrl = pgsql://postgres:postgres@localhost/ propel.database.url = pgsql://postgres:postgres@localhost/demodb
あと、以下の1行も追加。
propel.disableIdentifierQuoting=true
synfonyにテーブル情報を教える(schema.xml)
まず、
$ symfony propel-build-schema
これにより、 /home/naka/Work/symfony/demosite/config/schema.yml の雛型が生成される。このファイルを以下のように書く。
--- propel: users: _attributes: loginid: type: longvarchar required: true passwd: type: longvarchar required: true
「type」に指定するのは一般的な型であり、以下のコマンドを実行すると、自動的に変換される。
このように書いたら、
$ symfony propel-build-sql
これで、/home/naka/Work/symfony/demosite/data/sql/ の下に、SQL文が生成される。
これを実行する。
$ symfony propel-insert-sql
DROP&CREATEしようとするので、最初の実行時はエラーが出る。2度目からは出なくなる。
モデルを作成する
以下のコマンドをたたく。
$ symfony propel-build-model
すると、/home/naka/Work/symfony/demosite/lib の下にファイルが生成される。
[naka@fc7 lib]$ ls -lR .: 合計 4 drwxr-xr-x 4 naka naka 4096 2007-08-10 23:58 model/
./model: 合計 16 -rw-r--r-- 1 naka naka 141 2007-08-10 23:58 Users.php -rw-r--r-- 1 naka naka 167 2007-08-10 23:58 UsersPeer.php drwxr-xr-x 2 naka naka 4096 2007-08-10 23:58 map/ drwxr-xr-x 2 naka naka 4096 2007-08-10 23:58 om/
./model/map: 合計 4 -rw-r--r-- 1 naka naka 752 2007-08-10 23:58 UsersMapBuilder.php
./model/om: 合計 20 -rw-r--r-- 1 naka naka 6305 2007-08-10 23:58 BaseUsers.php -rw-r--r-- 1 naka naka 8843 2007-08-10 23:58 BaseUsersPeer.php
作成するテーブル1つにつき、phpファイルが5個生成される。らしい。
この例では、テーブル「users」を作ったが、BaseUsers,php、BaseUsersPeer.php、Users.php、UsersPeer.php、UsersMapBuilder.php が生成された。
BaseUsers.php は、テーブル「users」のカラム名と同じ名前のパラメータとそのパラメータへのアクセサメソッドを持つクラスである。
BaseUsersPeer.php は、目的とするデータを抽出するためのメソッドを持つクラスである。
Users.php と UsersPeer.php は、それぞれ、BaseUsers.php と BaseUsersPeer.php のクラスを継承したクラスを定義しており、メソッドなどを追加する場合は、こっちのファイルを書き換える。schema.yml を書き換えてから、 symfony propel-build-model を実行すると、Base系は上書きされるが、それを継承したクラスは上書きされずに残る。
UsersMapBuilder.phpは、ランタイム用にデータベースモデルを構築するためのクラスファイルである。
(参考:http://codezine.jp/a/article/aid/837.aspx?p=2)
バリデーション
/home/naka/Work/symfony/demosite/apps/shop/modules/main/validate/login.yml を以下のように作成する。(動作する例なので、チェック内容に意味はない)
fields: loginid: required: Yes msg: id is required. sfStringValidator: min: 2 min_error: IDは2文字以上です max: 10 max_error: IDは10文字以下です
ここでは、「sfStringValidator」を使用しているが、バリデーションの種類には以下のものがある。
- sfCallbackValidator
- sfCompareValidator
- sfDataValidator
- sfEmailValidator
- sfFileValidator
- sfHtmloValidator
- sfNumberValidator
- sfRegexValidator
- sfStringValidator
- sfUrlValidator
メモ(未分類)
propelってなに?
ORマッパーのひとつ。 (http://symfony.jp/index.php?propel)
デバッグモード
index.php の中で、define('SF_ENVIRONMENT', 'dev'); とする。
アプリケーション名を指定しない状態で、PATH_INFOを取れる?
とりあえず、こんな感じで、ごまかしてる。httpd.conf 内での、mod_rewriteの設定。
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/css/
RewriteCond %{REQUEST_URI} !^/js/
RewriteCond %{REQUEST_URI} !^/images/
RewriteCond %{REQUEST_URI} !^/sf/
RewriteCond %{REQUEST_URI} !^/ejrparts/ [OR]
RewriteCond %{REQUEST_URI} ^/main/
RewriteRule ^/(.+)$ /index.php/$1
DocumentRoot に指定した、/home/naka/Work/symfony/demosite/web 直下に、.htaccess があり、適切な Rewriteルールが書かれていた。これが動作しなかったのは、httpd.conf で、全体のAllowOverride が None となっていたため。上記のルールを消して、AllowOverride All として再起動したら、.htaccessが機能して、期待通りの動作をするようになった。
アクションクラスのメソッド内で取得可能なフレームワークのコアオブジェクト。
$request = $this->getRequest(); $userSession = $this->getUser(); $response = $this->getResponse(); $controller = $this->getController(); $context = $this->getContext();
アクションから直接コンテンツを出力する
echo "<html>hoge</html>"; return sfView::NONE;
または
return $this->renderText("<html>hoge</html>");
X-JSONヘッダでJSONを返す
$output = '<"name","hoge"],["addr","tokyo">'; $this->getResponse()->setHttpHeader("X-JSON", '('.$output.')'); return sfView::HEADER_ONLY;
ビューを指定する
特定のテンプレートを指定したい場合は以下のようにする。
$this->setTemplate('menu'); return sfView::SUCCESS;
とすると、menuSuccess.php が使用される。
return sfView::ERROR;
としてreturnすると、 menuError.php が使用される。
404へリダイレクト
$this->forward404();
エラーページは、/home/naka/Work/symfony/demosite/apps/shop/config/setting.yml で、
error_404_module error error_404_action error404
と書いておくと、errorモジュールのerror404メソッドが呼ばれる。
このモジュールは、同じアプリケーション(この例では、shop)の下に作成しておく。
条件付きフォワード/リダイレクト
- forwardIf()
- forwardUndless()
- forward404If()
- forward404Unless()
- redirectIf()
- redirectUnless()
$this はどのオブジェクトを指している??
- アクションクラス内
sfActions (action/sfActions.class.php) - テンプレート内
sfPHPview (view/sfPHPview.class.php)。※これを直接使うことはほとんどない?
アクションクラス内で、リクエスト関連のパラメータにアクセスする
アクションクラスの $this は、
自作アクション ← sfActions ← sfAction ← sfComponent
というようにクラスを継承している。以下に示す getRequest()メソッドは、sfComponentクラス内で定義されている。
$req = $this->getRequest(); echo $req->getMethod() . "<br>"; // sfRequest::GETもしくはsfRequest::POST echo $req->getMethodName() . "<br>"; // メソッド名)(GET/POSTなど) echo $req->getHttpHeader('Host') . "<br>"; // リクエストヘッダ echo $req->getCookie('symfony') . "<br>"; // Cookie echo $req->isXmlHttpRequest(); // Ajaxか echo $req->isSecure() . "<br>"; // SSLか echo $req->hasParameter('hoge') . "<br>"; // 指定したパラメータがあるか echo $req->getParameter('hoge') . "<br>"; // パラメータ取得 echo $req->getParameterHolder()->getAll() . "<br>"; // 全パラメータ(Array) echo $req->getUri(). "<br>"; // REQUEST_URI echo $req->getPathInfo() . "<br>"; //PATH_INFO echo $req->getReferer() . "<br>"; // リファラー echo $req->getHost() . "<br>"; // Host echo $req->getScriptName() . "<br>"; // フロントコントローラ echo $req->getLanguage() . "<br>"; // array echo $req->getCharsets() . "<br>"; //array echo $req->getAcceptableContentType() . "<br>"; // array return sfView::NONE;
その他のメソッドは、sfWebRequest.class.php を参照。
$ grep "function get" /usr/share/pear/symfony/request/sfWebRequest.class.php
テンプレート内で利用できる変数
/usr/share/pear/symfony/view/sfPHPView.class.php 内で、
$context = $this->getContext();
$shortcuts = array( 'sf_context' => $context, 'sf_params' => $context->getRequest()->getParameterHolder(), 'sf_request' => $context->getRequest(), 'sf_user' => $context->getUser(), 'sf_view' => $this, );
こんな風に書いてある。テンプレート内では以下の変数を使用する。
$sf_context
<?php echo $sf_context->getActionName() ?>
/usr/share/pear/symfony/util/sfContextg.class.php で定義されている。
$sf_params
<?php echo $sf_params->getDefaultNamespace() ?>
/usr/share/pear/symfony/util/sfParameterHolder.class.php で定義されている。
$sf_request
<?php echo $sf_request->getMethod() ?>
/usr/share/pear/symfony/request/sfRequest.class.php で定義されている。
$sf_user
<?php echo $sf_user->getCulture() ?>
/usr/share/pear/symfony/user/sfUser.class.php で定義されている。
$sf_view
<?php echo $sf_view->getExtension() ?>
/usr/share/pear/symfony/view/sfView.class.php で定義されている。
$sf_data
<?php echo $sf_data->getRaw('sf_content') ?>
$sf_data は、sfOutputEscaperArrayDecorator クラスのインスタンスである。
これは、以下のようにすると分かる。
var_dump($sf_data instanceof sfOutputEscaperArrayDecorator