Memcachedをインストールしたうえで、cakePHPのcore.php設定ファイルにあるcache設定をengine => ‘File’ から engine=>’Memcache’に変更すると以下のエラーメッセージが表示されてしまう。
Warning (512): Cache not configured properly. Please check Cache::config(); in APP/config/core.php
デバッグして原因を調査したところ、php.ini に
extension=memcache.so
の設定がないためにMemcacheクラスが呼べなかったためだった。
エラーメッセージが適切?ではないために小一時間はまってしまった。
なお、memcache.soはphp-pecl-memcacheパッケージをインストールする必要がある。
pageTitleが利用できない
新しいアプリケーション「oh-toilet.com」をcakePHP+Ktai Libraryで作成していたら、なぜかタイトルが編集できない。
いつも通り
$this->pageTitle = ‘タイトル’;
にしているのに。。。。
原因を探してみると、Ver.1.3から廃止になっているじゃないですか。。。
View::$pageTitleは削除されました。代わりに$this->set(‘title_for_layout’, $var);を使用してください。
セキュリティ要件でない限りは、マイナバージョンアップ時に下位互換性をなくすのはやめてほしいと思うのは僕だけでしょうか?
下位互換性がなくなるということは、cakePHPのバージョンアップをするときには、前ページの動作確認をしなければならないことを意味しています。(もちろんドキュメントに書いてあることがすべてならばキーワードだけで探して対象を絞り込むだけでよいのかもしれませんが。。。)
携帯サイトをキャッシュする
財テク.jpのモバイルサイトは、CakePHPにKtai Libraryを使って動かしているのだが、Viewキャッシュをしてしまうと、キャリアごとの絵文字に対応できないことと、PCサイトがUTF-8だった場合に、headerでのcharset指定がUTF-8となってしまうため、キャッシュされたページは文字化けしてしまう可能性がある。
前者については絵文字を利用しない方法で対応可能だが、後者についてはキャッシュ済みの場合には、controllerすら通らず、エンコード指定を切り換える対応方法が分からなかったため、しばらくキャッシュさせないようにしていたが、データが多くなってくるとレスポンスが悪くなってきているため、キャッシュの方法を考えてみた。
Viewキャッシュが無理な場合には、modelキャッシュということで、CakePHP1.2 Behaviorでモデルのメソッドキャッシュを行うを使って、modelでキャッシュさせることにした。
結果的には、携帯サイトはmodelキャッシュ、PCサイトはmodelキャッシュ+ビューキャッシュとなりキャッシュによる効果は高くなったように思う。
logrotate
ログを出力するプログラムはたくさんあるが、1ファイルに書き出し続けると不要な過去のログを保持し続けて容量不足になってしまったりすることがある。
logrotateを使えば、出力側のプログラムを変更することなく、きめられたタイミングで現在のファイルをリネームしたうえで、新しいログファイルを作成してくれる。
Fedora Coreであれば、
/etc/logrotate.d/ の下にファイルを作成して、
/var/www/XXX/logs/*log {
daily
missingok
}
とすれば、cakePHPで出力されるdebug_logとerror_logを1日単位でローテートしてくれる。
create (パーミッション) (ユーザー名) (グループ名)のオプションを付ければ、空のファイルを作成してくれるし、apacheプロセスのようにログ出力プログラムがログファイルが無くなってしまうとそれ以降ログを書き出さないような仕組みなのであれば、postrotateオプションをつかってプロセスを再起動させることもできる。
詳しいオプションは@ITが参考になる。
ShellとControllerで処理を共有する
cakePHPでCronなどでタスク処理をしたい場合やコマンドライン実行をしたい場合にロジック部分を提供するShellクラスとWebアプリケーションのロジック部分を提供するController。いずれも同じロジック部分だけに、共有したいことが多い。
しかしながら、いずれもクラスはObjectから継承されたものであり、Objectクラスにゴリゴリ書かない限りは共有できないが、バージョンアップ時のメンテナンス負荷が高くなってしまう。
そしたら多重継承だ!という考えもPHPでは残念ながらできず、代わりにPHPにはinterfaceという仕組みが用意されているが、残念ながらcakePHPで使う方法がよくわからなかった(おそらくrequireするとか強引な手法であればできるはず)。
実はcakePHPにはコンポーネントという方法で対応することができる。しかし、このコンポーネントも癖があって、通常なら、
var $components = array(‘コンポート名‘);
とすれば
$this->コンポート名
で使えるようになるのだが、Shell側はそうはいかない。
App::import(‘Component’, ‘コンポート名‘);
と定義したうえで、
function startup(){
$this->コンポート名 = new コンポート名Component();
}
を定義しなければ、Controllerと同等には使えない。
ただ標準で用意されているEmailコンポーネントなどは、上記手法を使う必要がなく、$components変数に突っ込めば使えるようになっている。もう少し調べてみる必要がありそうだ。
Prefix利用時のPaginatorHelperが吐くURLが正しく表示されない
財テク.jp 価格比較サイトのモバイルサイトをPrefixを使って実現しようとしたのだが、Prefix利用時のPaginatorHelperが吐くURLが正しく表示されないにて指摘されているようにURLが正しく設定されない。そのため、このスレ主が情報提供していただいていると思われるブログを元に同様にURL置換を行うことで対応した。
ビューで置換するのは根本的な対応とは言えないが、逆にビューで置換するので、routes.phpで変更を加えるより、影響が(想定)限定されるともいえる。
今回もKtai Libraryを使って非常に簡単に作成することができた。バージョンが0.2.0になっており、cakeHPでモバイルサイトを作るならKtai Libraryとなりつつあり、今後もますます注目度が高いライブラリである。
サブディレクトリにcakePHPを構築する
もしサブドメインに構築する場合には、.htaccessの設定に追記が必要となる。
具体的には、RewriteBaseをきちんと設定にあるような
app/webroot/.htaccess にあるmod_rewriteの設定において
RewriteBase /(サブディレクトリ名)
を追加する必要がある。
もし、追加し忘れると、500 Internal Server Errorが表示され、Apacheのログには、
Request exceeded the limit of 10 internal redirects due to probable configuration error. Use ‘LimitInternalRecursion’ to increase the limit if necessary. Use ‘LogLevel debug’ to get a backtrace.
というメッセージが記録される。
今までDocumentRoot上にしか構築したことがなかったので、少しハマってしまった。
ビューをキャッシュする
cakePHP 1.2のキャッシュ機能を使ってみた。
データベースに問い合わせするシステムにおいて、頻繁にデータが変わらないような場合にはキャッシュを利用すると応答時間が改善するだけでなく、データベースへの問い合わせをしなくて済むようになるので、DBサーバーの負荷が軽減される。
キャッシュ機能を有効にするには、いくつか設定が必要なようで、Viewをキャッシュする場合に設定をした部分は次の通り。
core.phpの
Configure::write(‘Cache.check’, true);
を有効にした。
Viewのキャッシュを有効にしたいControllerにおいて
var $helpers = array(‘Cache’);
var $cacheAction = 28800; //8H
とした。通常、$helpers には他にもHTMLなどを指定する必要があるだろう。
[cakephp]1.2でviewをchacheするにはで詳しく説明されている。
キャッシュには、Fileキャッシュのほか、APC、XCace、Memcacheが利用できるが、FileキャッシュとAPCキャッシュの違いがよくわからなかった。
ちなみにベンチマークの結果は次の通り。
ab http://price.zaiteku.jp/products/detail/B002ANRN1E
キャッシュ前 Requests per second: 2.28 [#/sec] (mean)
キャッシュ後 Requests per second: 12.03 [#/sec] (mean)
約5.3倍速くなったことが分かる。
CakePHPのAjaxな問い合わせフォーム用プラグイン
YARE TOKOにて公開されており、非常に有用なプラグインです。
財テク.jp(掲載内容に関するお問い合わせのリンク)でも使用させていただきました。
ところで、contact_forms_controller.phpの51、52行目においてfromメソッドとtoメソッドにセットされるべき値が異なっているように思えました。
誤っていると思われるコード
$this->Qdmail->to($this->data[‘Form’][‘mail’], $this->data[‘Form’][‘name’] . ‘様’);
$this->Qdmail->from($this->admin_mail, $this->admin_mail);
正しいと思われるコード
$this->Qdmail->from($this->data[‘Form’][‘mail’], $this->data[‘Form’][‘name’] . ‘様’);
$this->Qdmail->to($this->admin_mail, $this->admin_mail);
なぜか一部のフィールドがsave()で保存できない!
debugレベルを0にしてリリースしているサイトで機能拡張のためにカラムを追加したが、なぜかsaveメソッドを呼び出しているところで追加したカラムが追加並びに更新対象にならない。
追加したカラムの名前がよくないのかと思って、いろいろ調べていたところ、CakePHP のおいしい食べ方で同じ現象が説明されていた。
debugレベルを0にしているとモデルがキャッシュされていることが原因で、データベースの構造が変わっていても反映されないようだ。通常はリリース後に機能拡張するときには、debugレベルを変更することが多いので、このような現象に悩まされることは少ないかもしれないが、cakePHPでアプリを開発している場合には、頭の片隅に入れておいてもよさそうだ。