‘CakePHP’タグの記事

Google Chrome のバグ? »

新ブラウザ、Google Chrome (0.2.149.29) を試してみたら、早速不具合を発見してしまった。
自分のサイト http://library.tail-lagoon.com で「魚」と検索すると、なぜか検索文字が「魁E」になってしまう。Chrom は Safari と同じレンダリングエンジンを使用していると聞いたので、Windows版Safari でも試してみたのだが問題ない(もちろん、IE7 や FireFox3 では既に問題ないことを確認済み)。
うーん、ベータ版ゆえの現象だろうか?

でも、アプリ側の文字コードの処理にも、問題がないとはいえないし、同様のことが別のユーザ・エージェントで起こらないとは断言できない。案外、Webアプリ側で対策すべきことかも。

「魚」という文字のコードについて調べてみると
SJIS : 8B9B
JIS : 357B
EUC : B5FB
UTF-8 : E9AD9A
UTF-16 : 9B5A
で、Shift-JISでよくある 5c文字(バックスラッシュ)でもなさそうだ。
もうちょっと調べてみる必要あり、ってことか。

Tail-Lagoon @ 22:08   |   PageUp

RewriteBase »

CakePHP の設置時、.htaccess でつまずいた。
ローカルでは問題なかったのに、レンタルサーバにアップしたら、500エラーが発生。mod_rewrite が使えないせいかと疑ったのだが、しかし WordPress で使っているのだから、mod_rewrite は使用できるはずだ。
そこでそれぞれの .htaccess を比較すると、CakePHP のそれには Rewritebase の指定がなかったため、これを追加してみたら、あっさり動いた。
(他にも、FTP からは同階層に見えている公開エリアと非公開エリアのフルパスが実は全く違う(※1)ということを知らず、それに気づくまでにもかなりてこずったのだが、これはレンタルサーバの仕様およびドキュメント不足のせいなので、別の問題)
いつかまた同様の問題に出くわすかもしれないので、忘れないようメモしておく。

(webroot)/.htaccess

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /   # この行を追加
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>

(※1) 自分のためにメモっておくが、公開エリアと非公開エリアについて、フルパスでは全く違うのに、相対パスでは参照可能なのだ。不思議。シンボリックリンクを置いているのだろうか?(でもそれなら、フルパスでだってリンクにアクセス可能なのでは?)……もともと別の箇所で相対パスで使用してうまくいっていたから、ますますフルパスが違うなど思いもよらなかったのである。思い込みってよくないね。しかしどういう仕組みなのだろう?

Tail-Lagoon @ 16:24   |   PageUp

CakePHP の h() »

 CakePHP では htmlspecialchars() を h() と短縮できるのだが……、ちょっと気になることがあって、該当するソースを確認すると、下記のようになっていた。

cake/basics.php

    function h($text) {
        if (is_array($text)) {
            return array_map('h', $text);
        }
        return htmlspecialchars($text);
    }

 配列を渡すと、その値をすべて処理してくれるのは便利だけど、htmlspecialchars() はデフォルトのまま使っているから、シングルクォートは変換されない(ENT_COMPACT になる)。これはちょっと危険な気がする。といって、コア部の cake/basics.php を直しても、バージョンアップのたびに対処しなきゃいけないし、むしろ忘れてしまう可能性大。

 ではやはり h() は使わず htmlspecialchars($str, ENT_QUOTES, 'UTF-8') ときちんと書くのが一番安全かな。でもかなり長ったらしいから、毎回面倒だ。本当は app/ の中のどこか適当な場所に、改良した h() が定義できればいいんだろうけど、でもどこに置けばいいのかな?

 と調べていたら、app/config/bootstrap.php に書き込めばいいらしい。なるほど、このファイル、今後もいろいろ利用価値がありそう。覚えておこう。

    function hsc($text, $quoteStyle=ENT_QUOTES, $encoding='UTF-8') {
        if (is_array($text)) {
            return array_map('hsc', $text, $quoteStyle, $encoding);
        }
        return htmlspecialchars($text, $quoteStyle, $encoding);
    }

Tail-Lagoon @ 12:54   |   PageUp

DISTINCT »

CakePHP といえば、このあいだ早速けつまづいたことがあったので、書き留めておく。

あるフィールドの値を重複なしですべてリスト化したかったのだが、

$keyLists = array();
$SQLStr = 'SELECT DISTINCT column FROM dbTables ORDER BY forSortColumn ASC';
if ($Res = mysql_query($SQLStr)) {
    while ($Row = mysql_fetch_row($Res)) {
        $keyLists[] = $Row[0];
    }
}

これを、findAll() とかでできるかと思ったら、DISTINCT をどう指定していいのかわからなくて、結局上記コードのままになっている。で、これをメソッドとしてモデルに追加したのだが……こういう場合、これで正解? それとも別の手がある?

追記

自前のクエリを発行する場合は query() が使えるということがわかった。これならコントローラーで気軽に(?)使える。この場合、返ってくるのはCakePHPモデルの他のAPIを使った時と同様の構造を持つ配列。
ただ、これを使用した場合の新たな疑問は、DBテーブル名にプレフィックスを付加している場合、他のAPIではプレフィックスを意識せずに使えるけれど、query() の場合は意識しないといけないらしい、ということ。
ビュー内で使用する時、常にこのプレフィックスを付けて($Variable['PreFix_Table']['Column'] とか)呼び出すのは、何だかちょっと気持ち悪い感じがする……。統一して $Variable['Table']['Column'] のように使いたい場合はどうすれば?
というわけで、それが解決するまでは、自前メソッドのままの方が使いやすいので、query() の使用は保留。

さらに追記── AS の使用 (080701)

もしかしたら、下記でいけるかもしれない。未確認。そのうち試してみよう。

$this->User->query('SELECT DISTINCT column FROM prefix_users AS User ORDER BY forSortColumn ASC');

Tail-Lagoon @ 15:39   |   PageUp

CakePHPの命名規則 »

CakePHPシステムデザイン(最新規約)

まず何か作ってみようと思って、真っ先に困惑したのが命名規則。データベースのテーブル名やらモデル名やらコントローラとか……ある命名規則があって、必ずしも遵守する必要はないけれど、守っておけば作りやすい(簡単便利?)らしい。というわけで、フォーラムの中にちょうどこれに関する記事を見つけたので、ブックマーク。

CakePHPシステムデザイン(最新規約)

Tail-Lagoon @ 18:29   |   PageUp