ソースコードと翻訳が大好き

ソースコードと翻訳大好き人間のてらぽんが、技術系と翻訳系のネタを適当に公開していくブログです。

カテゴリ: PHP

■■ 2. core.php
次は core.php のほうです。
bootstrap.php よりも先に読み込まれます。
(bootstrap.php に戻るならこちら。)
(core.php の全訳ファイルはこちら。)

2-1) 冒頭
/**
 * これは、コアとなる設定ファイルです。
 *
 * Cake のコアとなる振る舞いを設定するのに使ってください。
 *
 * PHP 5
 *
 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
 * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
 *
 * Licensed under The MIT License
 * ファイルの再配布には上記の著作権表示が必須です。
 *
 * @copyright     Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
 * @link          http://cakephp.org CakePHP(tm) Project
 * @package       app.Config
 * @since         CakePHP(tm) v 0.2.9
 * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
 */


2-2) デバッグレベル
/**
 * CakePHP デバッグレベル:
 *
 * 本番モード:
 *     0: エラーメッセージ、警告を画面に出さない。メッセージのフラッシュで redirect する。
 *
 * 開発モード:
 *     1: エラー、警告が表示される。モデルキャッシュはリフレッシュされる。メッセージのフラッシュで一時停止する。
 *     2: 上記1に加え、デバッグメッセージとSQL出力を完全に行う。
 *
 * flash() を使う場合、
 * 本番モードではメッセージ表示して一定時間後にリダイレクトされますが、
 * 開発モードではメッセージ表示後にクリックして次に進むようになります。
 */
    Configure::write('debug', 2);
メッセージのフラッシュというのは、Controller の flash() メソッドの動作のことです。


2-3) エラーハンドラ
/**
 * あなたのアプリケーションでエラーをハンドルするのに使うエラーハンドラを設定してください。
 * デフォルトでは、ErrorHandler::handleError() が使われます。その場合、
 * debug > 0 なら、エラーは Debugger を使って出力されます。
 * debug = 0 なら、エラーは CakeLog を使ってログ出力されます。
 *
 * オプション:
 *
 * - `handler` - callback - エラーをハンドルするコールバック。呼び出し可能なタイプは何でも(無名関数でも)セットできる。
 * - `level`   - int      - 捕捉したいエラーのレベル。
 * - `trace`   - boolean  - ログファイルにエラーのスタックトレースを含めるか。
 *
 * @see ErrorHandler - エラーのハンドルや設定の詳細はこのクラスを参照してください。
 */
    Configure::write('Error', array(
        'handler' => 'ErrorHandler::handleError',
        'level'   => E_ALL & ~E_DEPRECATED,
        'trace'   => true
    ));
エラーが発生した場合のハンドラです。


2-4) 例外ハンドラ
/**
 * catch されなかった例外のための、例外ハンドラを設定してください。
 * デフォルトでは、ErrorHandler::handleException() が使われます。その場合、その例外用の HTML ページが表示され、
 * debug > 0 なら、Missing Controller のようなフレームワークのエラーが表示されます。
 * debug = 0 なら、フレームワークのエラーは強制的に汎用的な HTTP エラーとして表示されます。
 *
 * オプション:
 *
 * - `handler`  - callback - エラーをハンドルするコールバック。呼び出し可能なタイプは何でも(無名関数でも)セットできる。
 * - `renderer` - string   - catch されなかった例外を描画(render)する担当のクラス。
 *      独自のクラスを指定するなら、そのクラスのファイルを app/Lib/Error の下に置くこと。
 *      このクラスは render メソッドを実装していなければなりません。
 * - `log`      - boolean  - 例外をログに出力するか。
 *
 * @see ErrorHandler - 例外のハンドルや設定の詳細はこのクラスを参照してください。
 */
    Configure::write('Exception', array(
        'handler'  => 'ErrorHandler::handleException',
        'renderer' => 'ExceptionRenderer',
        'log'      => true
    ));
例外が発生した場合のハンドラです。


