HTTP_RequestをHTTP_Request2に書き換える

PHP 5.4以降でE_STRICTによるメッセージが出るようになったこととHTTP_Requestがデサポになっていることから、ようやくHTTP_RequestをHTTP_Request2に書き換えてみることにした。
参考にしたサイトは[php][pear]HTTP_Request2のサンプル#1 : うえちょこ@ぼろぐ
互換性があるライブラリと思いきや、かなり非互換。
コンストラクタから違う。上記参考サイトとあわせて下記参考にしてみてください。
HTTP_Request
HTTP_Request HTTP_Request( [string $url = ”], [array $params = array()])
HTTP_Request2
HTTP_Request2 __construct( [string|Net_Url2 $url = null], [string $method = self::METHOD_GET], [array $config = array()])

CentOS 5.5にPHP 5.2をインストールする

CentOS 5.5のリポジトリでは、PHP 5.1.6までしかインストールできない。
PHPならびに対応するmemcachedのライブラリのインストール方法について「CentOS5.2にPHP5.2.6とmemcachedをインストールする」に記載があるので、こちらを利用するとよい。
ちなみに追加したリポジトリは次の通り。/etc/yum.repos.d/CentOS-Testing.repo として保存するとよい。
[c5-testing]
name=CentOS-5 Testing
baseurl=http://dev.centos.org/centos/$releasever/testing/$basearch/
enabled=1
gpgcheck=1
gpgkey=http://dev.centos.org/centos/RPM-GPG-KEY-CentOS-testing
includepkgs=php*
priority=1

CacheをMemcachedにするとエラーとなる

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倍速くなったことが分かる。