cakePHP1.2での確認画面

2008/03/29 | cakePHP

cakePHPでは、bakeしただけで一覧表示、追加、修正、削除の機能がすべて自動生成される。しかし追加、修正、削除の各機能では、確認画面は表示されない(同じようなことをバージョン1.1でも書いた)。バージョン1.1のときは仕方ないので自前で確認画面を実装した。もちろんその時点で、cakePHPの確認画面処理を紹介した記事があったのだが、そのときは何を自分でこだわっていたのか忘れたが自前実装したのだった(その記述はこちらを参照)。
今回は自前実装なんてばかばかしい、と思って上記のサイトをそのまま使おうと思っていたのだが・・・ところがどっこいバージョン1.2では使えなかった。いろいろ仕様が変わっているようだ。

仕方がないので、やっぱり自前で実装した。一応今回は上記の記事を参考にしつつ、なるべくcakePHPらしい記述でやることにして、以下のような内容になった(コントローラを修正)。

–[変更前]———————————————————-
function add() {
  if (!empty($this->data)) {
    $this->Site->create();
    if ($this->Site->save($this->data)) {
      $this->Session->setFlash(__(‘The Site has been saved’, true));
      $this->redirect(array(‘action’=>’index’));
    } else {
      $this->Session->setFlash(__(‘The Site could not be saved. Please, try again.’, true));
    }
  }
  $users = $this->Site->User->find(‘list’);
  $this->set(compact(‘users’));
}

–[変更後]———————————————————-
function add() {
  if (!empty($this->data)) {
    $this->Site->create();
    $btnConfirm=(isset($this->data[‘btnConfirm’])? 1:0);
    if($btnConfirm){
      $this->Site->set($this->data);
      if (!$this->Site->validates()) {
        $this->Session->setFlash(__(‘The Site could not be confirmed. Please, try again.’, true));
      }else{
        $this->Session->setFlash(__(‘The Site has been confirmed’, true));
        //$this->redirect(array(‘action’=>’index’));
        $this->render(“confirm”);
      }
    }else{
      if (!$this->Site->save($this->data)) {
        $this->Session->setFlash(__(‘The Site could not be saved. Please, try again.’, true));
      } else {
        $this->Session->setFlash(__(‘The Site has been saved’, true));
        $this->redirect(array(‘action’=>’index’));
      }
    }
  }
  $users = $this->Site->User->find(‘list’);
  $this->set(compact(‘users’));
}

なおテンプレートも修正の必要がある。やったことは以下の点。
(1) add.ctpのsubmitボタンのname属性を「data[btnConfirm]」とした
(2) 確認画面用のテンプレート「confirm.tpl」を作成した

まだ全部作りきっていないのだが、formヘルパーを使って、以下のものを組み合わせればよい。
・$form->label()
・$form->text()
・その他のtypeはそれに準じて・・・。

この作業にあたっての注意事項はモデルクラス内のvalidates()メソッドだろう。バージョン1.2は1.1のときと使い方が違うので注意が必要だ。ついでに言うと、モデル内のバリデーションの記述方法にも注意が必要だ(おそらく正式バージョンリリース時までに修正されるだろう)。

細かい記述方法は後日取りまとめてからということで。

WordPress高速化への道

2008/03/28 | SNS/CMS/ブログ

WordPressの便利さは大変すばらしいが、速度の遅さもすばらしい(すばらしく遅い)。もっとも・・・遅いといっても大量のデータを投稿してあれば、の話でもあるわけだが。
この遅い状況を改善する方法を考察してみた。もちろんボトルネックの洗い出しなので、WordPressよりも低次元なレベルから考えなくてはいけない。できるかできないかは別にして列挙する。

(0) インフラの高速化
WordPressが設置してあるサーバの回線環境を高速化する。もちろんレンタルサーバでは無理。一番実現できなさそうな部分ではある。

(1) ハードウェアの高速化
レンタルサーバでは無理な話。CPUの高速化はもちろんだけれど、もっとボトルネックになりそうなのがハードディスク。ストライピングを組み合わせられればかなり早くなるはず。

(2) MySQLのキャッシュ機能を利用
MySQLを適切な設定にするのはもちろんだが、キャッシュ機能を利用して、MySQLへの接続回数を減らすという方法だ。これはかなり有効だろう。しかし、この方法は専用サーバなら可能だが、レンタルサーバでは無理だ。具体的な設定箇所は「query-cache-type」や「query-cache-size」など。

(3) PHPのキャッシュ機能を利用
PHPはリクエストの都度コンパイルされる言語だ。つまりコンパイルの時間がボトルネック。だからeAcceleratorなどを組み込んでみる価値はある。もちろん専用サーバではできるが、レンタルサーバでは無理(事前に組み込まれているレンタルサーバなら問題ない)。ただし、これはアクセス数が多い場合には有効だが、そもそもアクセス数が少なければ効果が薄そうだ。

(4) WordPressのキャッシュ機能を利用
WordPressはリクエストを受けると、PHPファイルがコンパイルされ、MySQLに接続し、データを取得して表示する、という流れだ。つまりリクエストの都度MySQLに接続するので、当然MySQLが遅い場合は表示が遅くなる。だからMySQLに接続して取得したデータをキャッシュしておき、毎回データベースに接続するのをやめれば高速化が図れる。
この方法はそもそもMySQLに機能として含まれている(ただしデフォルトでは無効化されている)。この機能を有効化するには以下の作業をおこなう。
・ディレクトリ「wp-content/cache」を作成し、パーミッションは777。
・設定ファイル「wp-config.php」に以下の一行を追加(一番上がいい)。
 define(‘ENABLE_CACHE’,true);