2-5) charset エンコーディング
/**
 * アプリケーション全体の charset エンコーディング。
 */
    Configure::write('App.encoding', 'UTF-8');
非常に重要です。全体的なエンコーディングの指定です。


2-6) mod_rewrite使わない場合の設定
/**
 * CakePHP が mod_rewrite を【使わずに】、CakePHP 的な URL を使いたいのであれば、下記の .htaccess を削除し、
 *
 * /.htaccess
 * /app/.htaccess
 * /app/webroot/.htaccess
 *
 * 下記の、App.baseUrl についてのコメントアウトを解除してください。
 */
    //Configure::write('App.baseUrl', env('SCRIPT_NAME'));
mod_rewrite を使わない/使えない場合の設定です。
使わないようにすると、生成される URL が /inde.php/コントローラ名/アクション名 のようになります。
mod_rewrite は使えるなら使ったほうがいいでしょう。


2-7) 接頭辞ルート(Prefix routes)
/**
 * CakePHP の接頭辞ルート機能を使うなら、以下の定義のコメントアウトを解除してください。
 *
 * ここで定義した値により、ルートの名前が決まり、関連するコントローラのアクションが決まります。
 *
 * あなたのアプリケーションで使う接頭辞を配列で指定してください。admin や、その他、接頭辞が必要なルート用に使ってください。
 *
 *     Routing.prefixes = array('admin', 'manager');
 *
 * 上記のように設定した場合、下記のような URL になります。
 *    `admin_index()`   なら `/admin/controller名/index`
 *    `manager_index()` なら `/manager/controller名/index`
 *
 */
    //Configure::write('Routing.prefixes', array('admin'));
ほとんどのControllerには、管理用の特別なアクションも必要になりうるという観点から、
管理者用のURLが生成しやすくなっています。
UsersContoroller に admin_index() と index() の両方を実装した場合、
通常ならそれぞれ、/users/admin と /users/ でアクセスすることになりますが、
Configure::write('Routing.prefixes', array('admin'));
とするとそれぞれ、/admin/users/ と /users/ でアクセスできるようになります。


2-8) の設定
/**
 * アプリケーション全体でキャッシュ機能をオフにしたいなら、コメントアウトを解除してください。
 */
    //Configure::write('Cache.disable', true);


2-9) キャッシュ・チェック
/**
 * キャッシュ・チェック機能を有効にする。
 *
 * true にセットした場合、ビューのキャッシュを使うためには、
 * あなたのコントローラ内にある public $cacheAction
 * (キャッシュの設定を定義するもの)も使わなければなりません。
 * あるコントローラ全体で有効にするためにコントローラの public $cacheAction = true を設定してもよいですし、
 * 個々のアクションで $this->cacheAction = true と設定してもかまいません。
 */
    //Configure::write('Cache.check', true);
キャッシュ・チェックを使うと、View をキャッシュすることができます。
Controller や Model など一切通らずに View を返せるので高速です。
コメントにはありませんが、$casheAction には true だけなく、かなりきめ細やかな設定が可能です。


2-10) ログ出力のエラータイプ
/**
 * log() 関数を使う場合の、デフォルトのエラータイプを定義してください。
 * ログ出力と、デバッグの判別に使われます。今のところ PHP は LOG_DEBUG をサポートしています。
 */
    define('LOG_ERROR', LOG_ERR);


