CakePHPでフォームのバリデーションを行う場合、例えばチェックボックスで「選択肢A」が選択されている場合のみ、「アンケート」のテキストエリアを必須入力にしたい!といった事があるかと思います。

バリデーションルールを切り替えるというのも1つの手段かと思いますが、もっと簡単に、バリデーションの定義だけでそれを実現できる関数を、ビヘイビアとして書いてみたので公開します。
CONTINUE READING

CakePHPで開発したアプリケーションを公開する際、たとえばバグの修正やデータベースのアップデートを行う場合など、サイトの全機能をいったん止めて、バックエンドで作業したいことがあるかと思います。

エントリポイントであるAPP/webroot/index.phpを差し替えるという強硬手段もあるかと思いますが、もっと手軽に実現するためのMaintenanceコンポーネントを作成してみたので公開します。
CONTINUE READING

CakePHPではデバッグレベルを0としている場合、あらゆるエラーが非表示になり、CakePHPのエラーをはじめPHPのWarningやFatalエラーも記録されなくなります。

例えば、その状態で致命的なエラーが発生しても、画面が真っ白になったり、ErrorHandler::error404メソッドが実行されるだけで、どこかで能動的に$this->logなどで記録していない限り、解決につながる情報が記録されません。

そんな時、下記ブログを参考にカスタムエラーハンドラや、PHPエラーを記録する条件を定義しておくだけで、手軽にログを取ることができるようになります。

この中の内容で、自分も利用させて頂いている2つめの方法が手軽でよいので、紹介させて頂きます。

/app/config/bootstrap.phpの中にphpエラーログを常に/app/tmp/log/php_error.logに出力するとか
例えば:
if ( Configure::read(‘debug’) == 0 ) {
error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
ini_set(‘display_errors’, 0); ini_set(‘log_errors’, 1);
ini_set(‘error_log’, LOGS . DS . ‘php_error.log’);
}

CakePHPでdebug=0の際にset_error_handler – benny毎日ラボ

下記のコードをAPP/config/bootstrap.phpに書いておくだけです。

if (Configure::read('debug') == 0) {
    error_reporting(E_ALL & ~E_NOTICE & ~E_DEPRECATED);
    ini_set('display_errors', 0);
    ini_set('log_errors', 1);
    ini_set('error_log', LOGS . DS . 'php_error.log');
}

これだけで、デバッグレベルが0の場合でも、APP/tmp/logs/php_error.logにエラー情報が記録されるようになります。

CakePHPを利用している上で、一番悩むのがファイルのアップロードとその管理です。

MediaPluginという有名なファイルアップロードプラグインがありますが、高機能・多機能との引き替えに、インストール方法やその利用方法が非常にわかりづらく、さらにプラグインをバージョンアップしただけでエラーを吐いて動かなくなったりと、常時メンテナンス、するプロジェクトに導入するには少々の抵抗があります。

そこで、もっとシンプルで使いやすいファイルアップロードプラグインである、FileBinderプラグインを紹介したいと思います。

CONTINUE READING

CakePHPではデバッグレベルが2の場合、レンダリングした画面の下部に発行したSQLのログを表示してくれます。

この機能は非常に便利ですが、本番環境などでデバッグレベルを0にしていると、発行したSQLを確認する手段がありません。

本番環境で何かしらデータベースエラーが発生した場合に、発行されているSQLを確認したいと思っても、そのままでは方法が無いのが現状です。

そこで、利用しているデータベースのドライバクラスを改良して、CakePHPのデバッグレベルに関わらず、発行したSQLをログファイルに保存できるように改造してみます。

ロギング用のデータベースドライバを作成

CakePHPのコアファイルに手を入れるのは避けたいので、データベースのドライバクラスを継承したログファイル保存用のドライバクラスを作成します。

ここではMySQLを利用する場合を想定します。
他のデータベースを利用している場合は、適宜利用しているデータベースのドライバクラスにを読み替えて下さい。

ファイルを作成

app/models/datasources/dbo_mysql_log.php を作成します。

dbo_mysqlを継承したコードを記述する

ここではDboMysqlを継承したDboMysqlLogという名前でクラスを作成します。

そして、SQLを発行するための関数であるexecute関数と、SQLのログ表示に関する処理を行うlogQuery関数をオーバーライトして、SQLをログに保存する設定であれば、実行したSQLをログファイルに保存できるように改良します。

App::import()関数を利用してスーパークラスを読み込んでおかないとエラーが出ますので注意して下さい。

データベースの接続設定を行う

app/configs/database.php ファイルの中で、利用するデータベースのドライバ指定を、先ほど作成したドライバに切り替えます。

public $development = array(
	'driver' => 'mysql_log',
	'persistent' => false,
	'host' => 'localhost',
	'login' => '********',
	'password' => '********',
	'database' => 'test',
	'prefix' => '',
	'encoding' => 'utf8'
);

driverの指定は、作成したドライバのファイル名から dbo_ と拡張子を除いたもので指定しましょう。

ログ保存用の設定を行う

config/bootstrap.php に下記のようなコードを記述します。

Configure::write('Sql.log', true);

これで、デバッグレベルに関係なく、発行されたSQLが tmp/logs/sql.log に出力されます。