Caution: You are browsing the legacy symfony 1.x part of this website.
Cover of the book Symfony 5: The Fast Track

Symfony 5: The Fast Track is the best book to learn modern Symfony development, from zero to production. +300 pages in full color showing how to combine Symfony with Docker, APIs, queues & async tasks, Webpack, Single-Page Applications, etc.

Buy printed version

iPhone用に最適化されたWebサイトを作る方法

1.2
Symfony version
1.1
Language

symfony 1.1は異なるフォーマットとmime-typeのネイティブのサポート機能を導入します。 このことは同じモデルとコントローラはリクエストされたフォーマットに基づいて異なるテンプレートを持つことを意味します。 デフォルトのフォーマットはHTMLのままですが、symfonyはfactories.ymlファイルで定義されたいくつかのフォーマットをそのままサポートします:

request:
  class: sfWebRequest
    param:
      formats:
        txt:  text/plain
        js:   [application/javascript, application/x-javascript, text/javascript]
        css:  text/css
        json: [application/json, application/x-json]
        xml:  [text/xml, application/xml, application/x-xml]
        rdf:  application/rdf+xml
        atom: application/atom+xml

それぞれのフォーマットは1つもしくは複数のmime-typeに関連づけされます。 これらのmime-typeはHTTPのAcceptヘッダーを解析することでリクエストされたフォーマットを自動的に決定するために使われます。 ブラウザーをとおしてデータを利用可能なものにしてWebサービスとして公開したい場合にこれはとても重宝します。 レスポンスのフォーマットを変更するには、下記のようにWebサービスのクライアントがAcceptヘッダーを変更することだけが必要です:

$ curl -H "Accept: application/xml"  http://ws.example.com/api/article # データのXML表現を取得するため
$ curl -H "Accept: application/json" http://ws.example.com/api/article # データのJSON表現を取得するため

異なるフォーマットをサポートすることは異なるテンプレートを作ることと同じぐらい簡単です。 Webサービスがapi/articleアクションによって管理されることを前提とします。 HTML、XMLとJSONフォーマットをサポートするために、apps/frontend/modules/api/templatesの中で作らなければならないテンプレートの一覧です:

  • articleSuccess.php
  • articleSuccess.xml.php
  • articleSuccess.json.php

デフォルトでは、symfonyは、フォーマットに従ってContent-Typeレスポンスの変更を行い、HTMLではないフォーマットに対しては、レイアウトを無効にします。 パーシャルとレイアウトでさえもリクエストされたフォーマットに基づいて異なることがあります。 たとえば、listパーシャルをテンプレートの中に含める場合、ロードされたパーシャルの名前は現在のフォーマットに依存します:

  • _list.php
  • _list.xml.php
  • _list.json.php

別の例を考えてみましょう。 スタイルシートもしくはJavaScriptファイルをすぐに作りたいとします。 これらの事例においてHTTPのAcceptヘッダーは常に当てにできないので、ルーティングルールのsf_format変数を利用することでフォーマットの種類を強制できます。 動的なスタイルシート用のルートを作る方法は次のとおりです:

css1:
  url:   /css/dynamic1.css
  param: { module: css, action: dynamic, sf_format: css }

1つのアクションに対して複数のフォーマットを許可するためにURLパターンの中でsf_format変数を使うこともできます:

api_article:
  url:   /api/article.:sf_format
  param: { module: api, action: article }
  requirements:
    sf_format: (?:html|xml|json)

たいていの場合、新しいフォーマットをサポートするためにアクションのコードを変更する必要はありません; しかしフォーマットのために何か特別なことを本当に行う必要がある場合、現在のフォーマットを取得してそれに応じてふるまうために$request->getRequestFormat()を呼び出すことができます。

Ok、お待ちかねのお話です! iPhone用に最適化されたWebサイトを作りたい場合を考えてみましょう。 デフォルトではiphoneフォーマットは存在しませんが設定するのはかなり簡単です。 最初に、iPhoneから由来するリクエストを決定する方法が必要です。 User-AgentヘッダーがMobileSafariの単語を含む場合、ブラウザがiPhoneであることを安全に推測できます。request.filter_parametersイベント用のリスナーを登録することでこのロジックをProjectConfigurationクラスに設置できます:

// config/ProjectConfiguration.class.php
class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    // ...
 
    $this->dispatcher->connect('request.filter_parameters', array($this, 'filterRequestParameters'));
  }
 
  public function filterRequestParameters(sfEvent $event, $parameters)
  {
    $request = $event->getSubject();
 
    if (preg_match('#Mobile/.+Safari#i', $request->getHttpHeader('User-Agent')))
    {
      $request->setRequestFormat('iphone');
    }
 
    return $parameters;
  }
}

これで、リクエストが来るたびにfilterParameters()メソッドが呼び出され、ブラウザーがiPhoneの場合にリクエストフォーマットがiphoneに変更されます。

これでお終いです! iPhoneから来るすべてのリクエストは*Success.phpテンプレートの代わりに*Success.iphone.phpテンプレートを使います。

iPhoneのために特別なスタイルシートもしくはJavaScriptファイルを使いたい場合(たとえばiui libraryを使う場合)、view.configure_formatをリスニングすることでビューを設定することもできます:

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    // ...
 
    $this->dispatcher->connect('view.configure_format', array($this, 'configureIPhoneFormat'));
  }
 
  public function configureIPhoneFormat(sfEvent $event)
  {
    if ('iphone' == $event['format'])
    {
      // CSS、JavaScriptもしくは望むものを追加する
    }
  }
}

symfony 1.1の新しいフォーマットのサポートのおかげで、Webサービス、APIもしくはiPhoneを開発することは簡単になりました。新しいフォーマットをサポートする機能を追加する作業は新しいテンプレートの一式を作る作業と同じくらい簡単です。