(5) ページ単位でキャッシュする(プラグインの利用)
(4)を導入するとデータベースへの接続は減少する(無しにはならない)。しかしPHPがデータを組み立てる処理はその都度実行される。ページの組み立て作業そのものをキャッシュするのがプラグインwp-cacheだ。つまりいったん表示されたページの出力内容そのものをキャッシュしておき、次回から同じURLへのアクセスがあると、複雑な処理(データの取得やデータの組み立て)は一切スキップして、キャッシュした内容を表示するのだ。

高速化の方法は大体こんな感じ。後は不必要なプラグインは削除したり、テーマ内でのプログラム処理を極力減らすなどの努力は必要だろう。

cakePHPでファイルアップロード機能を自前で実装する

2008/03/27 | cakePHP

「自前で実装する」といってもcakeForgeのスクリプトの中で、いい感じなのを見つけたのでそれを流用するだけなのだが・・・。

以前アップロードを簡単に実現するためのコンポーネントのことを記事に書いたけど、あれはあれで複雑で自分好みにするのは少し面倒だった。であれば「コンポーネントで実現するよりもべた書きしたほうがいいかもしれない」と思い、どういうふうに記述すればいいのか探してみた。そしたらいいお手本があった。

Cheesecake Photoblog

cakeForgeのフォトアルバムを作成するためのスクリプトだ。この中のphotos_controller.php内の記述が参考になる(addの記述の部分)。

ファイルのアップロードについては、まずこんな具合に取り扱っている(その他のフォーム要素の取り扱いと同じ)。
$this->params[‘data’][‘Photo’]

で、ファイル($_FILES)の各変数を処理しないといけないわけだが、それはこんな具合にして対応できるようだ。
$this->params[‘data’][‘Photo’][‘file’]

最終的にコントローラ内では以下の一行が保存処理になっている。
$this->Photo->savePhoto($this->params[‘data’][‘Photo’][‘file’], $thumbSize, $thumbType)

つまりコントローラから、モデル(この場合はPhoto)に対して「保存処理を実行しなさい」という命令を下し、後はモデルにおまかせしてしまっているのだ。本来データの取り扱いはモデルのお仕事なのだから、これはこれで記述の仕方がスマートなように感じる。次にモデル(photo.php)のほうを見てみる。

function savePhoto($fileData,$thumbSize,$thumbType) {
  vendor(‘ccImageResize.class’);
  if (move_uploaded_file($fileData[‘tmp_name’], WWW_ROOT . “img/photos/” . $fileData[‘name’])) {
    $resizer = new ccImageResize;
    if ($resizer->resizeImage(WWW_ROOT . “img/photos/” . $fileData[‘name’], WWW_ROOT . “img/thumbnails/” . $fileData[‘name’],$thumbSize,$thumbType)) {
      return true;
    } else {
      // TODO: Clean up and set error message
      return false;
    }
  } else {
    // TODO: Set error message if move_uploaded_file fails
    return false;
  }
}

別途用意してある画像サイズ変更のためのライブラリが使用されてはいるが、直接関係のあるところは一目瞭然「move_uploaded_file」な部分だ。案外「生」なやり方で書いてある。

でもこのやり方、すごくスマートな気がするので、現在作成中のアプリはこれでいくことにする。

モデルに関係なくSQLを発行する

2008/03/26 | cakePHP

cakePHPではモデル(データベースのテーブル)とコントローラが密接に関連している。だからコントローラでデータベース内のデータを取得する際、通常は(あらかじめどのテーブルを使うか決められた)モデルを介してデータを取得するため、モデルで指定されたデータ以外を取得しようとするとエラーになったりすることがある(単にやり方がまずいだけなのだが)。
こういうときはデータベースに直接SQLを投げるのが手っ取り早い。cakePHPらしからぬ記述にはなってしまうが、個人的にはこれで十分。ノーマルな処理はcakePHPのノーマル処理に従い、一部の例外は直接SQLを発行することで進めることにした。
データベースに直接SQLを投げる方法は以下の記述を使用する。

$db=& ConnectionManager::getDataSource(‘default’);
$result=$db->query($sql);

これ、多分第二引数でキャッシュするか否かをbool値で与えるんだろうと思う(調べるの面倒なのでこのまま続行)。

SQLを書かなくてもプログラムが書けるところがcakePHPのいいところなのだが、直接SQLを書くことができるようになることで、より幅広く使えるようになるはずだ。

直接SQLを発行してみる

2008/03/25 | cakePHP

複雑なSQLを発行したい。
そう考えると、cakePHPで持ってる機能を使うよりも直接SQLを発行したほうが早そうだ。本当はcakePHPのお作法どおりにやりたいけれど、スピード第一。まずは動かしたい。cakePHPで直接SQLを発行する方法はこんな感じ。

$this->Site->query(‘SELECT * FROM sites as Site’,false)

モデルオブジェクトにqueryメソッドでSQLを発行することができる。queryメソッドには第二引数を渡すことができる。このメソッドはデフォルトで第二引数がtrueで渡されているのだが、この値によってSQLの結果をキャッシュするかどうかを決定できるらしい。本番時はtrueでいいのだが、開発時はfalseにして、結果をキャッシュしないほうが都合がいい。

ん〜。難しい。


守谷市(まちの情報ポータル) 無料アンケートレンタルjpForm.net