シンプルで簡単にするために、改修を必要としない標準的なアプリケーションのもっとも一般的な要求にこたえるデフォルト設定を symfony は使っています。しかしながら、単純で強力な設定ファイルのセットの助けを利用してフレームワークとアプリケーションがどのように動くかということについてあらゆるカスタマイズも可能です。これらのファイルを利用して、アプリケーションに特別なパラメータを追加することもできます。
ウェブアプリケーションのフレームワークの大きな利点は、フレームワークが開発者に設定ファイル - それは読むことができないコードではない - を使っているアプリケーションの多くの状況を完全に制御できるようにすることです。もはやロギングの振る舞いを変更したり、URL の表示方法を変更したりするために特別なクラスを探す必要はありません。つまり、ただ設定をおこなうだけです。
しかしながら、この方策には 2 つの深刻な欠点があります。
symfony はもっともベストな設定ファイルで、欠点であるこれらを取り除きました。事実、 symfony における設定システムの野望は次のようになっています。
野望は設定システムのPHPの実装によって可能なため、単なるはかない望みではありません。
symfony は今までよくあった INI や XML フォーマットの代わりに標準の YAML フォーマットを使用しています。この決定はYAMLの大きな利点に基づいています。下記はYAMLサイトからのプロの意見です。 * YAML は人間にとってとても読みやすいドキュメントです。 * YAML はスクリプト言語と上手く相互に作用します * YAML はホスト言語の時刻データ構造を利用します。 * YAML は一貫した情報モデルを持っています。 * YAML は流れに基づく処理を可能にします。 * YAML は表現力が豊かであり、拡張が可能です。 * YAML は実装するのが簡単です。
INI とは反対に、YAML は階層をサポートしています。XML とは反対に、YAML は多くで複雑な構文や閉じタグを使いません。現在のところ開発者の間に他のフォーマットと比べて広く知られていないということが YAML の唯一の欠点です。しかしながら、名声が不足しているからといってその特徴を見過ごすということが残念であるということは簡単にわかるでしょう。今現在、もし YAML 構文に精通していないのであれば、ただちに 学び始めるべきです。
他の設定ファイルフォーマットに愛着を持っている人たちも安心してください。つまり、 symfony はいろいろなタイプの設定ファイルをサポートしています。なぜならそれらは簡単に適用できる特別なハンドラー(この章の後半にある設定ハンドラーを参照してください)によって調べられるからです。
YAML ファイルを書くときに気をつける必要がある仕様があります。
決してタブを使わないでください。YAML パーサーはタブを持つファイルを理解できません。なので、スペースによるインデントを行ってください。(連続した空白は symfony ではインデントを表す仕様になっています。)
# 決してタブは使わない
all:
-> mail:
-> -> webmaster: webmaster@mysite.com
# 代わりに空白を使います
all:
mail:
webmaster: webmaster@mysite.com
値として配列を定義するときに、[] で要素を閉じ込めるか、拡張仕様である - を使ってください。
# 配列を表す省略形の構文
all:
params: [value1, value2]
# 配列を表す拡張構文
all:
params:
- value1
- value2
もしスペースで始まるか終わる文字列のパラメータであれば、シングルクォートで値を囲んでください。もし、特殊な文字を含む場合もクォートに値を閉じ込めてください。
# スペースで始まったり終わっている場合はシングルクォートで閉じます
all:
param1: This is a normal string
param2: ' This is a special string '
param3: 'That''s all folks!'
bool 値を与えるために、正値としての 1 か true、負値としての 0 か false のどちらかを使います。
# bool値
true_values:
- on
- 1
- true
false_values:
- off
- 0
- false
YAML website に YAML 構文の広範囲な説明があります。
思い出してください、symfony は 3 つのデフォルト環境、つまり製品版(prod)、テスト版( test )、そして開発版( dev )を提供しています。そしてあなたが望むカスタム環境を追加することができます。
異なる環境において( web フロントコントローラーは別ですが)同じ PHP コードを共有していますが、完全に異なる設定ファイルを持つことができます。したがって各環境は異なるデータベースへ接続することができるのです。
開発環境においては、ロギングとデバッグ設定がされています。なぜなら、メンテナンスがパフォーマンスよりも重要であるからです。一方で、製品環境はデフォルトでパフォーマンスを重視した設定がなされています。そのため製品設定は多くの特徴を切っています。
テスト環境の場合は少しばかり特別です。この環境はコマンドラインでプロジェクトからコードを実行するときに利用されます。そして大抵単体テストのときに利用されます。 結果として、テスト環境は製品設定に近いものになります。しかし、ウェブブラウザとの会話はありません。クッキーや HTTP 仕様のコンポーネントの使用をシミュレーションします。
新しい環境を加えるために、ディレクトリを作ったり、symfony コマンドを使う必要はありません。単純に製品のフロントコントローラー( myproject/web/index.php )を index_myenv.php などの名前のファイルで複製しこのファイル中で SF_ENVIRONMENT 定義を myenv に変更します。それで、新しい環境が準備できます。見ればわかるように、全ての環境に共通する設定を付け加えた標準の設定がこの環境には継承されます。
symfony には数種類の設定レベルがあります。
myproject/config/ ディレクトリ内にある)プロジェクト全体のためのグローバル設定myproject/apps/myapp/config/ 内にある)プロジェクトのアプリケーションのためのローカル設定myproject/apps/myapp/modules/mymodule/config 内にあるモジュールに制限されたローカル設定environment levels )
カスタマイズできる設定の全ては環境に左右されます。そのため、多くの YAML 設定ファイルは環境によって分けられるべきです。そしてファイルの最後に全て(all)環境のためのセクションを追加します。結果、次のようなsymfony 設定ファイルになります。
# 製品環境の設定
prod:
...
# 開発環境の設定
dev:
...
# テスト環境の設定
test:
...
# カスタム環境の設定
myenv:
...
# 全ての環境共通の設定
all:
...
さらに、プロジェクトのツリー構造の中に位置しない、symfony をインストールした $data_dir/symfony/config ディレクトリにあるファイルにあるデフォルト値をフレームワーク自体が定義しています。これらの設定は全てのアプリケーションによって継承されます。
# デフォルト設定:
default:
...
これらの標準設定の一部はproject/app/module設定ファイル中においてコメントアウトして(先頭に # がついて)繰り返されています。そのため、パラメータの中には標準で定義されているものもあり、修正できるということがわかるでしょう。
all:
# default_module: default
# default_action: index
#
# error_404_module: default
# error_404_action: error404
#
# login_module: default
# login_action: login
これはプロパティは数回定義されることができるということを意味し、次のような定義順で正確な値がわかります。
全ての設定ファイルが環境に依存しているとは限りません。
設定ファイルの可読性を上げるために、symfony ではカテゴリにパラメータの定義を置いています。次は app.yml のサンプルです。
all:
.general:
tax: 19.6
pager:
max_per_page: 5
mail:
webmaster: webmaster@mysite.com
commercial: commerce@mysite.com
.general、 pager、 mail 行はカテゴリの見出し行です。.文字で始まる見出し行は読みやすさと情報のためにあります。それに対して他の行は名前空間(name space)です。同じ名前空間を共有しないのであれば、名前空間によって数種類のパラメータのために同じkeyを使うことができます。
全ての設定ファイルは最終的に PHP に変換されます。しかし、パラメータの中にはコードからアクセスできるものもあります。この場合、特別な sfConfig クラスを通して利用することができます。それは設定パラメータのためのレジストリであり、単純な getter や setter クラスメソッドを通して、コードのあらゆる箇所からアクセスできます。
sfConfig::set('param_name', $value); // 設定を定義する parameter = sfConfig::get('param_name', $default_value); // 設定値を取得する
symfony の設定パラメータは PHP 定数の全アドバンテージを持っていますが、値を変更できてしまうので、不都合な点も持っています。
たとえば、PHP コードから前の例において定義した値にアクセスする場合次のように書くでしょう
sfConfig::get('app_tax'); sfConfig::get('app_pager_max_per_page'); sfConfig::get('app_mail_webmaster'); sfConfig::get('app_mail_commercial');
名前は次のものによって連結されています。
sf_ は setings.yml、app_ はapp.yml、 mod_ は module.yml )PHP コードはそれが実行される環境のための定義された値へのみアクセスできるので、環境に関するものは含まれていません。
コードにカスタム設定を追加する方法が2つあります。
myproject/apps/myapp/config/app.yml にはアプリケーションのための設定myproject/apps/myapp/modules/mymodule/config/module.yml にはモジュールのための設定 (デフォルトでは存在しません)例えば、サイトにクレジットカード操作を追加する必要があるなら、次のようにapp.ymlに書くことができます。
all:
creditcards:
fake: off
visa: on
americanexpress: on
dev:
creditcards:
fake: on
fake クレジットカードが現在の環境で受け入れられるかどうか知るためには、次のようにして値を取得します
sfConfig::get('app_creditcards_fake');
しかし、1つの配列や、多くのパラメータを持つ連想配列を追加する必要があるかもしれない。この場合には付随するconfigrationハンドラと一緒に、新しい設定ファイルを作成するほうが良いでしょう。
注意: プロジェクトのカスタム設定のために、
config/config.phpファイルをsfConfig::set()関数で呼び出したり、あなた自身の YAML ファイルにて定義しsfYaml::load($file)関数で読み込んだりすることができます。autolodingはconfig.phpが実行されたときに有効になっていないことに注意してください。そのため、必要なファイルを手動で読み込ませる必要があります。
設定が外部パラメータ (データベース、他の設定ファイル) に依存している場合もあるでしょう。これらの場合のために、 symfony 設定ファイルは YAML でパースされる前に PHPファイルとしてパースされます。これは次のように書けることを意味します。
all:
translation:
format: <?php echo sfConfig::get('sf_i18n') == true ? 'xliff' : 'none' ?>
そうです。PHP コードを YAML ファイル内に置くことができるのです!
そうはいうもののリクエストの初期段階においてパースされ、symfonyの組み込み関数が利用できないということに気づくでしょう。もし他に依存するある設定ファイルを利用したいなら、前もってパースされた外部に依存するファイルを確認する必要があります。 ( どの順序で設定ファイルがパースされるかを symfony のソースコード 内で確認してください)。 app.yml ファイルは最後にパースされるファイルの 1 つです。そのため、ここで他に依存させるかもしれません。
また、製品環境では設定ファイルはキャッシュされるので、設定ファイルは一度キャッシュをクリアしたあとにだけ、パースされ (実行され) ます。
注意: もしあなたが必要とする定義された設定が他の設定ファイルで繰り返されているのであれば、定数トリックを使います。前もって定義された設定は YAML ファイル内で定数として利用できます。 - ただ、大文字の名前で % 文字で囲まれているだけです。たとえば、次に
setting.ymlで設定した定義をview.ymlファイルでどのように再利用しているかを説明します。
all:
javascripts: [%SF_PROTOTYPE_WEB_DIR%/js/prototype]
そして、YAML に対してアレルギー反応があったり、設定ファイルと設定ハンドラーの両方で最終的に PHP の連想配列を取得するのを避けたほうがいいと思うのであれば、 YAML ファイルのパース処理を完全にバイパスさせ、 YAML ファイルにおいて PHP 配列を返すことができます。これは次のように logging.yml ファイルが書けるということです。
<?php return array( 'default' => array( 'enabled' => true, 'level' => 'debug' ) );
...これまでのような下記の書き方の代わりになります。
default:
enabled: on
level: debug
設定ファイルはそれらのファイルがどんなフォーマットであれ、高速処理される PHP コードに翻訳するhandlersと呼ばれる特別なクラスによって処理されます。開発環境において良い反応性を許すために、すぐに YAML ファイルにある変更を理解できるようにハンドラーは各リクエストごとに構成を解析します。しかし、もちろん、製品環境においては、最初のリクエスト中で一度だけ処理します。そして、そのときにキャッシュに PHP コードを保存する処理を行います。製品版における各リクエストは最適化された PHP コードを実行するだけなので、パフォーマンスは保証されます。
たとえば、app.yml は次のようなデータを含んでいます。
all:
mail:
webmaster: webmaster@mysite.com
プロジェクトの cache フォルダにある config_app.yml.php には次のようなデータを含んであるでしょう
<?php sfConfig::add(array( 'app_mail_webmaster' => 'webmaster@mysite.com', )); ?>
これは多くの PHP フレームワーク、ここでいう PHP フレームワークとは製品版において、各リクエストに対して毎回設定ファイルがコンパイルされているフレームワークですが、それらのなかで大きな利点となっています。Java とは違い、PHP はリクエスト間で実行の前後関係を共有することができません。他の PHP フレームワークは、XML 設定ファイルの柔軟性を保つことは各リクエストで全ての設定を処理するために大きなパフォーマンスヒットを要求します。これは symfony においては当てはまりません。つまり、キャッシュシステムのおかげで、設定ファイルの解析が原因によるオーバーヘッドはとても低いのです。
もうひとつのコンフィグレーションハンドラを使う大きな利点は、あなたが YAML 以外のフォーマットを利用することができるということです。コンフィグレーションハンドラは設定ファイルを最適化した PHP コードに翻訳することだけです。もし、あなたが別の言語 - そして PHP はもともと XML や INI ファイルをサポートしています - のパーサーをもっているのなら、あなた自身の設定ファイルフォーマットを読むカスタムハンドラを書くことはとても簡単なことでしょう。
要約すれば、YAML設定ファイルの構文を覚えておくだけです。
environment:
.header1:
key1: value1
key2: value2
namespace1:
key3: value3
key4: value4
# comment
十分にこれらの一般的な考慮すべきところを踏まえ、実際の設定ファイル とYAMLのすばらしい可能性を探求しましょう。