Caution: You are browsing the legacy 1.x part of this website.
This version of symfony is not maintained anymore. If some of your projects still use this version, consider upgrading.

第5章 - symfony を設定する

A Gentle Introduction to symfony

シンプルで使いやすくするために、symfony には最初からいくつかの規約が定義されています。これらの規約は修正しなくても標準的なアプリケーションの共通要件を満たします。しかしながら、シンプルで強力なこの設定機能を利用することで、symfony とアプリケーションを連携させる方法をほとんどカスタマイズできます。これらのファイルによって、アプリケーションに固有のパラメーターを追加することもできます。

この章では設定システムがどのように機能するのかを説明します:

  • symfony の設定は YAML ファイルに保存されますが、YAML以外の別のファイルフォーマットを選ぶこともできます。
  • 設定ファイル (configuration file) はプロジェクトレベル、アプリケーションレベル、モジュールレベルで存在します。
  • 複数のコンフィギュレーション設定をグループで定義できます。設定のグループは環境 (environment) と呼ばれます。
  • 設定ファイルで定義された値はアプリケーションの PHP コードから利用できます。
  • 加えて、symfony は YAML ファイルのなかで PHP コードを書けるようにすることで設定システムをはるかに柔軟なものにできます。

設定システム

目的にかかわらず、多くの Web アプリケーションには共通部分があります。たとえば、機能の一部にユーザーによって制限をかけたり、もしくはページはレイアウトによってデコレート(装飾)されていたり、もしくはバリデーションが失敗したあとでフォームでユーザーが入力した内容が補完されるなどです。symfony はこれらの機能をエミュレートするため設定ができるので、開発者はコンフィギュレーション設定を変更するだけでこれらの機能を調整することができます。多くの変更ではコードは一行も必要ないので、たくさんのコードが背後に存在するとしても、この機能のおかげで多くの開発時間が節約されます。これらの情報は単独で簡単に見分けられる位置に保存されるので、はるかに効率的でもあります。

しかしながら、このアプローチには重大な欠点が2つあります:

  • 開発者は複雑な XML ファイルを絶え間なく書かなければならない事態に陥ります。
  • PHP アーキテクチャにおいて、すべてのリクエストを処理する時間がはるかに長くなります。

これらの不都合な点を考慮にいれ、symfony では設定ファイルが得意なことに対してのみ設定ファイルを使います。実際のところ、symfony の設定システムは次のようになっています:

  • パワフルである: 設定ファイルで管理できるところはできるだけ全てを設定ファイルを利用して管理する。
  • シンプルである: 変更をほとんど行わずにすむので、通常のアプリケーションにおいて多くの設定を行う状況に遭遇しない。
  • 簡単である: 開発者が読みやすく、作成と修正を簡単に行うことができる設定ファイルである。
  • カスタマイズ可能である: デフォルト言語は YAML であるが、INI、XML、または開発者が好きなフォーマットを利用できる。
  • 速い: 設定ファイルはアプリケーションではなく設定システムによって処理される。この設定システムによって設定ファイルは PHP サーバーで速く処理されるコードの塊 (チャンク) にコンパイルされます。

YAML 構文と symfony の規約

symfony は設定に対して、より伝統的な INI もしくは XML フォーマットの代わりに、デフォルトで YAML フォーマットを利用します。YAML はインデント (字下げ) を通して構造を示すので速く書けます。その利点と基本ルールはすでに1章で説明しました。しかしながら、YAML ファイルを書く際には覚えておかなくてはならない規約があります。このセクションではもっとも有名な規約をいくつか紹介します。完全なドキュメントを必要とする場合は、専用のリファレンスガイドブック)を読んでください。

まず最初に、タブは使いません; 代わりに半角スペース (ブランク) を使います。YAML パーサーはタブを含むファイルを理解できないので、リスト5-1で示すようにスペースで行をインデントします (2つのスペースは symfony の規約です)。

リスト5-1 YAML ファイルではタブの使用は禁止されています

# タブは使わない
all:
-> mail:
-> -> webmaster:  webmaster@example.com

# 代わりに半角スペースを使う
all:
  mail:
    webmaster: webmaster@example.com