2-11) セッション
/**
 * セッションの設定。
 *
 * セッションの設定に使用する配列の設定値を定義してください。
 * Session.defaults のキーは、セッションを使う際の、デフォルトのプリセット(初期設定群)を選ぶのに使い、
 * なんらかの設定を宣言した際には、このデフォルト値を上書くことになります。
 *
 * ## オプション
 *
 * - `Session.cookie`        - 使用する Cookie の名前。デフォルトは 'CAKEPHP'
 * - `Session.timeout`       - セッションの生存期間(分)。このタイムアウトは CakePHP によってハンドルされる。
 * - `Session.cookieTimeout` - セッション Cookie の生存期間(分)。
 * - `Session.checkAgent`    - セッション開始時に user agent をチェックするか。
 *              昔のIEや、Chromeのフレーム、Webブラウザを持つ装置とAJAX などを扱う必要がある場合に、
 *              false に設定したいということがありえる。
 * - `Session.defaults`      - あなたのセッションのベースとして使うデフォルトの設定。
 *              4つの組み込み値が存在する。: php, cake, cache, database.
 * - `Session.handler`       - カスタムのセッションハンドラを有効にするために使うことができる。
 *              呼び出し可能なものを配列で指定し、それは `session_save_handler` とともに使われる。
 *              このオプションを使うと、自動的に `session.save_handler` が ini 配列に追加される。
 * - `Session.autoRegenerate` - この設定を有効にすると、セッションの自動更新がONになり、
 *              セッションIDが頻繁に変更されることになる。CakeSession::$requestCountdown 参照。
 * - `Session.ini`           - 追加でセットしたい ini 値の連想配列。
 *
 * Session.defaults の組み込みの値:
 *
 * - 'php'      - あなたの php.ini で定義されている設定値を使う。
 * - 'cake'     - CakePHP の /tmp ディレクトリにセッションファイルを保存する。
 * - 'database' - CakePHP のデータベースセッションを使う。
 * - 'cache'    - セッションの保存に Cache クラスを使う。
 *
 * カスタムのセッションハンドラを定義する場合は、その定義ファイルを /app/Model/Datasource/Session/<name>.php に保存してください。
 * 必ず `CakeSessionHandlerInterface` をそのクラスに実装し、Session.handler に <name> をセットしてください。
 *
 * データベースセッションを使うためには、cake のシェルコマンド【cake schema create Sessions】を使って、
 * app/Config/Schema/sessions.php スキーマを走らせてください。
 *
 */
    Configure::write('Session', array(
        'defaults' => 'php'
    ));
Session.checkAgent というのは、同一セッションなのに、途中で UserAgent が変わったら、強制的にセッションをクリアする機能です。


2-12) セキュリティ関連
/**
 * CakePHP のセキュリティのレベル。
 */
    Configure::write('Security.level', 'medium');

/**
 * セキュリティのハッシュ生成に用いられるランダム文字列。
 */
    Configure::write('Security.salt', 'DYhG93b0qyJfIxfs2guVoUubWwvniR2G0FgaC9mi');

/**
 * 文字列を encrypt/decrypt する際に使う、ランダムな数値(数値のみ)の文字列。
 */
    Configure::write('Security.cipherSeed', '76859309657453542496749683645');


2-13) Assetファイル関連
/**
 * static な資産ファイル(js, css, images)に対して、最終更新日時のタイムスタンプを使うようにします。
 * こうすることで、querystring パラメータにファイルの更新日時が追加されることになります。
 * これはブラウザのキャッシュを無効にするのに便利な方法です。
 *
 * debug > 0 の場合にタイムスタンプを適用するなら true を指定してください。
 * debug に関係なく常にタイムスタンプを適用するなら、'force' を指定してください。
 */
    //Configure::write('Asset.timestamp', true);

/**
 * CSS の出力で、コメント、空白、連続するタブなどを撤去することで圧縮します。
 * これは a/var/cache ディレクトリが Web サーバからキャッシュ用に書き込むことが可能であることと、
 * /vendors/csspp/csspp.php が必要です。
 *
 * 使用の際には、CSS へリンクする URL の頭に '/css/' ではなく '/ccss/' を付けるか、HtmlHelper::css() を使ってください。
 */
    //Configure::write('Asset.filter.css', 'css.php');

/**
 * 独自の JavaScript 圧縮ロジック(出力をハンドルするために webroot にスクリプトを配置するロジック)をプラグインとしてセットします。
 * 下記のようにこのスクリプトの名前を指定してください。
 *
 * 使用の際には、JavaScript へリンクする URL の頭に '/js/' ではなく '/cjs/' を付けるか、JavaScriptHelper::link() を使ってください。
 */
    //Configure::write('Asset.filter.js', 'custom_javascript_output_filter.php');



