Practical symfony

4日目: ControllerとView

About

You are currently reading "Practical symfony" which is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.

Jobeet Links

Symfony 2.0 Preview Release

Chapter Content

MVCアーキテクチャ

レイアウト

スタイルシート、画像、JavaScript

jobモジュールのホームページ

アクション

テンプレート

Jobページのテンプレート

~スロット~

求人ページのアクション

リクエストとレスポンス

リクエスト

レスポンス

また明日

symfony training
Be trained by symfony experts
Apr 12: Paris (What's new in 1.3/1.4 - Français)
Apr 21: Paris (1.4 + Doctrine - Français)
Apr 28: Online (What's new in 1.3/1.4 - Français)
and more...

Search


powered by google
You are currently browsing "Practical symfony" in Japanese for the 1.2 version - Doctrine edition - Switch to version: - Switch to ORM: - Switch to language:
Creative Commons License This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.
This version of symfony is not maintained anymore.
If some of your projects still use this version, consider upgrading as soon as possible.
Practical symfony (Doctrine edition)
Buy Practical symfony (Doctrine edition) from amazon.com

昨日はsymfonyがどうやってデータベースエンジン間の違いを吸収していたり、オブジェクト指向クラスに変換しているかを見ました。 そしてDoctrineでデータベーススキーマを記述したりテーブルを作成したり初期データをデータベースに投入したりしました。

今日は昨日作ったjobモジュールの基本的なカスタマイズを続けます。 jobモジュールはJobeetに必要なコードをすべて有しています:

すでにコードの準備ができてるのでモックアップに近づくようにリファクタリングしてゆきます。

MVCアーキテクチャ

もしフレームワークなしでPHPでWebサイトの開発を行うならば、HTMLごとに1つのPHPファイルのパラダイムを使うでしょう。 これらのPHPファイルは同じ種類の構造を含んでます。 それは初期化、全体設定、ページリクエストのためのビジネスロジックやデータベースからレコードの検索、最終的にはページを生成するためのHTMLコードを含んでいます。

HTMLからロジックを分離するためにテンプレートエンジンを利用しているかもしれません。 ビジネスロジックからモデルとのやりとりを分離するためにデータベース抽象化レイヤーを利用しているでしょう。 しかしたいていの場合、メンテナンスが悪夢になるたくさんのコードで終わることになります。 速く作れますが、時間が経つにつれて、とりわけ変更するのが難しくなります。 どのように作りどのように動作するのかあなた以外は誰も理解できないからです。

これら全ての問題に対し、よい解決方法があります。 Web開発の分野では近年コーディングのための最適解として認識されているのはMVC~デザインパターン~です。 手短に言えば、MVCデザインパターンはコードの性質ごとに体系化する方法を定義しています。 このパターンは3つのレイヤーに分けられます。

これらフロントコントローラーは実際の動作はアクション(action)で行われます。 昨日見たようにこれらアクションはモジュール(module)で論理的にグループ化されます。

MVC

今日は、ホームページと求人ページをカスタマイズするために2日目で定義したモックアップを使います。 これらを動的なものにもします。 この先、symfonyのディレクトリを構造とレイヤーの間でコードを分離する方法を示すためにたくさんの異なるファイルでたくさんの調整を行います。

レイアウト

まず、モックアップをじっと見てみると各ページのほとんどが同じ部品であることに気づくでしょう。 PHPやHTMLであろうとなかろうと、コードの重複は悪いことです。 だからコードが重複しているView要素を抑える方法が必要となります。

この問題を解決する1つの方法として各テンプレートでヘッダーとフッターを定義する方法があります:

ヘッダーとフッター

しかしこの場合ヘッダーやフッターは有効なHTMLを含んでいません。 よい方法であることは違いありません。 車輪の再発明をする代わりにこの問題を解決するため別のデザインパターンを使うことにします。 それはDecoratorデザインパターンです。 Decoratorデザインパターンは別のやり方で問題を解決します。

グローバルテンプレートによって表示されるコンテンツの後にデコレートされるうテンプレートを使います。

symfonyではグローバルテンプレートを~レイアウト~と呼びます:

レイアウト

アプリケーションのデフォルトテンプレートとしてlayout.phpが呼び出されます。 それはapps/frontend/templatesディレクトリにあります。 このディレクトリにはアプリケーションのグローバルテンプレート全てが置かれます。

symfonyのデフォルトレイアウトを下記コードに置き換えましょう:

<!-- apps/frontend/templates/layout.php -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  <head>
    <title>Jobeet - Your best job board</title>
    <link rel="shortcut icon" href="/favicon.ico" />
    <?php include_javascripts() ?>
    <?php include_stylesheets() ?>
  </head>
  <body>
    <div id="container">
      <div id="header">
        <div class="content">
          <h1><a href="<?php echo url_for('job/index') ?>">
            <img src="/images/logo.jpg" alt="Jobeet Job Board" />
          </a></h1>
 
          <div id="sub_header">
            <div class="post">
              <h2>Ask for people</h2>
              <div>
                <a href="<?php echo url_for('job/index') ?>">Post a Job</a>
              </div>
            </div>
 
            <div class="search">
              <h2>Ask for a job</h2>
              <form action="" method="get">
                <input type="text" name="keywords"
                  id="search_keywords" />
                <input type="submit" value="search" />
                <div class="help">
                  Enter some keywords (city, country, position, ...)
                </div>
              </form>
            </div>
          </div>
        </div>
      </div>
 
      <div id="content">
        <?php if ($sf_user->hasFlash('notice')): ?>
          <div class="flash_notice">
            <?php echo $sf_user->getFlash('notice') ?>
          </div>
        <?php endif; ?>
 
        <?php if ($sf_user->hasFlash('error')): ?>
          <div class="flash_error">
            <?php echo $sf_user->getFlash('error') ?>
          </div>
        <?php endif; ?>
 
        <div class="content">
          <?php echo $sf_content ?>
        </div>
      </div>
 
      <div id="footer">
        <div class="content">
          <span class="symfony">
            <img src="/images/jobeet-mini.png" />
            powered by <a href="http://www.symfony-project.org/">
            <img src="/images/symfony.gif" alt="symfony framework" />
            </a>
          </span>
          <ul>
            <li><a href="">About Jobeet</a></li>
            <li class="feed"><a href="">Full feed</a></li>
            <li><a href="">Jobeet API</a></li>
            <li class="last"><a href="">Affiliates</a></li>
          </ul>
        </div>
      </div>
    </div>
  </body>
</html>

symfonyの~テンプレート~は単なるプレーンなPHPファイルです。 レイアウトテンプレートにおいて、PHP関数の呼び出しとPHP変数への参照が見られます。 ~$sf_content~はもっとも興味深い変数です: この変数はsymfonyによって定義されアクションによって生成されるHTMLを格納します。

jobモジュール(http://jobeet.localhost/frontend_dev.php/job)を見ると、すべてのアクションがレイアウトによってデコレートされていることがわかります。

スタイルシート、画像、JavaScript

このチュートリアルの目的はWebデザインではないので、Jobeetで必要なすべてのアセットはすでに用意されています: 画像ファイルをダウンロードしてweb/images/ディレクトリに設置します; スタイルシートファイルをダウンロードしてweb/css/ディレクトリに設置します。

レイアウトにおいて、ファビコン(favicon)を含めることができます。 Jobeetのファビコンをダウンロードしてweb/ディレクトリに設置します。

レイアウトとアセットつきのjobモジュール

標準では、generate:projectタスクはプロジェクトのアセットとして3つのディレクトリを生成します。 web/imagesは画像用、web/css/は~スタイルシート~用、web/jsはJavaScript用です。 これはsymfonyで定義される多くの~規約~の1つですが、もちろんwebディレクトリの下であればどこにでも置くことはできます。

鋭い読者ならmain.cssがデフォルトレイアウトのどこにも記述されていないということに気づくでしょう。 main.cssは生成されたHTMLの中に確かに含まれています。 しかしどこにもみあたりません。どうやって可能にしているのでしょうか?

スタイルシートはレイアウトの<head>タグブロックで見つかるinclude_stylesheets()関数の呼び出しによって インクルードされました。 include_stylesheets()関数はヘルパー(helper)と呼ばれます。 ヘルパーはsymfonyによって定義される関数で、パラメーターを受け取りHTMLコードを返します。 たいていの場合、ヘルパーによって時間が節約され、テンプレートで頻繁に使われるコードスニペットをパッケージにします。

include_stylesheets()ヘルパーはスタイルシート用に<link>タグを生成します。

しかしヘルパーはどうやって格納すべきスタイルシートを知るのでしょうか?

Viewレイヤーはアプリケーションの設定ファイルであるview.ymlのスタイルシートのキーを編集することで設定できます。 generate:appタスクがデフォルトで生成するview.ymlは次のとおりです:

# apps/frontend/config/view.yml
default:
  http_metas:
    content-type: text/html
 
  metas:
    #title:        symfony project
    #description:  symfony project
    #keywords:     symfony, project
    #language:     en
    #robots:       index, follow
 
  stylesheets:    [main.css]
 
  javascripts:    []
 
  has_layout:     on
  layout:         layout

view.ymlファイルはアプリケーションの全てのテンプレートのdefaultを設定します。 たとえば、stylesheetsエントリはアプリケーション全てのページに含むためのスタイルシートファイルの配列が定義されます(含めたファイルは include_stylesheets()ヘルパーから呼び出されます)。

標準のview.ymlファイルには、参照ファイルとしてmain.cssが設定されており、/css/main.cssではありません。 実際のところ、symfonyによって相対パスに~プレフィックス~の/css/がつけられるので両方の定義は同等です。

多くのファイルが定義されたのであれば、定義と同じ順序でこれらをインクルードします:

stylesheets:    [main.css, jobs.css, job.css]

media属性を変更し、.cssを省略することもできます。:

stylesheets:    [main.css, jobs.css, job.css, print: { media: print }]

この設定では下記のような表示となります:

<link rel="stylesheet" type="text/css" media="screen"
  href="/css/main.css" />
<link rel="stylesheet" type="text/css" media="screen"
  href="/css/jobs.css" />
<link rel="stylesheet" type="text/css" media="screen"
  href="/css/job.css" />
<link rel="stylesheet" type="text/css" media="print"
  href="/css/print.css" />

view.yml設定ファイルはアプリケーションによって使われるデフォルトの~レイアウト~も定義します。 デフォルトでは、名前はlayoutで、symfonyはすべてのページをlayout.phpファイルでデコレートします。 has_layoutエントリをfalseに切り替えることでデコレーションプロレスを無効にすることもできます。

jobs.cssファイルはホームページに必要とされるときだけ読み込まれ、job.cssファイルは求人ページだけに適用されます。 view.ymlファイルはモジュール単位でカスタマイズできます。 アプリケーションのview.ymlファイルはmain.cssだけを持つように変更します:

# apps/frontend/config/view.yml
stylesheets:    [main.css]

jobモジュールのViewをカスタマイズするには、apps/frontend/modules/job/configディレクトリでview.ymlファイルを生成します:

# apps/frontend/modules/job/config/view.yml
indexSuccess:
  stylesheets: [jobs.css]
 
showSuccess:
  stylesheets: [job.css]

indexSuccessshowSuccessセクション(indexshowアクションで使われるテンプレート名であり、後で出てきます)の下で、アプリケーションview.ymlのデフォルトセクションで見たようなエントリーを使ってカスタマイズできます。 全ての固有のエントリーはアプリケーションのコンフィギュレーションとしてマージされます。 allセクションを使えば、モジュールの全てのアクションに対してコンフィギュレーションを定義できます。

経験上、設定ファイル経由で変更可能なのは、PHPコードで完成するのと同じことです。 例としてjobモジュールにview.ymlファイルを作る代わりにテンプレートからスタイルシートを呼び出すための~use_stylesheet()ヘルパー~を使うこともできます:

<?php use_stylesheet('main.css') ?>

スタイルシートを全体に含めるために、レイアウト内で上記のヘルパーを使うことも可能です。

このメソッドもしくは他のメソッドを選ぶのは本当に好みの問題です。 view.ymlファイルはモジュールのすべてのアクション用の内容を定義する方法を提供します。 これはテンプレートでは定義できませんが、コンフィギュレーションはとても静的です。 一方で、use_stylesheet()~ヘルパー~を利用すればより柔軟になり、さらに、同じ場所ですべての内容: スタイルシートの定義とHTMLコードを同じ位置で定義されます。 Jobeetに関しては、use_stylesheet()ヘルパーを使うので、先ほど作ったview.ymlを削除してuse_stylesheet()を呼び出してjobテンプレートを更新できます:

<!-- apps/frontend/modules/job/indexSuccess.php -->
<?php use_stylesheet('jobs.css') ?>
 
<!-- apps/frontend/modules/job/showSuccess.php -->
<?php use_stylesheet('job.css') ?>

対照的に、JavaScriptのコンフィギュレーションもview.ymljavascriptsエントリーを使ったり、テンプレート内から~use_javascript()ヘルパー~で呼び出すことで行うことができます。

jobモジュールのホームページ

3日目に見たように、ホームページはjobモジュールのindexアクションで作られています。 indexアクションはページのController部分で、関連テンプレートであるindexSuccess.phpはViewの部分です:

apps/
  frontend/
    modules/
      job/
        actions/
          actions.class.php
        templates/
          indexSuccess.php

アクション

各~アクション~はクラスメソッドで表されます。 ホームページではjobActions(モジュール名の末尾にActionsをつけたもの)クラスとexecuteIndex(executeの末尾にアクション名をつけたもの)メソッドが使われます。 データベースから全ての求人情報を取得します:

// apps/frontend/modules/job/actions/actions.class.php
class jobActions extends sfActions
{
  public function executeIndex(sfWebRequest $request)
  {
    $this->jobeet_job_list = Doctrine::getTable('JobeetJob')
      ->createQuery('a')
      ->execute();
  }
 
  // ...
}

コードをよく見てみましょう: すべての求人情報を検索するクエリを作るためにexecuteIndex()メソッド(Controller)はテーブルのJobeetJobを呼び出します。 jobeet_job_listオブジェクトプロパティに割り当てられたJobeetJobオブジェクトのDoctrine_Collectionを返します。 このような全てオブジェクトプロパティは自動的にテンプレート(View)に渡されます。 ControllerからのデータをViewに渡すには、下記のように新しいプロパティを作ります:

public function executeFooBar(sfWebRequest $request)
{
  $this->foo = 'bar';
  $this->bar = array('bar', 'baz');
}

このコードはテンプレートからアクセス可能な$foo$bar変数を定義しています。

テンプレート

デフォルトでは、アクションに関連する~テンプレート~はsymfonyによって推測されます(Successをサフィックスとして持つアクションの名前)。

indexSuccess.phpテンプレートはすべての求人用のHTMLテーブルを生成します。 現在のテンプレートコードは次のとおりです:

<!-- apps/frontend/modules/job/templates/indexSuccess.php -->
<?php use_stylesheet('jobs.css') ?>
 
<h1>Job List</h1>
 
<table>
  <thead>
    <tr>
      <th>Id</th>
      <th>Category</th>
      <th>Type</th>
<!-- more columns here -->
      <th>Created at</th>
      <th>Updated at</th>
    </tr>
  </thead>
  <tbody>
    <?php foreach ($jobeet_job_list as $jobeet_job): ?>
    <tr>
      <td>
        <a href="<?php echo url_for('job/show?id='.$jobeet_job->getId()) ?>">
          <?php echo $jobeet_job->getId() ?>
        </a>
      </td>
      <td><?php echo $jobeet_job->getCategoryId() ?></td>
      <td><?php echo $jobeet_job->getType() ?></td>
<!-- more columns here -->
      <td><?php echo $jobeet_job->getCreatedAt() ?></td>
      <td><?php echo $jobeet_job->getUpdatedAt() ?></td>
    </tr>
    <?php endforeach; ?>
  </tbody>
</table>
 
<a href="<?php echo url_for('job/new') ?>">New</a>

テンプレートコード内ではforeachJobオブジェクト($jobeet_job_list)のリストを繰り返し取得して、各求人ごとのカラムごとに出力させます。 覚えておいて欲しいのは、カラムの値はgetから始まりカラム名の~キャメルケース|コードのフォーマッティング~(camelCase)になっているアクセサーメソッドが呼び出されていることです(たとえば、getCreatedAt()メソッドはcreate_atカラムからデータを取得します)。

利用できるカラムのみを表示するように整理してみましょう:

<!-- apps/frontend/modules/job/templates/indexSuccess.php -->
<?php use_stylesheet('jobs.css') ?>
 
<div id="jobs">
  <table class="jobs">
    <?php foreach ($jobeet_job_list as $i => $job): ?>
      <tr class="<?php echo fmod($i, 2) ? 'even' : 'odd' ?>">
        <td class="location"><?php echo $job->getLocation() ?></td>
        <td class="position">
          <a href="<?php echo url_for('job/show?id='.$job->getId()) ?>">
            <?php echo $job->getPosition() ?>
          </a>
        </td>
        <td class="company"><?php echo $job->getCompany() ?></td>
      </tr>
    <?php endforeach; ?>
  </table>
</div>

ホームページ

テンプレートの中で呼び出されているurl_for()関数はsymfonyのヘルパーで、明日詳しく説明します。

Jobページのテンプレート

求人ページのテンプレートをカスタマイズしましょう。 showSuccess.phpファイルを開いて、下記コードに置き換えてください:

<!-- apps/frontend/modules/job/templates/showSuccess.php -->
<?php use_stylesheet('job.css') ?>
<?php use_helper('Text') ?>
 
<div id="job">
  <h1><?php echo $job->getCompany() ?></h1>
  <h2><?php echo $job->getLocation() ?></h2>
  <h3>
    <?php echo $job->getPosition() ?>
    <small> - <?php echo $job->getType() ?></small>
  </h3>
 
  <?php if ($job->getLogo()): ?>
    <div class="logo">
      <a href="<?php echo $job->getUrl() ?>">
        <img src="/uploads/jobs/<?php echo $job->getLogo() ?>"
          alt="<?php echo $job->getCompany() ?> logo" />
      </a>
    </div>
  <?php endif; ?>
 
  <div class="description">
    <?php echo simple_format_text($job->getDescription()) ?>
  </div>
 
  <h4>How to apply?</h4>
 
  <p class="how_to_apply"><?php echo $job->getHowToApply() ?></p>
 
  <div class="meta">
    <small>posted on <?php echo date('m/d/Y', strtotime($job->getCreatedAt())) ?></small>
  </div>
 
  <div style="padding: 20px 0">
    <a href="<?php echo url_for('job/edit?id='.$job->getId()) ?>">
      Edit
    </a>
  </div>
</div>

テンプレートは求人情報を表示するためアクションから渡される$job変数を使います。 テンプレートへ渡す変数を$jobeet_jobから$jobにリネームするので、showアクションの該当箇所を変更してください(変数が2カ所にあることに注意してください):

// apps/frontend/modules/job/actions/actions.class.php
public function executeShow(sfWebRequest $request)
{
  $this->job = Doctrine::getTable('JobeetJob')-> find($request->getParameter('id'));
  $this->forward404Unless($this->job);
}

仕事の説明文で使われているsimple_format_text()ヘルパーはHTMLを整形します。 たとえば、改行を<br />へ置き換えます。 このヘルパーはTextヘルパーグループに属しており、デフォルトではロードされないので~use_helper()ヘルパー~を使って手動でロードさせています。

求人ページ

~スロット~

今のところ、全てのページのタイトルはレイアウトの<title>タグで定義されています:

<title>Jobeet - Your best job board</title>

しかし求人ページでは会社名や役職のようなもっと有用な情報を提供したいと考えます。

symfonyではレイアウトの領域が表示されるテンプレートに依存するとき、スロットを定義する必要があります:

スロット

動的にタイトルを変更するためにレイアウトにスロットを追加します:

// apps/frontend/templates/layout.php
<title><?php include_slot('title') ?></title>

各スロットは(title)という名前で定義され、include_slot()ヘルパーで表示されます。 今からshowSuccess.phpテンプレートの始めに求人ページのコンテンツについて定義したslot()ヘルパーを使うようにします:

// apps/frontend/modules/job/templates/showSuccess.php
<?php slot(
  'title',
  sprintf('%s is looking for a %s', $job->getCompany(), $job->getPosition()))
?>

もしタイトルが複雑なら、slot()ヘルパーをコードブロックで使うこともできます:

// apps/frontend/modules/job/templates/showSuccess.php
<?php slot('title') ?>
  <?php echo sprintf('%s is looking for a %s', $job->getCompany(), $job->getPosition()) ?>
<?php end_slot(); ?>

(ホームページのような)ページの中には、一般的なタイトルが必要となる場合があります。 テンプレート内で同じタイトルを何回も繰り返す代わりに、レイアウトでデフォルトのタイトルを定義します:

// apps/frontend/templates/layout.php
<title>
  <?php if (!include_slot('title')): ?>
    Jobeet - Your best job board
  <?php endif; ?>
</title>

include_slot()ヘルパーはスロットが定義されていればtrueを返します。 よって、テンプレートコンテンツ内にtitleスロットが定義されていればそれを使い、デフォルトタイトルを使うようになります:

ごくわずかですがinclude_で始まるヘルパーを見てきました。 これらのヘルパーはHTMLを出力し、たいていの場合、内容を返すためだけにget_ヘルパーに対応するものがあります:

<?php include_slot('title') ?>
<?php echo get_slot('title') ?>
 
<?php include_stylesheets() ?>
<?php echo get_stylesheets() ?>

求人ページのアクション

求人のページはjobモジュールのexecuteShow()メソッドで定義されるshowアクションで生成されます:

class jobActions extends sfActions
{
  public function executeShow(sfWebRequest $request)
  {
    $this->job = Doctrine::getTable('JobeetJob')-> find($request->getParameter('id'));
    $this->forward404Unless($this->job);
  }
 
  // ...
}

indexアクションに関しては、今回の場合、JobeetJobテーブルクラスはfind()メソッドを利用して求人情報を読み取るために使われます。 このメソッドのパラメーターはjob、~主キー~の一意的な識別子です。 次のセクションでは$request->getParameter('id')ステートメントがjobの主キーを返す理由を説明します。

もし求人データがデータベースに存在しなければ、ユーザーを~404エラー~のページに転送させたいと考えます、 それはまさしくforward404Unless()メソッドが実行します。 第1引数のブール値をチェックして、trueでなければ現在実行中のフローを中止します。 forwardメソッドはsfError404Exceptionに投げて実行中のアクションをすぐに停止させるので、その後でreturn文は必要ありません。

~例外|例外処理~に関して、ユーザーに表示されるページはprod~環境~とdev環境で異なります:

dev環境の404エラー

prod環境の404エラー

JobeetのWebサイトを運用サーバーにデプロイする前に、デフォルトの404エラーページをカスタマイズする方法を学びます。

リクエストとレスポンス

/jobページや/job/show/id/1ページをブラウザー上で見る際、データがWebサーバーの間を往復し始めます。ブラウザーは~リクエスト|HTTPリクエスト~(request)を送り、サーバーは~レスポンス|HTTPレスポンス~(response)を返します。

すでにsymfonyがリクエストをsfWebRequestオブジェクトでカプセル化されるのは見ました(executeShow()メソッドを見てください)。 symfonyはオブジェクト指向フレームワークであるのでレスポンスもオブジェクトです。 これは sfWebResponseクラスです。 $this->getResponse()メソッドを呼び出すことでアクション内からレスポンスオブジェクトにアクセスすることができます。

これらオブジェクトはPHP関数やグローバル変数から情報を受け取るために便利なメソッドをたくさん提供します。

なぜsymfonyは既存のPHP関数をラップしているのでしょうか? 第一に、symfonyのメソッドはPHPの標準関数より強力です。 そして、アプリケーションのテストをするときは、グローバル変数をあれこれいじったり、マジックのようなheader()関数を使うよりもリクエストやレスポンスオブジェクトを使えばもっと簡単になります。

リクエスト

sfWebRequestクラスは~$_SERVER~、~$_COOKIE~、~$_GET~、~$_POST~、~$_FILES~といったPHPのスーパーグローバルをラップしています:

メソッドの名前 対応するPHPのスーパーグローバル
getMethod() $_SERVER['REQUEST_METHOD']
getUri() $_SERVER['REQUEST_URI']
getReferer() $_SERVER['HTTP_REFERER']
getHost() $_SERVER['HTTP_HOST']
getLanguages() $_SERVER['HTTP_ACCEPT_LANGUAGE']
getCharsets() $_SERVER['HTTP_ACCEPT_CHARSET']
isXmlHttpRequest() $_SERVER['X_REQUESTED_WITH'] == 'XMLHttpRequest'
getHttpHeader() $_SERVER
getCookie() $_COOKIE
isSecure() $_SERVER['HTTPS']
getFiles() $_FILES
getGetParameter() $_GET
getPostParameter() $_POST
getUrlParameter() $_SERVER['PATH_INFO']
getRemoteAddress() $_SERVER['REMOTE_ADDR']

すでにgetParameter()メソッドを使ってリクエストパラメーターにアクセスしました。 このメソッドは$_GETまたは$_POSTグローバル変数やPATH_INFO変数から値を返します。

もしこれらの中の特定の1つを取得できるようにしたいのであれば、getGetParameter()getPostParameter()getUrlParameter()メソッドを利用する必要があります。

特定の~HTTPメソッド~用のアクションを制限したいとき、たとえばフォームがPOSTとして投稿されることを保証したい場合、isMethod()メソッドを使うことができます: $this->forwardUnless($request->isMethod('POST'));

レスポンス

sfWebResponseクラスはPHP関数の~header|HTTPヘッダー~()setrawcookie()をラップします:

メソッドの名前 対応するPHP関数
setCookie() setrawcookie()
setStatusCode() header()
setHttpHeader() header()
setContentType() header()
addVaryHttpHeader() header()
addCacheControlHttpHeader() header()

もちろんsfWebResponseクラスはレスポンスのコンテンツをセットする方法(setContent())とブラウザーにレスポンスを送る方法(send())も提供します。

本日のチュートリアルの最初の方でview.ymlとテンプレートの両方でスタイルシートやJavaScriptを管理するやり方を見ました。 結局2つのテクニックともレスポンスオブジェクトのaddStylesheet()addJavascript()メソッドを使います。

sfActionsfRequestsfResponseクラスもたくさんの有用なメソッドを提供します。 APIドキュメントを読んでsymfonyの内部クラスをもっと学習しましょう。

また明日

今日は、symfonyで使われているいくつかのデザインパターンを説明しました。 プロジェクトのディレクトリ構造の理解が進むことを願っております。 レイアウトとテンプレートファイルを操作することでテンプレートで遊びました。 スロットとアクションのおかげでこれらを少し動的なものに変えることもしました。

明日は、今日使ったurl_for()ヘルパーとルーティングサブフレームワークについて学びます。

5日目: ルーティング »
« 3日目: ~データモデル~

Questions & Feedback

If you find a typo or an error, please register and open a ticket.

If you need support or have a technical question, please post to the official user mailing-list.

The Sensio Labs Network

Since 1998, Sensio Labs has been promoting the Open-Source software movement by providing quality web application development, training, consulting.
Sensio Labs also supports several large Open-Source projects.