symfony book 日本語ドキュメント

第19章 - symfonyの設定ファイルをマスターする

現在あなたはsymfonyをとてもよく理解しています。すでにコアの設計を理解し、新しい隠し機能を見つけるためにコードを徹底的に調べる準備ができています。しかし、独自要件に適用するためにsymfonyのクラスを拡張するまえに、設定ファイルをもっとよく見ることが必要です。すでに多くの機能はsymfonyに組み込まれ、設定を少し変更すれば有効になります。このことはクラスをオーバーライドしなくてもsymfonyコアのふるまいを調整できることを意味します。この章では設定ファイルとこれらの強力な機能を詳しく説明します。

symfonyの設定

frontend/config/settings.ymlファイルはおもにfrontendアプリケーション用のsymfonyの設定を含みます。前の章でこのファイルから多くの設定の機能をすでに見てきましたが、再度これらを見ることにします。

5章で説明したように、このファイルは環境に依存します。すなわちそれぞれの設定が環境ごとに異なる値をとります。このファイルで定義されたそれぞれのパラメーターはsfConfigクラスを通してPHPクラスの内部からアクセスできることを覚えておいてください。パラメーター名は設定名にプレフィックスのsf_をつけたものです。たとえば、cacheパラメーターの値を取得したい場合、必要なことはsfConfig::get('sf_cache')を呼び出すだけです。

デフォルトのモジュールとアクション

symfonyは特殊な状況に対してデフォルトページを用意します。ルーティングエラーの場合、symfonyはdefaultモジュールのアクションを実行します。このモジュールは$sf_symfony_lib_dir/controller/default/ディレクトリに保存されています。settings.ymlファイルはエラーごとに実行されるアクションを定義します:

運用サーバーにデプロイするまえにこれらのアクションはアプリケーションをカスタマイズすべきです。defaultモジュールのテンプレートではページにsymfonyのロゴが含まれるからです。これらのページの1つのスクリーンショット、404エラーのページは図19-1をご覧ください。

図19-1 - デフォルトの404エラーページ

デフォルトの404エラーページ

以下の2つの方法でデフォルトのページをオーバーライドできます:

ほかの2つのページはsymfonyの見た目を有しており、運用サーバーにデプロイするまえにこれらのページはカスタマイズすることも必要です。これらのページはdefaultモジュールには存在しません。これはsymfonyが適切に動作しないときに呼び出されるからです。代わりに、これらのデフォルトページは$sf_symfony_lib_dir/exception/data/ディレクトリで見つかります:

これらのページをカスタマイズするには、プロジェクトもしくはアプリケーションのweb/errors/ディレクトリのなかでerror500.phpページとunavailable.phpページを作ります。symfonyは固有のページの代わりにこれらを使うようになります。

NOTE 必要なときにリクエストをunavailable.phpページにリダイレクトするには、アプリケーションのsettings.ymlのなかでcheck_lock設定をonにする必要があります。デフォルトではこの設定は無効です。この設定によってすべてのリクエストに対してわずかですがオーバーヘッドが追加されるからです。

オプション機能の有効

settings.ymlファイルのパラメーターのなかには有効もしくは無効にできるsymfonyのオプション機能をコントロールするものがあります。使わない機能を無効にすることでパフォーマンスが少し押し上げられるので、アプリケーションをデプロイするまえにテーブル19-1に示されている設定の一覧を見直してください。

テーブル 19-1 - settings.ymlファイルを通したオプション機能の一式