2-14) ACL
/**
 * CakePHP の ACL (アクセス・コントロール・リスト) 機能で使う、クラス名とデータベース。
 */
    Configure::write('Acl.classname', 'DbAcl');
    Configure::write('Acl.database', 'default');


2-15) タイムゾーン
/**
 * この行のコメントアウトを解除し、あなたのサーバのタイムゾーンに修正してください。
 * エラーに関連する日時が正しくなります。
 */
    //date_default_timezone_set('UTC');


2-16) キャッシュ
/**
 * 使用するキャッシュエンジンを指定します。APC が有効なら、それを使ってください。
 * CLI を介して実行しているなら、APC はデフォルトでは無効です。
 * それがこの場合で利用可能であり、有効になっているのか確認してください。
 *
 * 注: 'default' および、そのほかのアプリケーションキャッシュは app/Config/bootstrap.php の中で設定されていなければなりません。
 *      利用可能なキャッシュエンジンについては boostrap.php 内のコメントと、その設定値をチェックしてください。
 */
$engine = 'File';
if (extension_loaded('apc') && function_exists('apc_dec') && (php_sapi_name() !== 'cli' || ini_get('apc.enable_cli'))) {
    $engine = 'Apc';
}

// 開発モードなら、キャッシュはすぐに期限切れとなります。
// In development mode, caches should expire quickly.
$duration = '+999 days';
if (Configure::read('debug') >= 1) {
    $duration = '+10 seconds';
}

// Memcache と APC とで衝突しないように、同じサーバで動く各アプリケーションに異なる接頭辞を付けます。
// Prefix each application on the same server with a different string, to avoid Memcache and APC conflicts.
$prefix = 'myapp_';

/**
 * 一般的なフレームワークのキャッシュ用に使われるキャッシュの設定です。
 * path 情報、オブジェクト・リスティング、翻訳キャッシュファイルはこの設定を使って保存されます。
 */
Cache::config('_cake_core_', array(
    'engine'    => $engine,
    'prefix'    => $prefix . 'cake_core_',
    'path'      => CACHE . 'persistent' . DS,
    'serialize' => ($engine === 'File'),
    'duration'  => $duration
));

/**
 * モデルとデータベースのキャッシュの設定です。
 * このキャッシュ設定はコネクション内のスキーマ記述とテーブル・リスティングを保存するのに使います。
 */
Cache::config('_cake_model_', array(
    'engine'    => $engine,
    'prefix'    => $prefix . 'cake_model_',
    'path'      => CACHE . 'models' . DS,
    'serialize' => ($engine === 'File'),
    'duration'  => $duration
));

以上!

CakePHP の bootstrap.phpcore.php 全訳 しました!!

PHP Advent Calendar 2012 の3日目です。

CakePHP の bootstrap.php と core.php の中って、ドキュメントばりに一杯コメント書いてあるんですが、全部英語なので、素敵な仕様も埋もれちゃってるかなあなんて思い、ここは全訳して、一つ一つ見ていこうかと思います!
(bootstrap.php の日本語バージョンはこちら。)
(core.php の日本語バージョンはこちら。)


■■ 1. bootstrap.php