パラメーターがスペースで始まるもしくは終わる、 特殊文字 (「シャープ記号」 (#)もしくはカンマなど)、 もしくは「true, false」のようなキーワード (文字列を想定) が含まれる場合、 リスト5-2で示されるようにシングルクォートで値を閉じなければなりません。

リスト5-2 - 非標準的な文字列はシングルクォートで閉じる

error1: This field is compulsory
error2: '  This field is compulsory  '
error3: 'Don''t leave this field blank'   # シングルクォートは二重でなければならない
error4: 'Enter a # symbol to define an extension number'
i18n:   'false' # if we left off the quotes here, a boolean false would be returned

特別な文字列のヘッダー (> (大なり記号)と | (縦線・パイプライン)) と追加のインデントを用いることで、複数行の長い文字列と複数行の文字列も定義できます。リスト5-3はこの規約を示しています。

リスト5-3 - 複数行の長い文字列を定義する

# >(大なり記号)で導入される、折り返しスタイル
# それぞれの改行はスペースで折り返される
# YAML がより読みやすくなる
accomplishment: >
  Mark set a major league
  home run record in 1998.

# | (縦線・パイプライン) によって導入される、リテラルスタイル
# すべての改行はカウントされる
# インデントは結果の文字列に表示されない
stats: |
  65 Home Runs
  0.278 Batting Average

値を配列として定義するには、リスト5-4で示されるように、要素を角かっこ ([、]) で閉じるかダッシュ (-) を用いた拡張構文を使います。

リスト5-4 - YAML の配列構文

# 配列のための省略構文
players: [ Mark McGwire, Sammy Sosa, Ken Griffey ]

# 配列のための拡張構文
players:
  - Mark McGwire
  - Sammy Sosa
  - Ken Griffey

値を連想配列もしくはハッシュとして定義するには、波かっこ ({、}) で要素を囲み、key: value の組のようにキーと値の間に空白文字を挿入します。リスト5-5で示されるように、すべての新しいキーに対して、インデントとキャリッジ・リターン (CR) を追加することで拡張構文も利用できます。

リスト5-5 - YAMLの連想配列構文

# 正しくない構文、スペースがコロンのあとで見つからない
mail: {webmaster:webmaster@example.com,contact:contact@example.com}

# 連想配列のための正しい省略構文
mail: { webmaster: webmaster@example.com, contact: contact@example.com }

# 連想配列のための拡張構文
mail:
  webmaster: webmaster@example.com
  contact:   contact@example.com

ブール値を追加するには、正の値に対しては クォートで囲まれていないfalsetrue値を使うことができます。

リスト5-6 - ブール値の YAML 構文

true_values:   true
false_values:  false

リスト5-7で示されるように、YAML ファイルを読みやすくするために (ハッシュ記号の # で始まる) コメントを追加したり値にスペースを追加することにためらう必要はありません。

リスト5-7 - YAML のコメント構文と値の位置の調整

# これはコメント行
mail:
  webmaster: webmaster@example.com
  contact:   contact@example.com
  admin:     admin@example.com   # 追加スペースのおかげで値をわかりやすく配置できる

symfony の設定ファイルにおいて、ハッシュ記号で始まる行(コメントとして YAML パーサーによって無視される)を見ることがありますが、通常の設定行のように見えます。これは symfony の規約です: デフォルト設定、symfony コアに設置されたほかの YAML ファイルから継承されたものは、アプリケーションの設定のなかでコメント行として繰り返されます。このようなパラメーターの値を変更するには、リスト5-8で示されるように、行の最初のコメントを解除する必要があります。

リスト5-8 - デフォルトの設定はコメントとして示される

# キャッシュはデフォルトで off
settings:
# cache: false

# この設定を変更したい場合、最初の行をコメント解除する
settings:
  cache: true

symfony はパラメーターの定義をカテゴリに分類することがあります。任意のカテゴリのすべての設定はカテゴリヘッダーの下でインデントされて表示されます。key: value の一組の長いリストをカテゴリに分類してこれらを構造化することで設定の読みやすさが改善されます。カテゴリヘッダーはドット (.) で始まります。リスト5-9ではカテゴリの例が示されています。

リスト5-9 - カテゴリヘッダーはキーのように見えるが、ドットで始まる

all:
  .general:
    tax:        19.6

  mail:
    webmaster:  webmaster@example.com

この例では、mail がキーで general はカテゴリヘッダーのみです。リスト5-10で示されるように、そのカテゴリがあたかも存在しなかったようにすべてが機能します。tax パラメーターは実際には all キーの直接の子供です。しかしながらカテゴリーを利用することで symfony が allキーの真下に存在する配列を扱うための助けになります。

リスト5-10 - カテゴリヘッダーは読みやすくする目的のためだけに存在し、実際には無視される

all:
  tax:          19.6

  mail:
    webmaster:  webmaster@example.com

sidebar

YAML がお好きでなければ

YAML は PHP コードで使われる設定を定義するための単なるインターフェイスなので、YAML で定義された設定は PHP に変換されることになります。ブラウザーでアプリケーションを見た後に、キャッシュされた設定を確認してください (たとえば、cache/frontend/dev/config/)。PHP ファイルが YAML 設定に対応していることがわかります。この章の後のほうで、設定のキャッシュを詳しく学びます。

YAMLファイルを使いたくないのであればよいお知らせがあります。PHP もしくは別のフォーマット (XML、INI など) を通して設定ファイルを手動で設定できます。この本全体を通して、YAML を使わずに設定を定義する別の方法と、symfony のコンフィギュレーションハンドラーを置き換える方法も学ぶことになります(19章)。これらを賢く使えば、これらのトリックによって設定ファイルを回避するもしくは独自の設定フォーマットを定義できます。

助けてください、YAML ファイルを修正したらアプリケーションが動かなくなりました!

YAML ファイルは解析されて PHP ハッシュと配列に変換されます。ビュー、コントローラー、もしくはモデルのふるまいを修正するためにアプリケーションのさまざまな場所で値が使われます。多くの場合、YAML ファイルに問題があるとき、値を実際に使う必要があるまで検出されません。その上、通常は投じられたエラーもしくは例外が YAML 設定ファイルに関連しているのかどうかは明らかではありません。

設定を変更したあとでアプリケーションが突然機能を停止する場合、YAML を記入するさいに共通の不注意な間違いをしなかったことを確認します:

  • キーと値のあいだのスペースを入れ忘れていないか:

    key1:value1      # :のあとでスペースが見つからない
    
  • 連続したキーが同じ方法でインデントされていない:

    all:
      key1:  value1
       key2: value2  # インデントのレベルがほかの連続したメンバーと同じではない
      key3:  value3
    
  • 文字列の区切り文字なしで、キーもしくは値に YAML の予約文字が存在する:

    message: tell him: go way    # :(コロン)、[、] (角かっこ)、{ と } (中かっこ) は YAML の予約文字
    message: 'tell him: go way'  # 正しい構文
    
  • コメント行を修正している:

    # key: value     # 見出しの#が原因で無視される
    
  • 同じレベルで同じキーを持つ値を2回設定している:

    key1: value1
    key2: value2
    key1: value3     # key1 は2回定義され、値は最後に定義されたものになる
    
  • 設定はつねに文字列であるにもかかわらず、変換するまで、設定が特別な型をとると考える:

    income: 12,345   # 変換するまで、これはまだ文字列
    

設定ファイルの概要

設定は項目によってファイルに分割されます。ファイルはパラメーターの定義、もしくは設定を格納します。これらのパラメーターはいくつかのレベル (プロジェクト、アプリケーションとモジュール) でオーバーライドされます; パラメーターのなかには特定のレベル限定のものもあります。つぎの章でこれらのメイントピックに関連する設定ファイルを扱い、19章では高度な設定方法を扱います。

プロジェクトのコンフィギュレーション

デフォルトではプロジェクトの設定ファイルはわずかに存在します。myproject/config/ ディレクトリのなかで見つかるファイルはつぎのとおりです:

  • ProjectConfiguration.class.php: これはリクエストもしくはコマンドによってとても最初のほうでインクルードされるファイルです。これはフレームワークへのパスを含むので、異なる場所にインストールされたsymfonyライブラリを利用するために変更できます。このファイルの高度な使いかたに関しては19章を参照してください。
  • databases.yml: このファイルはデータベースへのアクセスと接続の設定を定義する (ホスト名、ログイン名、パスワード、データベース名など)。8章で詳しく説明します。このファイルをアプリケーションレベルでオーバーライドできます。
  • properties.ini: このファイルは、プロジェクト名と異なるサーバーのための接続設定を含む、コマンドラインツールによって利用されるいくつかのパラメーターを格納します。このファイルを利用する機能の概要は16章を参照してください。
  • rsync_exclude.txtrsync_include.txt: このファイルでディレクトリやファイルを指定し、サーバーと同期をとるときに除外または含まれるようにします。設定方法は16章で説明しています。
  • schema.yml:このファイルは Propel や Doctrine(symfony の ORM レイヤー) によって使われるデータアクセス用の設定ファイルです。これらのファイルは ORM のライブラリと symfony のクラスとプロジェクトのデータを連携させるために使われます。schema.yml はプロジェクトのリレーショナルデータモデルの記述を格納します。Doctrine を使用する場合はこのファイルは config/doctrine/ ディレクトリに作成されます。

これらのファイルはおもに外部のコンポーネントもしくはコマンドラインによって使われる、もしくは symfony によって読み込まれる YAML の解析プログラムよりも先に処理される必要があります。これらのなかに YAML フォーマットを使わないものが存在するのはそういうわけです。

アプリケーションのコンフィギュレーション

設定のメイン部分はアプリケーションの設定です。アプリケーションの設定は主要な設定のためにフロントコントローラー (web/ ディレクトリ)のなかで定義されます。YAML ファイルはアプリケーションの config/ディレクトリ、i18n/ ディレクトリ、フレームワークのディレクトリに設置されます。i18n/ ディレクトリは国際化のために、フレームワークファイルは表立って表れないが役に立つ追加のアプリケーション設定のためにあります。

フロントコントローラーのコンフィギュレーション

最初のアプリケーションのコンフィギュレーションは実際にはフロントコントローラーのなかで見つかります; これはリクエストによって実行される最初のスクリプトです。リスト5-11のデフォルトの web/index.phpをご覧ください。

リスト5-11 - 運用環境用のデフォルトのフロントコントローラー

<?php
 
require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php');
 
$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', false);
sfContext::createInstance($configuration)->dispatch();

アプリケーションの名前 (frontend) と環境 (prod) とデバッグモード (false) を定義したあとで、アプリケーションの設定はコンテキスト作成とディスパッチ実行のまえに呼び出されます。ですのでアプリケーションの設定クラスのなかで利用できる便利なメソッドはわずかです:

  • $configuration->getRootDir(): プロジェクトルートディレクトリ(通常は、ファイル構造を変更しないかぎり、デフォルト値のままにします)。
  • $configuration->getApplication(): プロジェクトのアプリケーションの名前。ファイルのパスを算出するために必要。
  • $configuration->getEnvironment(): 環境の名前 (proddevtest、もしくはあなたが定義するプロジェクト固有の環境)。使われるコンフィギュレーション設定を決定します。環境はこの章のあとのほうで説明します。
  • $configuration->isDebug(): デバッグモードの有効 (詳細は16章)。

これらの値の1つを変更したい場合、追加のフロントコントローラーが必要でしょう。つぎの章でフロントコントローラーに関する詳細な情報と新しいフロントコントローラーを作成する方法をお伝えます。

メインアプリケーションのコンフィギュレーション

メインアプリケーションの設定は myproject/apps/frontend/config/ ディレクトリに設置されるファイルに保存されます:

  • app.yml: このファイルはアプリケーション固有の設定です; すなわち、アプリケーションに固有なビジネスロジックもしくはアプリケーションロジックを定義するグローバル変数で、データベースに保存する必要のないものです。税率、運賃、メールアドレスはこのファイルによく保存されます。デフォルトではこのファイルは空です。
  • frontendConfiguration.class.php: このクラスはアプリケーションを起動します。このことはアプリケーションを始めることができるようにするためにとても基本的な初期化を行うことを意味します。ここはディレクトリ構造もしくはアプリケーション固有の定数をカスタマイズする場所です (19章で詳細な情報を提供します)。このクラスは ProjectConfiguration クラスを継承します。
  • factories.yml: symfony は、ビュー、リクエスト、リスポンス、セッション、などを扱う独自クラスを定義します。独自クラスを使いたい場合、ここで指定できます。17章で詳細な情報を提供します。
  • filters.yml: フィルターはすべてのリクエストに対して実行されるコードの一部です。このファイルでは処理されるフィルターを定義し、それぞれのモジュールからオーバーライドできます。6章でこれらの詳細について検討します。
  • routing.yml: ルーティングルールがこのファイルに保存されます。ルーティングルールはわかりづらくてブックマークしにくい URL を「スマート」 (smart) で明快な文字列に変換します。新しいアプリケーション用にデフォルトのルールがいくつか存在します。9章でリンクとルーティングのすべてを説明します。
  • settings.yml: symfony のアプリケーションの主要な設定はこのファイルで定義されます。このファイルでアプリケーションが国際化機能、デフォルトの言語、リクエストの有効期間とキャッシュにオンにするかなどを指定します。このファイルで1行変更すれば、アプリケーションをシャットダウンできるのでメンテナンスを実行するもしくはコンポーネントの1つをアップグレードすることが可能です。共通の設定と使いかたは19章で説明します。
  • view.yml: デフォルトのビューの構造 (レイアウトの名前、インクルードされるデフォルトのスタイルシートと JavaScript のファイル、デフォルトの Content-Type など) はこのファイルのなかで設定されます。7章でこのファイルの詳細な情報をお伝えます。これらの設定はそれぞれのモジュールからオーバーライドできます。

tip

symfony の全設定ファイルについてはsymfony リファレンスブックで詳しく説明されています。

国際化のコンフィギュレーション

国際化されたアプリケーションはさまざまな言語のページを表示できます。このためには特別な設定が必要です。国際化のための設定を行う場所は2ヶ所あります:

  • アプリケーションの config/ ディレクトリの factories.yml: このファイルは国際化ファクトリと一般的な翻訳オプション、翻訳がファイルもしくはデータベースから由来するか、そしてそれらのフォーマットを定義します。
  • アプリケーションの i18n ディレクトリの翻訳ファイル: これらは基本的に辞書 (dictionary) です。ユーザーが言語を切り替えたときにページが翻訳テキストを表示するようにアプリケーションのテンプレートのなかで使われるそれぞれのフレーズに対する翻訳を渡します。

国際化機能の有効は settings.yml ファイルで設定されることに留意してください。これらに関する詳細な情報は13章で見つかります。

アプリケーションの追加コンフィギュレーション

設定ファイルの2番目の一式は symfony のインストールディレクトリ ($sf_symfony_lib_dir/config/config/) に存在し、アプリケーションの設定ディレクトリには表示されません。そこで定義される設定はほとんど修正する必要のないもしくはすべてのプロジェクトに対してグローバルなデフォルトです。しかしながら、修正する必要がある場合、同じ名前を持つ空のファイルを myproject/apps/frontend/config ディレクトリに作り、変更したい設定をオーバーライドします。アプリケーションで定義される設定はフレームワークで定義される設定よりつねに優先されます。以下のものは symfony がインストールされた config/ ディレクトリに存在する設定ファイルです:

  • autoload.yml: このファイルはオートロード機能の設定を格納します。カスタムクラスが指定ディレクトリに設置されている場合、この機能のおかげでこれらのクラスをコードのなかで require を行わずにすみます。詳細は19章で説明します。
  • core_compile.yml: アプリケーションを開始するために必要なクラスのリストです。これらのクラスは実際には (コメント部分を取り除いた) 最適化された1つの PHP ファイルに連結されます。この PHP ファイルはファイルアクセスのオペレーションを最小にすることで実行速度を加速します(置き換えられた1つのファイルはそれぞれのリクエストに対して40倍以上速くロードされます)。これはとりわけ PHP アクセラレータを使わない場合に役立ちます。最適化のテクニックは18章で説明します。
  • config_handlers.yml: このファイルのなかでそれぞれの設定ファイルを処理するハンドラーを追加もしくは修正できます。19章に詳細な説明があります。

モジュールのコンフィギュレーション

デフォルトでは、モジュールは特別な設定を持ちません。しかしながら、必要ならば、任意のモジュールのためにいくつかのアプリケーションレベルの設定をオーバーライドできます。たとえば、1つのモジュールのすべてのアクションのために特定の JavaScript ファイルをインクルードするためにこれを行うことでしょう。カプセル化を保持するために指定モジュールに制限された新しいパラメーターを追加するやりかたを選ぶこともできます。

ご明察のとおり、モジュールの設定ファイルは myproject/aaps/frontend/modules/mymodules/config/ ディレクトリに設置しなければなりません。これらのファイルはつぎのとおりです:

  • generator.yml: (scaffolding と administrationを利用して) データベースのテーブルに対応して生成されたモジュールに対して、このファイルはインターフェイスが列とフィールドを表示する方法と、ユーザーに提示されるインタラクション (フィルター、ソート、ボタンなど) を定義します。14章でより詳細な内容を説明します。
  • module.yml: このファイルはモジュールとアクションに固有なカスタムパラメーターとアクション設定を格納します。6章で詳細を説明します。
  • security.yml: このファイルはアクションに対するアクセス制限を設定します。ここで登録ユーザーもしくは特別なパーミッションを持つ登録ユーザーの一部のみがページを閲覧できるように指定することができます。6章に詳細な説明があります。
  • view.yml: このファイルはモジュールのアクションの1つもしくはすべてのビューのための設定を格納します。このファイルはアプリケーションの view.yml をオーバーライドします。7章で説明します。

たいていのモジュールの設定ファイルは、すべてのビュー、もしくは1つのモジュールのすべてのアクション、もしくはそれらの一部に対して、パラメーターを追加する機能を提供します。

sidebar

ファイルが多すぎるでしょうか?

アプリケーション内部に存在する設定ファイルの数に圧倒されているかもしれません。しかしながらつぎのことを念頭に置いて下さるようお願いします:

たいていの場合、デフォルトの規約が多くの共通の要件を満たすので、設定を変更する必要はありません。それぞれの設定ファイルは特定の機能に関係し、つぎの章でこれらの使いかたを一つずつ説明します。単独のファイルにとり組むとき、それが何を行い、どのように編成されているのかわかります。プロフェッショナルな Web 開発のために、しばしデフォルトの設定は完全には適用されません。設定ファイルによって symfony のメカニズムをコードなしで簡単に修正できます。同じ量のコントロールを実現するために必要な PHP のコード量を想像してください。すべての設定が1つのファイルに設置されたとしたら、ファイルの完全な可読性がなくなるだけでなく、いくつかのレベルで設定を再定義できなくなります(この章の後のほうにある「コンフィギュレーションカスケード」をご覧ください)。

設定システムは symfony のすばらしい強みの1つです。これによって、元来対象とした Web アプリケーションだけでなく、ほかのほとんどすべてのアプリケーションでも symfony を利用できるからです。

環境

アプリケーションの開発過程で、おそらく平行していくつかの設定の一式を用意することが必要になります。たとえば、開発期間にテストのデータベースのための接続設定と、運用環境で利用できる実際のデータのための接続設定が必要になるでしょう。同時に設定する方法の需要に応えるために、symfony は異なる環境 (environment) を提供します。

環境とは何か?

アプリケーションはさまざまな環境 (environment) のもとで動くことができます。異なる環境は同じ PHP コード (フロントコントローラーは別) を共有しますが、完全に異なる設定を持つことができます。それぞれのアプリケーションに対して、symfony は3つの異なるデフォルト環境を提供します: 運用 (prod)、テスト (test)、と開発 (dev) です。欲しい数だけカスタム環境を追加することも自由にできます。

ですので、基本的には、環境 (environment) とコンフィギュレーション (configuration) は同義語です。たとえば、test 環境では警告とエラーが記録されるのに対して、prod 環境ではエラーのみが記録します。キャッシュのアクセラレータは dev 環境ではよく無効にされますが、testprod 環境では有効にされます。devtest 環境ではテストデータが必要になることがあります。テストデータは運用環境で使われるものとは別にデータベースに保存されます。ですので2つの環境のあいだでデータベースの設定は異なります。すべての環境は同じマシン上に同居できますが、運用サーバーは一般的に prod 環境のみを持ちます。

dev 環境では、メンテナンスはパフォーマンスよりも重要なので、ロギングとデバッグの設定はすべて有効です。一方で、prod 環境はデフォルトでパフォーマンスを最適化した設定を持つので、運用環境の設定では多くの機能をオフです。よい経験則はとり組んでいる機能に満足するまで開発環境で作業を行い、運用環境に切り替えてからはスピードをチェックします。

test 環境はつぎの点で devprod 環境とは異なります。機能テストとバッチスクリプトを作成するためにコマンドラインを通してのみこの環境と関わることになります。結果として、test環境は運用環境と近いですが、Web ブラウザーでアクセスできません。Cookie の使用とほかの HTTP 固有のコンポーネントをシミュレートします。

ブラウザーで閲覧しているアプリケーションの環境を変更するには、フロントコントローラーを変更するだけです。これまでは開発環境だけを見てきました。例で使われたURLは開発用のフロントコントローラーを呼び出していたからです:

http://localhost/frontend_dev.php/mymodule/index

しかしながら、運用環境でアプリケーションが応対する様子を見たいのであれば、運用環境用のフロントコントローラーを呼び出します:

http://localhost/index.php/mymodule/index

Web サーバーが mod_rewrite を有効にしている場合、web/.htaccess に書かれている、symfony のカスタム書き換えルールを利用できます。これらのルールは運用環境用のフロントコントローラーをデフォルトの実行スクリプトとして定義し、つぎのような URL を許可します:

http://localhost/mymodule/index

sidebar

環境とサーバー

環境とサーバーの概念を混同しないでください。symfony において、異なる環境は異なる設定でありフロントコントローラー (リクエストを実行するスクリプト) に対応します。異なるサーバーは URL の異なるドメイン名に対応します。

http://localhost/frontend_dev.php/mymodule/index
       _________ _____________
        サーバー   環境

通常、開発者は開発サーバーでアプリケーションにとり組みます。開発サーバーではインターネットから切り離され、すべてのサーバーと PHP の設定を自由に変更できます。運用環境でアプリケーションをリリースする時期が来たとき、アプリケーションのファイルを運用サーバーに転送して、エンドユーザーがアクセスできるようにします。

このことは多くの環境がそれぞれのサーバー上で利用できることを意味します。たとえば、開発サーバー上でも運用環境で運用できます。しかしながらたいていの場合、サーバーの設定の公開とセキュリティのリスクを避けるために、運用環境のみ運用サーバーにアクセスできます。運用システムで開発用ではないコントローラーを誤って流出させることを避けるために、symfony はこれらのコントローラーに基本的な IP チェックを追加します。このことによって localhost からのみアクセスが制限されます。これらにアクセスできるようにしたい場合、この制限を削除できますが、悪意のあるユーザーはデフォルトの frontend_dev.php を推測して多くの見られたくない情報にアクセスできるので、これを誰でもアクセスできるようにする場合のリスクを考えてください。

新しい環境を追加するには、新しいディレクトリを作るもしくは symfony CLI を使う必要はありません。単に新しいフロントコントローラーを作り、環境の名前の定義を変更するだけです。この環境はすべての環境に共通の設定に加えてデフォルトのすべての設定を継承します。つぎの章でこれを行う方法を示します。

コンフィギュレーションカスケード

同じ設定を異なる場所で複数定義することができます。たとえば、すべてのアプリケーションに対して、text/xml mime-type が必要な rss モジュールのページを除いて、mime-type のページを text/html に設定することを考えます。symfony は最初の設定を frontend/config/view.yml に書き込み、2番目の設定を frontend/modules/rss/config/view.yml に書き込む機能を提供します。設定システムはモジュールレベルで定義された設定はアプリケーションレベルで定義された設定をオーバーライドしなければならないことを知っています。

実際、symfonyにはいくつかの設定レベルが存在します:

  • 粒度のレベル:
    • フレームワークに設置されたデフォルトの設定
    • プロジェクト全体のグローバル設定 (myproject/config/)
    • プロジェクトのアプリケーションのローカル設定 (myproject/apps/frontend/config/)
    • モジュールに制限されたローカル設定 (myproject/apps/frontend/modules/mymodule/config/)
  • 環境レベル:
    • 特定の環境に固有
    • すべての環境用

カスタマイズできるすべてのプロパティのうち、多くは環境に依存します。結果として、すべての環境に適用される設定ファイルの末尾の部分に加えて、多くのYAMLの設定ファイルは環境によって分割されます。よくある symfony の設定はリスト5-12のようになります。

リスト5-12 - symfony の設定ファイルの構造

# 運用環境の設定
prod:
  ...

# 開発環境の設定
dev:
  ...

# テスト環境の設定
test:
  ...

# カスタム環境の設定
myenv:
  ...

# すべての環境のための設定
all:
  ...

加えて、symfony フレームワーク自身は、プロジェクトのツリー構造ではなく、symfony インストールディレクトリの $sf_symfony_lib_dir/config/config/ ディレクトリに設置されたファイルでデフォルト値を定義します。リスト5-13で示されるようにデフォルト設定はこれらのファイルで設定されます。これらの設定はすべてのアプリケーションによって継承されます。

リスト5-13 - デフォルト設定 ($sf_symfony_lib_dir/config/config/settings.yml)

 # デフォルト設定:
 default:
   default_module:         default
   default_action:         index
   ...

リスト5-14で示されるように、これらのデフォルトの定義はプロジェクト、アプリケーション、モジュールの設定ファイルのなかでコメントとして繰り返されるので、いくつかのパラメーターはデフォルトで定義されこれらが修正可能であることはご存じのとおりです。

リスト5-14 - 開発者に知ってもらうために繰り返されるデフォルト設定 (frontend/config/settings.yml)

#all:
#  default_module:         default
#  default_action:         index
#...

このことはプロパティは何度も定義することが可能で、実際の値は定義のカスケードから由来します。名前つきの環境のパラメーター定義はすべての環境のための同じパラメーター定義より優先され、すべての環境のための定義はデフォルトの定義より優先されます。モジュールレベルでのパラメーター定義はアプリケーションレベルでの同じパラメーター定義よりも優先されます。アプリケーションレベルでの定義はプロジェクトレベルでの定義より優先されます。これはつぎの優先順位のリストにまとめることができます:

  1. モジュール
  2. アプリケーション
  3. プロジェクト
  4. 特別な環境
  5. すべての環境
  6. デフォルト

コンフィギュレーションキャッシュ

実行時の YAML の解析と設定カスケードの処理はそれぞれのリクエストに対する深刻なオーバーヘッドを意味します。symfony はリクエストを迅速にするために設計された組み込みのコンフィギュレーションキャッシュ (configuration cache) のメカニズムを持ちます。

設定ファイルは、フォーマットが何であれ、ハンドラー (handler) と呼ばれるいくつかの特別なクラスによって処理され、これらのファイルは速く処理されるPHPコードに変換されます。開発環境におけるインタラクティビティを推進するために、ハンドラーはリクエストごとの変更に対応して設定をチェックします。これらのハンドラーは最近修正されたファイルを解析するのでYAMLファイルのなかの変更を即座に確認できます。しかしながら、運用環境においては、最初のリクエストの間に処理が一回行われ、その後のリクエストに備えて処理すみのPHPコードはキャッシュに保存されます。運用環境においてすべてのリクエストは十分に最適化されたPHPコードを実行するので、パフォーマンスは保証されます。

たとえば、app.ymlファイルがつぎの内容を格納するとします:

all:                   # すべての環境のための設定
  mail:
    webmaster:         webmaster@example.com

それから、プロジェクトの cache/ フォルダーに設置された config_app.yml.php ファイルはつぎの内容を格納します:

<?php
 
sfConfig::add(array(
  'app_mail_webmaster' => 'webmaster@example.com',
));

結果として多くの場合、YAML ファイルは symfony によって解析されず代わりにコンフィギュレーションキャッシュに依存します。しかしながら開発環境において、symfony は体系的に YAML ファイルの修正日時とキャッシュされたファイルを比較し、以前のリクエスト以降に変更されたファイルだけを再処理します。

このことは、運用環境でもリクエストごとに設定ファイルがコンパイルされる多くの PHP フレームワークよりも優れた強みを示しています。Javaと は異なり、PHP はリクエスト間の実行コンテキストを共有しません。ほかの PHP フレームワークに関しては、XML 設定ファイルの柔軟性を維持すると、リクエストごとにすべての設定を処理するために余分な負荷 (パフォーマンスヒット) が多く必要になります。しかしながらsymfonyにはこのことがあてはまりません。キャッシュシステムのおかげで設定によって引き起こされるオーバーヘッドはとても低くなっています。

このメカニズムには考慮すべきことがあります。運用環境で設定を変更した場合、修正を考慮したすべての設定ファイルの再解析を強制する必要があります。そのためには、キャッシュをクリアする必要があります。キャッシュをクリアするには cache/ ディレクトリの内容を削除するか、symfony の cache:clear タスクを呼び出します:

$ php symfony cache:clear

コードから設定にアクセスする

すべてのファイルは最終的には PHP に変換され、それらが含む多くの設定は干渉なしでフレームワークによって自動的に使われます。しかしながら、ときには設定ファイルで定義されたいくつかの設定をコード (アクション、テンプレート、カスタムクラスなど) からアクセスする必要があります。settings.ymlapp.ymlmodule.ymli18n.yml のなかで定義された設定は sfConfig という名前の特別なクラスを通して利用できます。

sfConfig クラス

sfConfig クラスを通してアプリケーションのコードの範囲から設定にアクセスできます。このクラスは設定パラメーターのレジストリ(保存場所)です。クラスメソッドであるシンプルなゲッターを持ちすべてのコードからアクセスできます:

// 設定を読みとる
$parameter = sfConfig::get('param_name', $default_value);

PHP コードの範囲から設定を定義、オーバーライドすることもできます:

// 設定を定義する
sfConfig::set('param_name', $value);

パラメーター名は、アンダースコア (_) によって区切られたいくつかの要素をつぎの順番で連結したものです:

  • 設定ファイル名に関連するプレフィックス (sf_settings.ymlapp_app.ymlmod_module.yml)
  • 親キーは小文字 (定義されている場合)
  • キーの名前は小文字

PHP コードは実行される環境のために定義された値だけにアクセスするので、環境は含まれません。

たとえば、リスト5-15で示される app.yml ファイルで定義された値にアクセスする必要がある場合、リスト5-16で示されているようなコードが必要です。

リスト5-15 - app.yml の設定のサンプル

all:
  .general:
    tax:          19.6
  default_user:
    name:         John Doe
  mail:
    webmaster:    webmaster@example.com
    contact:      contact@example.com
dev:
  mail:
    webmaster:    dummy@example.com
    contact:      dummy@example.com

リスト5-16 - PHP コードで dev 環境のコンフィギュレーション設定にアクセスする

echo sfConfig::get('app_tax');   // カテゴリヘッダーが無視されることに注意
 => '19.6'
echo sfConfig::get('app_default_user_name');
 => 'John Doe'
echo sfConfig::get('app_mail_webmaster');
 => 'dummy@example.com'
echo sfConfig::get('app_mail_contact');
 => 'dummy@example.com'

すべての値を変更できるので、symfony のコンフィギュレーション設定は PHP 定数のすべての利点を持ち、欠点はともないません。

このため、アプリケーションのために symfony が設定を行う settings.yml ファイルは sfConfig::set() の呼び出しリストと同じです。リスト5-17はリスト5-18で示されるようなコードとして解釈されます。

リスト5-17 - settings.yml の抜粋

all:
  .settings:
    csrf_secret:       FooBar
    escaping_strategy: true
    escaping_method:   ESC_SPECIALCHARS

リスト5-18 - settings.yml を解析するときに symfony が行うこと

sfConfig::add(array(
  'sf_csrf_secret' => 'FooBar',
  'sf_escaping_strategy' => true,
  'sf_escaping_method' => 'ESC_SPECIALCHARS',
));

settings.yml ファイルのなかで見つかる設定の意味に関しては19章を参照してください。

アプリケーションのカスタム設定と app.yml

アプリケーションの機能に関連する多くの設定は myproject/apps/frontend/config/ ディレクトリに設置される app.yml に保存されます。このファイルは環境に依存しておりデフォルトの内容は空です。すべての設定は簡単に変更できます。コードからこれらの設定にアクセスするには sfConfig クラスを使います。リスト5-19は例を示しています。

リスト5-19 - 特定のサイト用に受理されたクレジットカードのオペレータを定義する app.yml のサンプル

all:
  creditcards:
    fake:             false
    visa:             true
    americanexpress:  true

dev:
  creditcards:
    fake:             true

fake クレジットカードが現在の環境で受理されるか知るには、つぎの値を取得します:

sfConfig::get('app_creditcards_fake');

note

all キーの真下でPHPの配列が必要なときカテゴリヘッダーを使うことが必要です。そうでなければ上記で示されたように symfony は値を個別に利用できるようにします。

all:
  .array:
    creditcards:
      fake:             false
      visa:             true
      americanexpress:  true
print_r(sfConfig::get('app_creditcards'));
 
Array(
  [fake] => false
  [visa] => true
  [americanexpress] => true
)

tip

1つのスクリプト内部で定数もしくは設定を定義したくなったら、app.yml ファイルに設置するほうがよいのかどうかを考えてください。このファイルはすべてのアプリケーションの設定を保存するためにとても便利な場所です。

app.yml の構文を処理するのが難しくなったカスタムパラメーターが必要なとき、独自構文を定義することが必要になるかもしれません。その場合、設定を新しいファイルに保存することができます。この設定は新しいコンフィギュレーションハンドラーによって解釈されます。コンフィギュレーションハンドラーに関する詳しい情報に関しては19章を参照してください。

設定ファイルからより多くの情報を得るためのティップス

独自の YAML ファイルを書くまえに学ぶべきしくみがいくつかあります。これらによって設定の重複を回避し、独自のYAMLフォーマットを扱うことができます。

YAML 設定ファイルのなかで定数を使う

いくつかのコンフィギュレーション設定はほかの設定の値に依存します。同じ値を2度設定することを避けるために、symfony は YAML ファイル形式で定数をサポートします。パーセント記号 (%) で囲まれた大文字の設定名 (sfConfig::get() でアクセス可能) を見てみると、コンフィギュレーションハンドラーはこれらの設定を現在の値に置き換えます。例に関しては5-20のリストをご覧ください。

リス5-20 - autoload.yml ファイルでの定数の使いかたの例

autoload:
  symfony:
    name:           symfony
    path:           %SF_SYMFONY_LIB_DIR%
    recursive:      true
    exclude:        [vendor]

path パラメーターは sfConfig::get('sf_symfony_lib_dir') が返す値をとります。ほかの設定ファイルに依存する1つの設定ファイルが欲しい場合、すでに依存するファイルが解析されたかどうかを確認する必要があります (解析された設定ファイルの順序を理解したければ symfony のソースを調べてください)。app.yml は解析される最後のファイルの1つなので、このファイルで別のファイルに依存することがあります。

設定にスクリプトを組み込む

設定が外部パラメーター (たとえばデータベース、またはほかの設定ファイル) に依存することがあります。このような特別な場合に対処するには、symfony の設定ファイルは YAML パーサーに渡されるまえに PHP ファイルとして解析されます。このことは、リスト5-21のように、PHP コードを YAML ファイル内部に設置できることを意味します。

リスト5-21 - YAML ファイルに PHP コードを入れることができる

all:
  translation:
    format:  <?php echo (sfConfig::get('sf_i18n') == true ? 'xliff' : 'none')."\n" ?>

しかしながら設定はリクエストのかなり初期の間に解析されるので、助けをしてくれる symfony の組み込みメソッドもしくは関数が存在しないことにご注意ください。

また、デフォルトで echo 言語構造は CR (キャリッジ・リターン) を追加しないので、YAMLフォーマットを有効に保つには \nもしくは echoln ヘルパーを追加する必要があります。

all:
  translation:
    format:  <?php echoln(sfConfig::get('sf_i18n') === true ? 'xliff' : 'none') ?>

caution

運用環境において、設定はキャッシュされるので、設定ファイルはキャッシュがクリアされたあとで1回だけ解析されます(そして実行されます)。

独自の YAML ファイルを読み込む

YAML ファイルを直接読み込みたいときは、いつでも sfYaml クラスが使えます。このクラスは YAML ファイルを PHP の連想配列に変換できる YAML パーサーです。リスト5-22はサンプルの YAML ファイルを表し、リスト5-23は解析方法を示しています。

リスト5-22 - test.yml ファイルのサンプル

house:
  family:
    name:     Doe
    parents:  [John, Jane]
    children: [Paul, Mark, Simone]
  address:
    number:   34
    street:   Main Street
    city:     Nowheretown
    zipcode:  12345

リスト5-23 - YAML ファイルを連想配列に変換する sfYaml クラスを使う

$test = sfYaml::load('/path/to/test.yml');
print_r($test);
 
Array(
  [house] => Array(
    [family] => Array(
      [name] => Doe
      [parents] => Array(
        [0] => John
        [1] => Jane
      )
      [children] => Array(
        [0] => Paul
        [1] => Mark
        [2] => Simone
      )
    )
    [address] => Array(
      [number] => 34
      [street] => Main Street
      [city] => Nowheretown
      [zipcode] => 12345
    )
  )
)

まとめ

symfony は設定システム (configuration system) をシンプルで読みやすくするためにYAMLフォーマットを利用します。複数の環境 (environment) を扱い定義のカスケードを通してパラメーターを設定する機能によって開発者は多彩なことができます。設定のなかには sfConfig オブジェクトを通してコードの範囲からアクセスできるものが存在します。とりわけアプリケーションの設定は app.yml ファイルに保存されます。

もちろん、symfony はたくさんの設定ファイルを持ちますが、このアプローチによって symfony はより多くのプロジェクトに採用できるものになります。アプリケーションが高度なレベルのカスタマイズを必要としないのであれば、これらの設定ファイルに悩む必要がないことを覚えておいてください。