パラメーター | 説明 | デフォルト値 ----------------------- | ----------- | ------------- use_database | データベースマネージャを有効にする。データベースを使わない場合はoffに切り替える。 | on i18n | インターフェイスの翻訳機能を有効にする(13章を参照)。他言語アプリケーションのためにonに設定する。 | off logging_enabled | symfonyのイベントのロギングを有効にする。symfonyのロギング機能を完全にオフにしたい場合はoffに設定する。 | on escaping_strategy | 出力エスケーピング機能を有効にする(7章を参照)。テンプレートに渡すデータをエスケープしたい場合はonに設定する。| off cache | テンプレートキャッシュを有効にする(12章を参照)。モジュールの1つがcache.ymlファイルを含む場合にonに設定する。キャッシュフィルター(sfCacheFilter)がonになっている場合にのみ有効 | 開発環境ではoff、運用環境ではon web_debug | 簡単なデバッグのためのWebデバッグツールバーを有効にする(16章を参照)。ツールバーをすべてのページに表示するにはonに設定する。| 開発環境ではon、運用環境ではoff check_symfony_version | すべてのリクエストに対してsymfonyのバージョンチェックを有効にする。symfonyをアップグレードした後に自動的にキャッシュをクリアするためにonに設定する。アップグレードした後につねにキャッシュをクリアする場合はoffのままにしておく。|off check_lock | アプリケーションのロックシステムを有効にする。cache:clearproject:disableタスクによって起動する(以前のセクションを参照)。$sf_symfony_lib_dir/exception/data/unavailable.phpのページにリダイレクトするように無効なアプリケーションにリクエストを行うためにonに設定する。| off compressed | PHPのレスポンス圧縮機能を有効にする。PHP圧縮ハンドラー経由で出力するHTMLを圧縮するにはonにする。 | off

機能のコンフィギュレーション

symfonyは組み込み機能、たとえば、バリデーション、キャッシュ、サードパーティのモジュールなどのふるまいを変更するにはいくつかのsettings.ymlファイルのパラメーターを使います。

出力エスケーピングの設定

出力エスケーピングの設定は変数がテンプレートにアクセスする方法をコントロールします(7章を参照)。settings.ymlファイルはこの機能のために2つの設定を含みます:

ルーティングの設定

ルーティングの設定(9章を参照)はfactories.ymlファイルのなかのroutingキーの下で定義されます。リスト19-1はルーティングのデフォルトコンフィギュレーションを示しています。

リスト19-1 - ルーティングコンフィギュレーションの設定(frontend/config/factories.yml)

routing:
  class: sfPatternRouting
  param:
    load_configuration: true
    suffix:             .
    default_module:     default
    default_action:     index
    variable_prefixes:  [':']
    segment_separators: ['/', '.']
    variable_regex:     '[\w\d_]+'
    debug:              %SF_DEBUG%
    logging:            %SF_LOGGING_ENABLED%
    cache:
      class: sfFileCache
      param:
        automatic_cleaning_factor: 0
        cache_dir:                 %SF_CONFIG_CACHE_DIR%/routing
        lifetime:                  31556926
        prefix:                    %SF_APP_DIR%

sfPatternRoutingクラス専用の設定があります。アプリケーションのルーティング、独自もしくはsymfonyのルーティングファクトリ(sfNoRoutingsfPathInfoRouting)の1つのどちらかに対して別のクラスを利用できます。これらの2つのどちらかを用いることで、すべての外部URLは'module/action?key1=param1'のようになります。カスタマイズする必要はありませんが、速いです。違いは最初のものはPHPのGETを使用し、2番目はPATH_INFOを使います。おもにバックエンドのインターフェイスにこれらを使います。

ルーティングに関連する追加パラメーターが1つありますが、これは settings.ymlファイルに保存されます:

フォームバリデーションの設定

NOTE このセクションで説明されている機能はsymfonyのバージョン1.1では廃止されsfCompat10プラグインを有効にしている場合のみに動作します。

フォームバリデーションの設定はValidationヘルパーによるエラーメッセージが表示される方法をコントロールします(10章を参照)。これらのエラーは<div>に含まれ、id属性を形成するためにこれらのエラーはvalidation_error_class設定とvalidation_error_id_prefix設定をclass属性として使います。デフォルト値はform_errorerror_for_なので、foobarという名前の入力に対してform_error()ヘルパーへの呼び出しによる属性出力はclass="form_error" id="error_for_foobar"になります。

2つの設定はそれぞれのエラーメッセージ: validation_error_prefixvalidation_error_suffixの前後に来る文字を決定します。一度にすべてのエラーメッセージをカスタマイズするためにこれらの設定を変更できます。

キャッシュの設定