■1-1) 冒頭
/**
* このファイルは app/webroot/index.php から自動的に読み込まれ、core.php の後に
* 読み込まれます。
*
* このファイルはアプリケーション全体の設定を作成する/読み込むのに使ってください。
* 例: キャッシュ、ログ、別の設定ファイルの読み込みなど。
*
* また、あなたのアプリケーションで使う、グローバルな関数/定数の定義ファイルを
* include するのにもこのファイルを使ってください。
*
* PHP 5
*
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* ファイルの再配布には上記の著作権表示が必須です。
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @package app.Config
* @since CakePHP(tm) v 0.10.8.2117
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
ここは特にそのままなので、次いきまーす。


■1-2) キャッシュエンジンの設定
/**
* キャッシュエンジンの設定。
* デフォルトの設定は以下のとおり。
*
* ファイル・ストレージ・エンジン。
*
* Cache::config('default', array(
* 'engine' => 'File', //[必須]
* 'duration' => 3600, //[省略可]
* 'probability' => 100, //[省略可]
* 'path' => CACHE, //[省略可] システムの tmp ディレクトリを使う。注:絶対パスであること。
* 'prefix' => 'cake_', //[省略可] prefix every cache file with this string
* 'lock' => false, //[省略可] ファイル・ロックを使う。
* 'serialize' => true, //[省略可]
* 'mask' => 0666, //[省略可] キャッシュ・ファイルを生成した際に使うパーミッション・マスク
* ));
*
* APC (http://pecl.php.net/package/APC)
*
* Cache::config('default', array(
* 'engine' => 'Apc', //[必須]
* 'duration' => 3600, //[省略可]
* 'probability' => 100, //[省略可]
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[省略可] この文字列を各キャッシュファイルの接頭辞として使う。
* ));
*
* Xcache (http://xcache.lighttpd.net/)
*
* Cache::config('default', array(
* 'engine' => 'Xcache', //[必須]
* 'duration' => 3600, //[省略可]
* 'probability' => 100, //[省略可]
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[省略可] この文字列を各キャッシュファイルの接頭辞として使う。
* 'user' => 'user', //xcache.admin.user の設定値から user を取得する。
* 'password' => 'password', //平文のパスワード (xcache.admin.pass)
* ));
*
* Memcache (http://memcached.org/)
*
* Cache::config('default', array(
* 'engine' => 'Memcache', //[必須]
* 'duration' => 3600, //[省略可]
* 'probability' => 100, //[省略可]
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[省略可] この文字列を各キャッシュファイルの接頭辞として使う。
* 'servers' => array( //[省略可]
* '127.0.0.1:11211' // localhost, デフォルトのポートは 11211
* ),
* 'persistent' => true, // [省略可] 非持続接続(non-persistent connections)にしたいなら false に設定する。
* 'compress' => false, // [省略可] Memcache のデータを圧縮する(遅くなるがメモリを節約できる)
* ));
*
* Wincache (http://php.net/wincache)
*
* Cache::config('default', array(
* 'engine' => 'Wincache', //[必須]
* 'duration' => 3600, //[省略可]
* 'probability' => 100, //[省略可]
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[省略可] この文字列を各キャッシュファイルの接頭辞として使う。
* ));
*
* Redis (http://http://redis.io/)
*
* Cache::config('default', array(
* 'engine' => 'Redis', //[必須]
* 'duration' => 3600, //[省略可]
* 'probability' => 100, //[省略可]
* 'prefix' => Inflector::slug(APP_DIR) . '_', //[省略可] prefix every cache file with this string
* 'server' => '127.0.0.1', // localhost
* 'port' => 6379, // デフォルトのポートは 6379
* 'timeout' => 0, // タイムアウトの秒数。0 は無制限。
* 'persistent' => true, // [省略可] 非持続接続(non-persistent connections)にしたいなら false に設定する。
* ));
*/
Cache::config('default', array('engine' => 'File'));

ここでは、使いたいキャッシュエンジンを選んで、指定します。


