コントローラ | Symfony2日本語ドキュメント
http://docs.symfony.gr.jp/symfony2/quick_tour/the_controller.html
3. コントローラ
第1部と第2部を読み終えても、まだ読み続けているの? あなたはもうすっかり Symfony2 中毒になっていますね! 余談はこれくらいにして、コントローラで何ができるのかを見ていきましょう。
3.1. フォーマットの使用
今日では、Web アプリケーションは単なる HTML ページ以上のモノを配信できるはずです。 Web サービスには、RSS フィード用の XML から、Ajax リクエスト用の JSON まで、選択するに足る種々のフォーマットがあります。 Symfony2 では、これらのフォーマットを直接サポートしています。 では、routing.yml を編集して、xml の値を持つ _format を追加してみましょう:
# src/Sensio/HelloBundle/Resources/config/routing.yml
hello:
pattern: /hello/{name}
defaults: { _controller: HelloBundle:Hello:index, _format: xml }
<!-- src/Sensio/HelloBundle/Resources/config/routing.xml -->
<route id="hello" pattern="/hello/{name}">
<default key="_controller">HelloBundle:Hello:index</default>
<default key="_format">xml</default>
</route>
// src/Sensio/HelloBundle/Resources/config/routing.php
$collection->add('hello', new Route('/hello/{name}', array(
'_controller' => 'HelloBundle:Hello:index',
'_format' => 'xml',
)));
追加するのは次の赤字の部分です。
defaults: { _controller: HelloBundle:Hello:index, _format: xml }
次に、index.html.twig がある場所と同じところに index.xml.twig テンプレートを作成します:
<!-- src/Sensio/HelloBundle/Resources/views/Hello/index.xml.twig -->
<hello>
<name>{{ name }}</name>
</hello>
最後に、フォーマットに応じてテンプレートを選択する必要があるので、コントローラに対して次のような変更を行います:
// src/Sensio/HelloBundle/Controller/HelloController.php
public function indexAction($name, $_format)
{
return $this->render(
'HelloBundle:Hello:index.'.$_format.'.twig',
array('name' => $name)
);
}
これで完了です。 Symfony2 では、標準フォーマットに関しては、レスポンスに適切な Content-Type ヘッダを自動的に選択します。 あるアクションに対して、異なるフォーマットをサポートしたい場合には、パターンに {_format} プレースホルダーを使います:
# src/Sensio/HelloBundle/Resources/config/routing.yml
hello:
pattern: /hello/{name}.{_format}
defaults: { _controller: HelloBundle:Hello:index, _format: html }
requirements: { _format: (html|xml|json) }
<!-- src/Sensio/HelloBundle/Resources/config/routing.xml -->
<route id="hello" pattern="/hello/{name}.{_format}">
<default key="_controller">HelloBundle:Hello:index</default>
<default key="_format">html</default>
<requirement key="_format">(html|xml|json)</requirement>
</route>
// src/Sensio/HelloBundle/Resources/config/routing.php
$collection->add('hello', new Route('/hello/{name}.{_format}', array(
'_controller' => 'HelloBundle:Hello:index',
'_format' => 'html',
), array(
'_format' => '(html|xml|json)',
)));
この時点では、/hello/Fabien.xml または /hello/Fabien.json のような URL に対して、コントローラが呼び出されます。
requirements エントリーには、{_format} プレースホルダーが一致する必要のある正規表現を定義します。 この例では、/hello/Fabien.js リソースにリクエストしようとすると、_format の条件にマッチしないので、HTTP 404 エラーを返します。(訳注: リクエスト URI が /hello/Fabien.xml のとき、$name={name}=Fabien、$_format={_format}=xml が代入されるイメージです。)
3.2. レスポンスオブジェクト
さて、Hello コントローラに戻りましょう:
// src/Sensio/HelloBundle/Controller/HelloController.php
public function indexAction($name)
{
return $this->render('HelloBundle:Hello:index.html.twig', array('name' => $name));
}
render() メソッドは、テンプレートをレンダーリングし、Response オブジェクトを返します。 レスポンスをブラウザーに送信する前に、それを調整することができます。例として、 Content-Type を変更してみましょう:
public function indexAction($name)
{
$response = $this->render('HelloBundle:Hello:index.html.twig', array('name' => $name));
$response->headers->set('Content-Type', 'text/plain');
return $response;
}
シンプルなテンプレート用に、手動で Response オブジェクトを作成して、数ミリ秒を節約することもできます:
public function indexAction($name)
{
return new Response('Hello '.$name);
}
コントローラで Ajax リクエストのために JSON レスポンスを送り返す必要があるとき、これは本当に役立ちます。
3.3. エラーの管理
実体が見つからない場合、HTTP プロトコルで上手に処理するべきなので、404 レスポンスを返します。 これは、組込みの HTTP 例外をスローすることで簡単にできます:
public function indexAction()
{
$product = // データベースからオブジェクトを取得
if (!$product) {
throw new NotFoundHttpException('The product does not exist.');
}
return $this->render(...);
}
NotFoundHttpException は、ブラウザーに HTTP 404 レスポンスを返します。
3.4. リダイレクトとフォワード
ユーザーを別ページにリダイレクトする場合は、RedirectResponse クラスを使用します:
return new RedirectResponse($this->generateUrl('hello', array('name' => 'Lucas')));
generateUrl() メソッドは、router ヘルパーを使用する、前の generate() メソッドと同じです。 このメソッドは、ルート名とパラメータの配列を引数にとり、わかりやすい関連 URL を返します。
forward() メソッドで、簡単に別ページにアクションをフォワードすることもできます。 actions ヘルパーに関しては、内部でサブリクエストを行いますが、forward() メソッドでは変更を加えることのできる Response オブジェクトを返します:
$response = $this->forward('HelloBundle:Hello:fancy', array('name' => $name, 'color' => 'green'));
// レスポンスに対して何かを行う、またはレスポンスを直接返す
3.5. リクエストオブジェクト
コントローラは、ルーティングのプレースホルダー設定値の他に、Request オブジェクトへのアクセス権も持っています:
$request = $this->get('request');
$request->isXmlHttpRequest(); // Ajax リクエストかどうか?
$request->getPreferredLanguage(array('en', 'fr'));
$request->query->get('page'); // $_GET パラメータを取得
$request->request->get('page'); // $_POST パラメータを取得
テンプレートでは、app.request 変数経由で、Request オブジェクトにアクセスすることもできます:
{{ app.request.query.get('page') }}
{{ app.request.parameter('page') }}
3.6. セッション
HTTP プロトコルがステートレスでも、Symfony2 はクライアント (ブラウザーを使用している人や、ボット、もしくは Web サービス) を表現する素晴らしいセッションオブジェクトを提供します。 Symfony2 は、2 つのリクエスト間において、PHP 固有のセッションを用いて、セッション属性をクッキーに保存します。
任意のコントローラから簡単に、セッション情報の保存と取得ができます:
$session = $this->get('request')->getSession();
// 後のユーザーリクエスト時に再利用する属性を保存
$session->set('foo', 'bar');
// 別のリクエスト用の別のコントローラに
$foo = $session->get('foo');
// ユーザーロケールを設定
$session->setLocale('fr');
すぐ次のリクエストでのみ利用可能なスモールメッセージを格納することもできます(訳注: setFlash メソッドでセッションに格納したメッセージは、そのメッセージを格納したリクエストの後、その次のリクエスト完了後に自動的に削除されます。):
// すぐ次のリクエスト用のメッセージを保存 (コントローラで)
$session->setFlash('notice', 'Congratulations, your action succeeded!');
// 次のリクエスト時に復活するメッセージを表示 (テンプレートで)
{{ app.session.flash('notice') }}
3.7. 最後に
これで終わりです。 10 分もかからなかったと思います。 第 1 部ではバンドルを簡単に紹介しました。 これまでに学んできた機能のすべては、コアフレームワークのバンドルの一部になります。 バンドルのおかげで、Symfony2 にあるものすべてを拡張または置換することができるのです。 それが本チュートリアルの次部のトピックになります。
updated redirected response - 2011-02-21 09:15:24
https://github.com/symfony/symfony-docs/blob/master/quick_tour/the_controller.rst
0 コメント:
コメントを投稿