キャッシュ設定の大部分はcache.ymlファイルで定義されますが、settings.ymlファイルのなかの2つは異なります: cacheはテンプレートキャッシュのメカニズムを有効にし、etagはサーバーサイド上のETagハンドリングを有効にします(15章を参照)。factories.ymlファイルのなかで2つのすべてのキャッシュシステム(ビューキャッシュ、ルーティングキャッシュと、国際化キャッシュ)に対してどのストレージを使うのかを指定することもできます。リスト19-2はビューのキャッシュファクトリのデフォルトコンフィギュレーションを示しています。

リスト19-2 - ビューのキャッシュコンフィギュレーション(frontend/config/factories.yml)

view_cache:
  class: sfFileCache
  param:
    automatic_cleaning_factor: 0
    cache_dir:                 %SF_TEMPLATE_CACHE_DIR%
    lifetime:                  86400
    prefix:                    %SF_APP_DIR%/template

classの値はsfFileCachesfAPCCachesfEAcceleratorCachesfXCacheCachesfMemcacheCache、と sfSQLiteCacheのどれかになります。sfCacheを継承しキャッシュのキーの読みとりと削除をする、設定用の同じ一般的なメソッドを提供するのであれば、独自クラスも可能です。ファクトリのパラメーターは選んだクラスに依存しますが、定数が存在します:

それぞれの特定のファクトリに関しては、キャッシュストレージの位置を定義しなければなりません。

追加パラメーターに関しては、それぞれのキャッシュクラスのAPIドキュメントを確認してください。

ビューはキャッシュを使える唯一のコンポーネントではありません。routingファクトリとI18Nファクトリの両方は、ビューキャッシュと同じように、キャッシュファクトリを設定できるcacheパラメーターを提供します。たとえば、リスト19-1はデフォルトで加速戦術用にファイルキャッシュを使うルーティングを示していますが、望むものは何でも変更できます。

ロギングの設定

2つのロギングの設定(16章を参照)はsettings.ymlファイルに保存されます:

アセットへのパス

settings.ymlファイルはアセットへのパスも保存します。symfonyに搭載されたアセット以外の別のバージョンのアセットを使いたい場合、これらのパス設定を変更できます:

デフォルトのヘルパー

デフォルトのヘルパーは、すべてのテンプレートに対してロードされ、standard_helpers設定で宣言されます(7章を参照)。デフォルトでは、これらはPartialCacheFormヘルパーグループです。アプリケーションのすべてのテンプレート内部でヘルパーグループを利用する場合、standard_helpers設定にヘルパーグループの名前を追加すればそれぞれのテンプレート上でuse_helper()ヘルパーを用いてヘルパーグループを宣言する煩わしい手続きを行わずにすみます。

有効なモジュール

プラグインもしくはsymfonyコアから有効にされるモジュールはenabled_modulesパラメーターで宣言されます。プラグインがモジュールを搭載する場合、enabled_modulesパラメーターで宣言されないかぎりユーザーはこのモジュールをリクエストできません。defaultモジュールはsymfonyのデフォルトページ(congratulations、page not foundページなど)を提供し、デフォルトで唯一有効なモジュールです。

文字集合

レスポンスの文字集合はアプリケーション全体の設定です。フレームワークの多くのコンポーネントで使われるからです(テンプレート、出力エスケーパ、ヘルパーなど)。定義されるcharset設定のデフォルト値はutf-8(推奨)です。

そのほかの設定

settings.ymlファイルはコアのふるまいのためにsymfonyが内部で利用するいくつかのパラメーターを含みます。リスト19-3は設定ファイルに現れるパラメーターの一覧です。

リスト19-3 - そのほかの設定(frontend/config/settings.yml)

# symfonyのコアクラスのコメントをcore_compile.ymlファイルで定義されたものとして除去する
strip_comments:         on
# 例外の起動前のアクションの前のフォワードの最大回数
max_forwards:           5
# グローバル定数
path_info_array:        SERVER
path_info_key:          PATH_INFO
url_format:             PATH

SIDEBAR アプリケーションの設定を追加する

settings.ymlファイルはアプリケーションに対してsymfonyの設定を定義します。5章で説明したように新しいパラメーターを追加したい場合、最適の場所はfrontend/config/app.ymlファイルです。このファイルは環境にも依存しており、このファイルが定義する設定の値はsfConfigクラスとプレフィックスのapp_を通して利用できます。