■1-3) App::buildの設定
/**
 * 下記の設定で、モデル、ビュー、コントローラのパスを追加することができます。
 *
 * App::build(array(
 *     'Model'                     => array('/path/to/models', '/next/path/to/models'),
 *     'Model/Behavior'            => array('/path/to/behaviors', '/next/path/to/behaviors'),
 *     'Model/Datasource'          => array('/path/to/datasources', '/next/path/to/datasources'),
 *     'Model/Datasource/Database' => array('/path/to/databases', '/next/path/to/database'),
 *     'Model/Datasource/Session'  => array('/path/to/sessions', '/next/path/to/sessions'),
 *     'Controller'                => array('/path/to/controllers', '/next/path/to/controllers'),
 *     'Controller/Component'      => array('/path/to/components', '/next/path/to/components'),
 *     'Controller/Component/Auth' => array('/path/to/auths', '/next/path/to/auths'),
 *     'Controller/Component/Acl'  => array('/path/to/acls', '/next/path/to/acls'),
 *     'View'                      => array('/path/to/views', '/next/path/to/views'),
 *     'View/Helper'               => array('/path/to/helpers', '/next/path/to/helpers'),
 *     'Console'                   => array('/path/to/consoles', '/next/path/to/consoles'),
 *     'Console/Command'           => array('/path/to/commands', '/next/path/to/commands'),
 *     'Console/Command/Task'      => array('/path/to/tasks', '/next/path/to/tasks'),
 *     'Lib'                       => array('/path/to/libs', '/next/path/to/libs'),
 *     'Locale'                    => array('/path/to/locales', '/next/path/to/locales'),
 *     'Vendor'                    => array('/path/to/vendors', '/next/path/to/vendors'),
 *     'Plugin'                    => array('/path/to/plugins', '/next/path/to/plugins'),
 * ));
 *
 */
CakePHP 関連のディレクトリの Path を通す感じです。
たとえば、下記のようにすると、デフォルトの /app/Model に加え、/app/WebAPI からもモデルを探しにいくようになります。
App::build(array(
    'Model' => array(ROOT.DS.'app'.DS.'WebAPI'),
), App::PREPEND);
なお App::PREPEND の代わりに、App::APPEND を指定すると、デフォルトよりも優先して(先に)探しにいきます。
ROOT や DS の定数は index.php で定義されているものです。


■1-4) Inflector ルール
/**
 * 独自の Inflector ルール。
 * テーブル名や、モデル名、コントローラ名、単複形変換関数に渡されるすべての文字列を正しく単数形や複数形に変換するための設定。
 *
 * Inflector::rules('singular', array('rules' => array(), 'irregular' => array(), 'uninflected' => array()));
 * Inflector::rules('plural', array('rules' => array(), 'irregular' => array(), 'uninflected' => array()));
 *
 * ※ singular : 単数形  /  plural : 複数形
 * ※ rules : 語尾変化ルール  /  irregular : 不規則変化 / uninflected : 語尾変化しない
 *
 */
テーブル名やコントローラ名は複数形でモデル名は単数形ですが、これらを相互に変換するためのロジックを定義します。(デフォルトならもちろん不要です。)

rules では、正規表現を使って一般的な語形変化ロジックを指定します。
例) rules => array('/$/' => 's')

irregular は、変換のテーブルを連想配列で渡します。
uninflected は変換しない単語を配列で渡します。

ちなみに、日本人にとっては複数形をなぜわざわざ使うのか判りづらいかもしれませんね。
たとえばなぜ Controller を複数形にしたいかというと、/items/ というURLで item のリストを出したいし、
/items/12 という URL で items の中の id=12 の item の詳細を出したい、
という感覚によるものですが、なんとなく判りますでしょうか?

ちなみに下記のようにすると、単数形・複数形の変換を完全にOFFにすることができます。
全部単数形でOKになります。
//全ての単語をそのまま使う(語形変化しない)。
Inflector::rules('plural', array('rules' => array('/^(.*)$/' => '\1')));


■1-5) プラグイン読み込み
/**
 * プラグインは手動で読み込む必要があります。1つ1つロードすることも、1回の呼び出しで全部を読み込むこともできます。
 * 必要に応じて、以下のどちらかのコメントアウトを解除してください。
 * より高度なプラグインの読み込み方法については、CakePlugin のドキュメントを確認してください。
 *
 * CakePlugin::loadAll(); // 一度にすべてのプラグインを読み込む。
 * CakePlugin::load('DebugKit'); //DebugKit という名前のプラグイン1個を読み込む。
 *
 */
