Symfony Best Practice 訳してみた - Chapter3 -
Symfony Best Practiceの翻訳をしてます。 三日目です。
前回の記事
※多分に意訳が入っておりますので、誤訳がある場合はご指摘ください。
※読み進めていくSymfony Best Practiceは 2016/10/23時点の情報です。
※写経をする場合は、事前にPHPの実行ができる環境をご用意ください。
3行まとめ
parameters.yml/config_dev.yml/config_prod.yml の使い分けをしよう。
この先変更されない値は定数化を検討しよう。
必要ないセマンティックコンフィグレーションを避けよう。
第3章 Configuration
環境設定には、動作環境や権限付与のような異なるアプリケーションの要素、開発環境、運用環境といった環境の違いが、往々にして含まれます。 このため、Symfonyでは環境設定を3つのパートに分けることをお勧めします。
インフラ関係の設定
- インフラに関連する環境設定は、app/config/parameters.ymlに定義しましょう。
デフォルトの parameters.ymlには、インフラの設定と、データベース、メールに関する設定が記載されています。
# app/config/parameters.yml parameters: database_driver: pdo_mysql database_host: 127.0.0.1 database_port: ~ database_name: symfony database_user: root database_password: ~ mailer_transport: smtp mailer_host: 127.0.0.1 mailer_user: ~ mailer_password: ~ # ...
こうした設定がapp/config/config.ymlに記載されないのは、設定がアプリケーションの振る舞い自体になんら関係しないからです。 換言すれば、これから開発するアプリケーションは、データベースが正しく設定されていさえすれば、データベースがどこにあるか、アクセス権限があるかといったことを気にする必要がないということです。
標準的なパラメーター
- アプリケーションに関するパラメーターは全てapp/config/parameters.yml.distに定義しましょう。
Symfonyはアプリケーションに関する標準的な設定を記載したparameters.yml.distを読み込みます。 新たなパラメーターが追加されるたびに、parameters.yml.distの更新も忘れずに実施して、バージョン管理するようにしましょう。 そうすることで、開発者がアプリを更新したり、デプロイしたりするたびにSymfonyがparameters.ymlとの差分をチェックしてくれます。 差分があった場合、Symfonyは開発者に新たなパラメーターの記載を要求した上で、parameters.ymlに追加してくれます。
アプリケーションに関する設定
- アプリケーションの振る舞い関する設定はapp/config/config.ymlに定義しましょう。
config.ymlにはメール通知やfeature toggle *1のon/offといった、アプリケーションの振る舞いを制御するオプションを含みます。こうした値をparameters.ymlに書くこともできますが、サーバーごとに値を変える必要はないでしょうから、無理にレイヤーを追加してまで定義する必要はないでしょう。 config.ymlに定義されている設定は、往々にして環境によって変わります。 そのため、環境ごとに設定を上書きできるように、Symfonyではあらかじめapp/config/config_dev.ymlとapp/config/config_prod.ymlを用意しています。
定数VS設定
アプリケーションのオプションを設定する際に最も犯しがちな間違いは、ページネーションの数など、変更されることがない値をオプションとして定義してしまうことです。
- 変更されることが予想されいてない設定は定数として定義しましょう。
オプションによる設定をする方法では、以下のようにブログのページに何件記事を表示するかといった設定を読み込ませるようにしてきました。
# app/config/config.yml parameters: homepage.num_items: 10
こうした設定に身に覚えのある方ならおわかりでしょう。こうした値を変更する必要が出てくることは決してありません。 変更する予定のない設定をオプションに追加する必要はありません。 そういった値は定数としてアプリケーションの中に定義することをおすすめします。可能であれば、例えばNUM_ITEMSという定数をPostエンティティに定義するのが良いでしょう。
// src/AppBundle/Entity/Post.php namespace AppBundle\Entity; class Post { const NUM_ITEMS = 10; // ... }
定数化する最大の利点は、アプリケーションのどこからでもアクセスできるという点です。 パラメーターをつかってしまうと、Symfonyコンテナにアクセスできるところから以外は参照できなくなってしまいます。 定数なら、例えばconstant() function*2を使うことでTwigテンプレートからもアクセスできます。
<p> Displaying the {{ constant('NUM_ITEMS', post) }} most recent results. </p>
Doctrine エンティティやリポジトリからであれば、コンテナ内のパラメーターにアクセスできなくても、定数なら簡単にアクセスできます。
namespace AppBundle\Repository; use Doctrine\ORM\EntityRepository; use AppBundle\Entity\Post; class PostRepository extends EntityRepository { public function findLatest($limit = Post::NUM_ITEMS) { // ... } }
こうした設定に定数を使う欠点を1つだけ挙げるとすれば、テストコードの中から気軽に値を変更できなくなってしまうことでしょう。
セマンティックコンフィグ:やってはいけない
- バンドルにセマンティックなDIを定義してはいけません。
How to Load Service Configuration inside a Bundle*3の記事で説明した通り、Symfonyのバンドルはservices.ymlから設定を読み込む方法と、専用の*Extensionクラスを定義するセマンティックコンフィギュレーションの2通りの方法があります。 セマンティックコンフィギュレーションは強力で、設定のバリデーションといった素敵な機能を有していますが、サードパーティ製のバンドルとして扱われることがないバンドルに対してそこまで労力をつぎ込む価値はないでしょう。 (2016/11/27 追記) 「セマンティックな」というところがわからなかったので、別にまとめました。 引き続き役に関するご意見や、私の理解が違う部分があるなら教えて下さい。
Symfonyの外に取扱を注意すべきオプションを移動する
データベースの認証情報など、取扱に注意すべきオプションを扱う場合、Symfonyプロジェクトの外に持ち、環境変数から取得できるようにすることをおすすめします。詳細はHow to Set external Parameters in the Service Container*4から確認できます。
感想
この辺は写経もしたほうが理解が深められそうなので、demoアプリで確認しよう。 設定をどこに持つか(DB/configファイル/定数)用途に応じて使い分けられるようになりたい。
(2016/10/31 更新)