all:
  creditcards:
    fake:             off    # app_creditcards_fake
    visa:             on     # app_creditcards_visa
    americanexpress:  on     # app_creditcards_americanexpress

プロジェクトの設定ディレクトリのなかでapp.ymlファイルを書くこともでき、カスタムプロジェクト設定を定義できます。設定カスケードはこのファイルにも適用されるので、アプリケーションのapp.ymlファイルで定義された設定はプロジェクトレベルで定義された設定をオーバーライドします。

オートロード機能を拡張する

オートロード機能は2章で手短に説明しましたが、これによってコードが特定のディレクトリに設置していればクラスをrequireせずにすみます。このことは、symfonyに、必要なときだけ、適切な時点に必要なクラスだけをロードする作業を任せられることを意味します。

autoload.ymlファイルはオートロードされたクラスが保存されるパスの一覧を示します。この設定ファイルが最初に処理されたとき、symfonyはこのファイルに参照されたすべてのディレクトリを解析します。.phpの拡張子を持つファイルがこれらのディレクトリの1つのなかで見つかるたびに、このファイルのなかで見つかるファイルパスとクラス名がオートロードクラスの内部リストに追加されます。このリストはキャッシュ、config/config_autoload.ymlファイルに保存されます。それから、実行時に、クラスが使われたとき、このリストのなかでsymfonyはクラスのパスを探し.phpファイルを自動的にインクルードします。

オートロード機能はクラスかつ/またはインターフェイスを含むすべての.phpファイルに対して機能します。

デフォルトでは、つぎのプロジェクトディレクトリに保存されたクラスはオートロード機能からの恩恵を受けます:

autolaod.ymlファイルはアプリケーションのデフォルトの設定ディレクトリ内には存在しません。symfonyの設定を修正したい場合、たとえばファイル構造のどこかに保存されたクラスをオートロードするには、空のautoload.ymlファイルを作り、$sf_symfony_lib_dir/config/autoload.ymlファイルもしくは独自ファイルの設定をオーバーライドします。

autoload.ymlファイルはautoload:キーで始まり、symfonyがクラスを探す場所のリストを記載しなければなりません。それぞれの場所はラベルを必要とします: これによってsymfonyのエントリーをオーバーライドできます。それぞれの場所に対して、name(config_autload.yml.phpでコメントとして表示される)と絶対パス(path)を記入してください。それから、検索が再帰的(recursive)であるように定義すると、symfonyはすべてのサブディレクトリで.phpファイルを探します。また望むサブディレクトリを除外(exclude)します。リスト19-2はデフォルトで使われる場所とファイルの構文を示しています。

リスト19-4 - オートロードのデフォルトコンフィギュレーション($sf_symfony_lib_dir/config/autoload.yml)

autoload:
  # プラグイン
  plugins_lib:
    name:           plugins lib
    path:           %SF_PLUGINS_DIR%/*/lib
    recursive:      on

  plugins_module_lib:
    name:           plugins module lib
    path:           %SF_PLUGINS_DIR%/*/modules/*/lib
    prefix:         2
    recursive:      on

  # プロジェクト
  project:
    name:           project
    path:           %SF_LIB_DIR%
    recursive:      on
    exclude:        [model, symfony]

  project_model:
    name:           project model
    path:           %SF_LIB_DIR%/model
    recursive:      on

  # アプリケーション
  application:
    name:           application
    path:           %SF_APP_LIB_DIR%
    recursive:      on

  modules:
    name:           module
    path:           %SF_APP_DIR%/modules/*/lib
    prefix:         1
    recursive:      on

ルールのパスにワイルドカードを含めることは可能で設定クラスのなかで定義されるファイルパスのパラメーターが使えます(つぎのセクションを参照)。設定ファイルのなかでこれらのパラメーターを使う場合、これらのパラメーターは大文字で始めと終わりを%で挟まなければなりません。

