PHPメンターズの後藤です。先日、日本Symfonyユーザー会のメーリングリストに次のような質問があり、回答した内容について記事にしておきます。補足の説明とともに、このような拡張を行えるポイントも紹介します。
質問内容は「Symfony2でerror_reportingの設定を変更したいが、そのような設定項目は?」というものです。
Symfonyにはさまざまな設定を行うためのコンフィギュレーションファイルがありますが、これは文字通り「バンドルのコンフィギュレーション」、つまり「バンドルが公開している拡張ポイントに対する設定」を目的としています。ですので、PHPに関するあらゆる設定がSymfonyの設定ファイルから行えるというのではなく、むしろ逆で、Symfonyで扱っているバンドルの関心事以外のことは、コンフィギュレーションファイルでは設定できません。
今回の質問にあるerror_reportingの設定であれば、Symfonyはフレームワークとして使いやすいデフォルト値を内部で設定していますが、そのデフォルト値をコンフィギュレーションファイルから変更するといったことはできません。
Symfonyでは、追加で必要な設定は開発者が自らコードを記述して行います。たとえばapp/AppKernel.phpは開発者の手にあるスクリプトなので、ここに設定用のメソッドやコードを追加することは自由に行えます。適切なタイミングで呼び出されるメソッドをオーバーライドし、希望の処理を追加すればよいでしょう。
今回の問題であれば、error_reportingはKernelのinit()メソッド内で設定されています。この部分を何らかの形で上書きできればよさそうです。
Symfony/Component/HttpKernel/Kernel.php
<php
// snip
abstract class Kernel implements KernelInterface
{
// snip
public function init()
{
if ($this->debug) {
ini_set('display_errors', 1);
error_reporting(-1);
DebugUniversalClassLoader::enable();
ErrorHandler::register();
if ('cli' !== php_sapi_name()) {
ExceptionHandler::register();
}
} else {
ini_set('display_errors', 0);
}
}
開発者が設定を差し込める部分
実際にどういったメソッドが、開発者がオーバーライドしてもよいものなのでしょうか。いくつか紹介します。
web/app.php web/app_dev.php
フロントコントローラスクリプトです。Symfony Standard Editionに付属するコードはフレームワークで処理を実行する最小限のものしか書かれていませんが、ここに独自のコードを追加することはできます。
app/AppKernel.php
アプリケーションカーネルクラスです。初期化が行われるメソッドをオーバーライドして設定を挿し込めばよいでしょう。
boot()メソッドはHttpKernel\KernelInterfaceに定義されており、ステーブルAPIです。
src/Acme/Bundle/DemoBundle/AcmeDemoBundle.php
バンドルクラスです。バンドルはすべて開発者の領域ですから当然バンドルクラスに開発者のコードを入れられます。
boot()メソッドはHttpKernel\Bundle\BundleInterfaceに定義されており、ステーブルAPIです。
Kernelのinit()メソッドはKernelのコンストラクタから呼び出されています。init()メソッド自体をAppKernel側でオーバーライドしてもよさそうですが、init()メソッドはステーブルAPIとして宣言されていません。他のメソッドでも代用可能な場合は、ステーブルAPIとして宣言されているものを使う方が望ましいでしょう。今回はKernelクラスのコンストラクタをAppKernel側でオーバーライドします。
app/AppKernel.php
<php
// snip
public function __construct($environment, $debug)
{
parent::__construct($environment, $debug);
if ($this->debug) {
error_reporting(E_ALL | E_STRICT);
} else {
error_reporting(E_PARSE | E_COMPILE_ERROR | E_ERROR | E_CORE_ERROR | E_USER_ERROR);
}
}
ごく稀にフレームワークのアップデート時にAppKernel.phpファイルやフロントコントローラファイルに修正が必要になる場合もありますが、万が一そのような場合はフレームワークのUPGRADEファイルに手順が記載されることになっています。AppKernel.phpやapp.phpは開発者の手にある領域なので、フレームワークのバージョンアップ時の修正などは、開発者の責任ということです。
まとめ
Symfonyでerror_reporting設定を変更する方法について解説しました。フレームワークは万能のツールキットではありません。特にSymfonyは、このような意図を明確に体現しています。フレームワークの責務と開発者自身が制御する領域を明確に認識することで、フレームワークの用意していない拡張が必要な場合の実装の糸口を見つけやすくなるでしょう。
参考