ここでプラグインを読み込みます。
loadAll ではプラグインのディレクトリにあるすべてのプラグインが読み込まれます。


■1-6) Dispatcher 設定
/**
 * イベント・リスナーをリクエストのライフサイクルに組み込むことが可能です。CakePHPはデフォルトで2つのフィルターを組み込むます。
 *
 * - AssetDispatcher フィルターは、あなたのテーマとプラグインから資産ファイル(css, images, js 等)を供給します。
 * - CacheDispatcher フィルターは、Cache.check の configure の値を読み、コントローラにより作成済みのキャッシュされたコンテンツを供給しようと試みます。
 *
 * あなたのアプリケーションに合わせて、好きなように追加/削除してください。
 * 使用例:
 *
 * Configure::write('Dispatcher.filters', array(
 *        'MyCacheFilter', //  あなたの app 内の、Routing/Filter パッケージから MyCacheFilter クラスを使います。
 *        'MyPlugin.MyFilter', // MyPlugin プラグイン内の、 Routing/Filter パッケージから MyFilter クラスを使います。
 *        array('callable' => $aFunction, 'on' => 'before', 'priority' => 9), // beforeDispatch で呼び出される、PHP コールバック形式での有効な記述
 *        array('callable' => $anotherMethod, 'on' => 'after'), // afterDispatch で呼び出される、PHP コールバック形式での有効な記述
 * ));
 */
Configure::write('Dispatcher.filters', array(
    'AssetDispatcher',
    'CacheDispatcher'
));
リクエストの前後に処理を加えることができます。


■1-7) ログ出力の設定
/**
 * デフォルトで使われる、ファイルにログを出力する際のオプション。
 */
App::uses('CakeLog', 'Log');
CakeLog::config('debug', array(
    'engine' => 'FileLog',
    'types' => array('notice', 'info', 'debug'),
    'file' => 'debug',
));
CakeLog::config('error', array(
    'engine' => 'FileLog',
    'types' => array('warning', 'error', 'critical', 'alert', 'emergency'),
    'file' => 'error',
));
ログ出力の設定です。


core.php 編へつづく。


PHPには次の2種類の例外系が存在しますね。
  1. RuntimeException
  2. LogicException
これはどのように使い分けるべきなのかについて
PHPのドキュメント(http://www.php.net/manual/)をベースに調べてみたので共有します。


まずは結論!
  1. RuntimeException系 : 運用で通常発生しうる例外
    発生してもバグとは限らない。通常の例外。
    例) throw new RangeException("規定範囲外の値が入力されました");
  2. LogicException系 : バグ検出のために仕込む例外。
    本来、実運用時には発生しない。発生したらバグ。
    例) throw new LogicException("引数で数値以外を渡さないでください!!");

java にも同名の例外がありますが、java の使い分け方とは全く異なるので java 使いには要注意です。


根拠は次の通り。

(1) php の例外の構成

(インデントは継承関係を表す)
Exception

    RuntimeException                : 実行時にだけ発生するエラー。
        OutOfBoundsException        : キーが範囲外。
        UnexpectedValueException    : 値が期待値外。
        RangeException              : 範囲エラー。
        OverflowException           : オーバーフロー。
        UnderflowException          : アンダーフロー。

        HttpException               : CakePHP で導入される例外。http関連。
            BadRequestException
            InternalErrorException
            など
        CakeException               : CakePHP で導入される例外。CakePHP関連。
            MissingControllerException
            MissingActionException
            など

 LogicException : プログラムのロジックエラー。バグ検出用。 BadFunctionCallException : 関数が未定義。引数なし。 BadMethodCallException : メソッドが未定義。 DomainException : 値が範囲外。 InvalidArgumentException : 引数が不正。 LengthException : 長さが異常。 OutOfRangeException : 値の異常。
php には LogicException と RuntimeException の2体系があります。
まずは RuntimeException を見てみます。