独自のautoload.ymlファイルを編集すれば 新しい位置がsymfonyのオートロード機能に追加されますが、このメカニズムを拡張してsymfonyのハンドラーに独自のオートロードハンドラーを追加したいことがあります。symfonyはクラスのオートロードを管理するために標準のspl_autoload_register()関数を使うので、アプリケーションの設定クラスに複数のコールバックを登録できます:

[php]
class frontendConfiguration extends sfApplicationConfiguration
{
  public function initialize()
  {
    parent::initialize(); // symfonyのオートロード機能を最初にロードする

    // 独自のオートロードコールバックをここに挿入する
    spl_autoload_register(array('myToolkit', 'autoload'));
  }
}

PHPのオートロードシステムは新しいクラスに遭遇するとき、最初にsymfonyのオートロードメソッドが試されます(そしてautoload.ymlファイルのなかで定義された位置が使われます)。クラスの定義が見つからない場合、クラスが見つかるまでspl_autoload_register()で登録されたすべてのcallableが呼び出されます。たとえば、ほかのフレームワークコンポーネントへのブリッジを提供するために(17章参照)、望む数だけオートロードメカニズムを追加できます。

カスタムファイル構造

symfonyフレームワークは何か(コアクラスからテンプレート、プラグイン、設定、など)を探すためにパスを使うたびに、実際のパスの代わりにパス変数を使います。これらの変数を変更することで、symfonyプロジェクトのディレクトリ構造を完全に変更して、顧客のファイル構造の要件に適合させることができます。

CAUTION symfonyプロジェクトのディレクトリ構造をカスタマイズするのは可能ですが、かならずしもよいアイディアではありません。symfonyのようなフレームワークの強みの一つは、規約を尊重されることでWeb開発者が慣習を尊重して開発されたプロジェクトを見て安心できることです。独自のディレクトリ構造を利用することを決定するまえにかならずこの問題を考えてください。

基本的なファイル構造

パス変数はsfProjectConfigurationsfApplicationConfigurationクラスのなかで定義されsfConfigオブジェクトに保存されます。リスト19-5はパス変数とこれらが参照するディレクトリの一覧を示しています。

リスト19-5 - sfProjectConfigurationsfApplicationConfigurationのなかで定義された、デフォルトのファイル構造の変数

sf_root_dir           # myproject/
sf_apps_dir           #   apps/
sf_app_dir            #     frontend/
sf_app_config_dir     #       config/
sf_app_i18n_dir       #       i18n/
sf_app_lib_dir        #       lib/
sf_app_module_dir     #       modules/
sf_app_template_dir   #       templates/
sf_cache_dir          #   cache/
sf_app_base_cache_dir #     frontend/
sf_app_cache_dir      #       prod/
sf_template_cache_dir #         templates/
sf_i18n_cache_dir     #         i18n/
sf_config_cache_dir   #         config/
sf_test_cache_dir     #         test/
sf_module_cache_dir   #         modules/
sf_config_dir         #   config/
sf_data_dir           #   data/
sf_doc_dir            #   doc/
sf_lib_dir            #   lib/
sf_log_dir            #   log/
sf_test_dir           #   test/
sf_plugins_dir        #   plugins/
sf_web_dir            #   web/
sf_upload_dir         #     uploads/

重要なディレクトリへのすべてのパスは_dirで終わるパラメーターによって決定されます。あとで必要なときにパスを変更できるように、本当の(相対もしくは絶対)ファイルパスの代わりにパス変数をつねに使用してください。たとえば、ファイルをアプリケーションのuploads/ディレクトリに移動させたいとき、パスに対してsfConfig::get('sf_root_dir').'/web/uploads/'の代わりにsfConfig::get('sf_upload_dir')を使います。

ファイル構造をカスタマイズする

アプリケーションを開発するさいに、顧客がすでにディレクトリ構造を定義しており、symfonyのロジックに適合させるために構造を変更する意志のない場合、おそらくデフォルトのプロジェクトファイル構造を修正する必要があります。sf_XXX_dir変数をsfConfigでオーバーライドすることで、デフォルトとはまったく異なるディレクトリ構造でsymfonyを動かすことができます。これを行う最良の場所はプロジェクトのディレクトリに対してはアプリケーションのProjectConfigurationクラス、もしくはアプリケーションのディレクトリに対してはXXXConfigurationクラスです。

