コントローラ | 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 コメント:
コメントを投稿