(2) RuntimeException の2つの謎
RuntimeException

実行時にだけ発生するようなエラーの際にスローされます。 Exception thrown if an error which can only be found on runtime occurs.
ここで疑問が2つ。

1つ目は、「実行時にだけ 発生するようなエラー」 とあるが、例外ってそもそも実行時にしか発生しないような。。。php では実行時以外でも発生するのだろうか。。。

2つ目は、Runtime の辞書的な意味は大きく2つ(「実行時」「ライブラリ」が)あるが、「実行時」で間違いないのか?

両者を検証すべく、他の例外のドキュメントをすべて確認してみると、驚くべき記述が見つかりました。


(3) 謎のワード 「コンパイル時」
OutOfBoundsException

値が有効なキーでなかった場合にスローされる例外です。
これは、コンパイル時には検出できないエラーです。

Exception thrown if a value is not a valid key.
This represents errors that cannot be detected at compile time.  
コンパイル時には検出できない!!!??
ということは、コンパイル時に検出できるエラーがありえるのか???
コンパイル時に検出できないから、そもそも例外を使うのではないのか。
なぜ、わざわざこの例外だけ、この記述がなされているのか。

謎が深まりましたが、とりあえず、他のドキュメントも確認してみます。
すると理解のカギとなりうる記述を発見しました。


(4) カギとなるワード 「実行時版」
RangeException

プログラムの実行時に範囲エラーが発生したことを示すときにスローされる例外です。
通常は、アンダーフローやオーバーフロー以外の計算エラーが発生したことを意味します。
これは、実行時版の DomainException です。

Exception thrown to indicate range errors during program execution.
Normally this means there was an arithmetic error other than under/overflow.
This is the runtime version of DomainException.
「実行時版」 という言葉が使われています。
ということは、「実行時版」 ではない DomainException と対比すれば何かわかるかも!
DomainException

定義したデータドメインに値が従わないときにスローされる例外です。

Exception thrown if a value does not adhere to a defined valid data domain.
ドキュメント自体は参考になりませんが、親クラスがRuntimeExceptionではなく、
LogicException であることがカギとなりそうです!


(5) LogicException の存在を知ることが理解のカギ
LogicException

プログラムのロジック内でのエラーを表す例外です。
この類の例外が出た場合は、自分が書いたコードを修正すべきです。

Exception that represents error in the program logic.
This kind of exceptions should directly lead to a fix in your code.
「自分が書いたコードを修正すべき」 !!
つまり、これが発生したら明らかにバグであるということ。
ということは、php の 「例外」 界では、

実行時 = RuntimeException系以外の例外は発生しないはず

という意味で使われているようです。
Runtime の辞書的な意味では 「実行時」 ですね。

つまり、まとめると、こういうことです。


(6) まとめ
  1. RuntimeException系 : 運用で通常発生しうる例外
    発生してもバグとは限らない。通常の例外。
  2. LogicException系 : バグ検出のために仕込む例外。
    本来、実運用時には発生しない。発生したらバグ。

(7) しかし、2点ほど謎が残りました。
  1. OutOfRangeException ではなぜ 「コンパイル時には検出できない」 とあえて明言したのでしょうか。
  2. 「実行時」 を表す原文に 「on runtime」 と紛らわしい表現をなぜ使ったのでしょうか。「at runtime」 のほうが一般的だし、まぎれも少ないのに。


(8) java 使いは要注意

ちなみに、java の例外にも RuntimeException、Exception という2系統がありますが、
catch 必須かどうかという次元の異なる理念が入っているため、
同じ名前でも区分けが全く異なります。java 使いには要注意ですね。
  1. RuntimeException系 : バグ検出のために仕込んだもの + 発生したら正常処理ができえないもの。
  2. Exception系 : 発生したら、呼び出し元で相応の処理を求めるもの。
java + PHP の人にしてみると、バグ検出のために使うのが RuntimeException かどうかで壮絶な混乱が予想されます。

↑このページのトップヘ