たとえば、すべてのアプリケーションにテンプレートのレイアウト用の共通ディレクトリを共有させたい場合、sf_app_template_dir設定をオーバーライドするためにつぎの行をProjectConfigurationクラスのconfigure()メソッドに追加します:

[php]
sfConfig::set('sf_app_template_dir', sfConfig::get('sf_root_dir').DIRECTORY_SEPARATOR.'templates');

NOTE sfConfig::set()を呼び出してプロジェクトのディレクトリ構造を変更できる場合でも、すべての関連パスの変更が考慮されるのでプロジェクトとアプリケーションの設定クラスによって定義された専用メソッドを使うほうが優れています。たとえば、setCacheDir()メソッドはつぎの定数: sf_cache_dirsf_app_base_cache_dirsf_app_cache_dirsf_template_cache_dirsf_i18n_cache_dirsf_config_cache_dirsf_test_cache_dir、とsf_module_cache_dirを変更します。

Web公開のrootディレクトリの修正

設定クラスに組み込まれたすべてのパスはプロジェクトのrootディレクトリに依存します。このディレクトリパスはプロジェクトのなかのProjectConfigurationファイルによって決定されます。通常のrootディレクトリはweb/ディレクトリの上位にありますが、異なる構造を利用できます。メインのディレクトリ構造が2つのディレクトリから構成される場合を考えてみます。リスト19-7で示されるように、1つのディレクトリは公開領域で、もう1つのディレクトリは非公開領域に存在します。プロジェクトを共用ホスティングサービス上でホストするときにこのコンフィギュレーションを選ぶことはよくあります。

リスト19-7 - 共用サーバーのためのカスタムディレクトリ構造の例

symfony/    # 非公開領域
  apps/
  config/
  ...
www/        # 公開領域
  images/
  css/
  js/
  index.php

この場合、rootディレクトリはsymfony/ディレクトリです。ですのでアプリケーションを動かすにはindex.phpフロントコントローラーがconfig/ProjectConfiguration.class.phpファイルをインクルードすることがだけが必要です:

[php]
require_once(dirname(__FILE__).'/../symfony/config/ProjectConfiguration.class.php');

加えて、つぎのように、公開領域を通常のweb/からwww/に変更するにはsetWebDir()メソッドを使います:

[php]
class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    // ...

    $this->setWebDir($this->getRootDir().'/../www');
  }
}

symfonyのライブラリにリンクする

リスト19-8で見られるように、symfonyへのパスは、config/ディレクトリ内に設置された、ProjectConfigurationクラスのなかで定義されます。

リスト19-8 - symfonyライブラリへのパス(myproject/config/ProjectConfiguration.class.php)

[php]
<?php

require_once '/path/to/symfony/lib/autoload/sfCoreAutoload.class.php';
sfCoreAutoload::register();

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
  }
}

コマンドラインからphp symfony generate:projectタスクを呼び出すとき、パスは初期化され、プロジェクトをビルドするために使われるsymfonyの設置ディレクトリを参照します。これはコマンドラインとMVCアーキテクチャの両方から利用されます。

このことはsymfonyのファイルへのパスを変更することでsymfonyの別の設置ディレクトリに切り替え可能であることを意味します。

このパスは絶対パスでなければなりませんが、dirname(__FILE__)を利用することで、プロジェクト構造内部のファイルを参照してプロジェクトを設置するために選ばれたディレクトリの独立性を保つことができます。たとえば、つぎのコードのように、多くのプロジェクトがsymfonyのlib/ディレクトリをプロジェクトのlib/vendor/symfony/ディレクトリのシンボリックリンクとして設定します:

myproject/
  lib/
    vendor/
      symfony/ => /path/to/symfony/

この場合、つぎのようにProjectConfigurationクラスはsymfonyのlibディレクトリを必要とするだけです:

[php]
<?php

require_once dirname(__FILE__).'/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php';
sfCoreAutoload::register();

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
  }
}

プロジェクトのlib/vendor/ディレクトリ内でsymfonyのファイルをsvn:externalsプロパティとして格納することを選んだ場合にも同じ原則があてはまります:

myproject/
  lib/
    vendor/
      svn:externals symfony http://svn.symfony-project.com/branches/1.1

TIP アプリケーションを稼働させているサーバーが異なる場合symfonyのライブラリへのパスが異なることがあります。これを有効にする1つの方法は(rsync_exclude.txtに追加することで)ProjectConfiguration.class.phpファイルを同期化の対象から除外することです。ほかの方法は開発と運用の両方のProjectConfiguration.class.phpファイルで同じパスを保つことですが、シンボリックリンクを指し示すこれらのパスがサーバーによって変わる可能性があります。

コンフィギュレーションハンドラーを理解する

それぞれの設定ファイルはハンドラーを持ちます。コンフィギュレーションハンドラー(configuration handler)の仕事は設定カスケードを管理することと、実行時に設定ファイルを最適化して実行可能なPHPコードに変換することです。

デフォルトのコンフィギュレーションハンドラー

デフォルトのハンドラー設定は$sf_symfony_lib_dir/config/config/config_handlers.ymlファイルに保存されます。このファイルはファイルパスにしたがってハンドラーを設定ファイルにリンクします。リスト19-9はこのファイルの内容を抜粋したものです。

リスト19-9 - $sf_symfony_lib_dir/config/config/config_handlers.ymlファイルの抜粋

config/settings.yml:
  class:    sfDefineEnvironmentConfigHandler
  param:
    prefix: sf_

config/app.yml:
  class:    sfDefineEnvironmentConfigHandler
  param:
    prefix: app_

config/filters.yml:
  class:    sfFilterConfigHandler

modules/*/config/module.yml:
  class:    sfDefineEnvironmentConfigHandler
  param:
    prefix: mod_
    module: yes

それぞれの設定ファイルに対して(config_handlers.ymlファイルはワイルドカードを持つファイルパスでそれぞれのファイルを識別する)、ハンドラークラスはclassキーの下で指定されます。

sfDefineEnvironmentConfigHandlerクラスによって処理される設定ファイルの設定はsfConfigクラスを通してコードのなかで直接利用できるようになり、paramキーはプレフィックスの値を含みます。

設定ファイルを処理するために使われるハンドラーの追加もしくは修正ができます。たとえば、YAMLファイルの代わりにINIファイルもしくはXMLファイルを使うためです。

NOTE config_handlers.ymlファイル用のコンフィギュレーションハンドラーはsfRootConfigHandlerクラスで、あきらかに変更できません。

設定の解析方法を修正する必要がある場合、アプリケーションのcofig/フォルダー内に空のconfig_handlers.ymlファイルを作り、classキーの行を書いたクラスでオーバーライドします。

独自ハンドラーを追加する

設定ファイルを処理するハンドラーを利用することで2つの大きな利点がもたらされます:

独自のコンフィギュレーションハンドラーを書きたい場合、$sf_symfony_lib_dir/config/ディレクトリのなかでsymfonyによって使われる構造の例にしたがってください。

アプリケーションがmyMapAPIクラスを含む場合を考えてみましょう。myMapAPIクラスは地図を配信するサードパーティのサービスのためのインターフェイスを提供します。リスト19-10で示されるように、このクラスはURLとユーザー名で初期化することが必要です。

リスト19-10 - myMapAPIクラスの初期化の例

[php]
$mapApi = new myMapAPI();
$mapApi->setUrl($url);
$mapApi->setUser($user);

アプリケーションのconfig/ディレクトリ内に設置された、map.ymlという名前のカスタム設定ファイルでこれら2つのパラメーターを保存するとよいでしょう。この設定ファイルはつぎのような内容を含むことがあります:

api:
  url:  map.api.example.com
  user: foobar

これらの設定をリスト19-8と同等なコードに変換するために、コンフィギュレーションハンドラーを作成しなければなりません。それぞれのコンフィギュレーションハンドラーはsfConfigHandlerクラスを拡張しexecute()メソッドを提供しなければなりません。execute()メソッドはパラメーターとして設定ファイルへのファイルパスの配列が必要で、キャッシュファイルに書き込まれるデータを返さなければなりません。YAMLファイル用のハンドラーはsfYamlConfigHandlerクラスを拡張します。このクラスはYAMLパーサーのために追加のファシリティを提供します。map.ymlファイルに対する典型的なコンフィギュレーションハンドラーはリスト19-11で示されるように書けます。

リスト19-11 - カスタムコンフィギュレーションハンドラー(frontend/lib/myMapConfigHandler.class.php)

[php]
<?php

class myMapConfigHandler extends sfYamlConfigHandler
{
  public function execute($configFiles)
  {
    // yamlを解析する
    $config = $this->parseYamls($configFiles);

    $data  = "<?php\n";
    $data .= "\$mapApi = new myMapAPI();\n";

    if (isset($config['api']['url'])
    {
      $data .= sprintf("\$mapApi->setUrl('%s');\n", $config['api']['url']);
    }

    if (isset($config['api']['user'])
    {
      $data .= sprintf("\$mapApi->setUser('%s');\n", $config['api']['user']);
    }

    return $data;
  }
}

symfonyがexecute()メソッドに渡す$configFiles配列はconfig/フォルダーのなかで見つかるすべてのmap.ymlファイルへのパスを格納します。parseYamls()メソッドは設定カスケードを扱います。

この新しいハンドラーをmap.ymlファイルと関連づけるには、つぎのような内容を持つconfig_handlers.yml設定ファイルを作成しなければなりません:

config/map.yml:
  class: myMapConfigHandler

NOTE classはオートロードするか(上記の例)ファイルパスがparamキーの下のfileパラメーターで指定されたファイルのなかで定義しなければなりません。

ほかの多くのsymfony設定ファイルに関しては、PHPコードにコンフィギュレーションハンドラーを直接追加することもできます:

sfContext::getInstance()->getConfigCache()->registerConfigHandler('config/map.yml', 'myMapConfigHandler', array());

アプリケーション内部でmap.ymlファイルに基づきmyMapConfigHandlerハンドラーによって生成されたコードが必要な場合、つぎの行を呼び出してください:

[php]
include(sfContext::getInstance()->getConfigCache()->checkConfig('config/map.yml'));

checkConfig()メソッドを呼び出すとき、map.yml.phpファイルがキャッシュにまだ存在しないもしくはmap.ymlファイルがキャッシュよりも新しい場合、symfonyは設定ディレクトリ内で既存のmap.ymlファイルを探しconfig_handlers.ymlファイルで指定されたハンドラーを利用してこれらのファイルを処理します。

TIP YAMLの設定ファイル内部で環境を扱いたい場合、ハンドラーはsfYamlConfigHandlerクラスの代わりにsfDefineEnvironmentConfigHandlerクラスを拡張できます。設定を読みとるには、parseYaml()メソッドの代わりにgetConfiguration()メソッド: $config = $this->getConfiguration($configFiles)を呼び出します。

-

SIDEBAR 既存のコンフィギュレーションハンドラーを利用する

ユーザーがsfConfigクラス経由でコードから値を読みとることができるようにする必要があるだけなら、sfDefineEnvironmentConfigHandlerコンフィギュレーションハンドラークラスを利用できます。たとえば、urluserパラメーターをそれぞれsfConfig::get('map_url')sfConfig::get('map_user')として使えるようにするには、ハンドラーをつぎのように定義します:

config/map.yml:
  class: sfDefineEnvironmentConfigHandler
  param:
    prefix: map_

すでにほかのハンドラーによって使われているプレフィックスを選ばないように気をつけてください。 既存のプレフィックスはsf_app、とmod_です。

まとめ

設定ファイル(configuration file)はsymfonyフレームワークの動作方法を大いに変更します。symfonyはコア機能とファイルの読み込みでさえも設定に依存するので、標準の専用ホストよりも多くの環境に適用できます。このすばらしい設定の柔軟性はsymfonyの主要な強さの1つです。設定ファイルのなかで学ぶべきたくさんの規約を見た初心者を怖がらせることがあるにせよ、このことによってsymfony製のアプリケーションは膨大な数のプラットフォーム、環境に対して、互換性があります。ひとたびsymfonyの設定を習得したら、あなたのアプリケーションを動かすことを拒むサーバーは存在しないでしょう。