guessworkでパラメータを自由に設定

2008/04/03 | guesswork

cakePHPも試しつつ、実は使い続けているguesswork。この軽量なフレームワークはPHP5でも動作し、いまだに手放すことができずにいる(多分使い続けるだろう)。

さて。guessworkでは外部からgetやpostで引き渡された値をcontrollerクラス内の同名のクラス変数に割り当てられるようになっている。しかし外部からの変数の汚染を防ぐために、デフォルトのクラス変数にしか割り当てられない(つまりデフォルトで想定していない引数を外部から割り当てようとしてもできない)。

これは有効なようだが、意外と使えないかもしれない。特にフォームの入力項目を可変にしたいような場合には、デフォルトでクラス変数を定義することができないので「実現不可能」ということになる(回避策はいろいろあるのだが)。

しかし本来guessworkでは、変更されたくないクラス変数は_(アンダースコア)で始めるというルールがあるわけだから、上記のような機能が不要なようだろうと思っている。もちろん想定外の変数を割り当てられてしまうというのは致命的なバグになる可能性もあるわけだから、安全をとるなら現状の記述がよいとは思う。

しかし不便だから書き換える。該当箇所はGuesswork/Controller.phpの200行目付近のinitializeController関数内の記述だ(デフォルトの状態は下記にようになっている)。

function initializeController()
{
  // call initialize method
  $method_name = “init”;
  if (method_exists($this, $method_name)) {
    call_user_func(array(&$this, $method_name));
  }

  // set acceptable form parameters to instance variable
  $vars = get_class_vars(get_class($this));
  $acceptable = array();
  foreach ($vars as $key => $value) {
    if (substr($key, 0, 1) == ‘_’) {
      continue;
    }
    $acceptable[] = $key;
  }

  // call form parameter callback if defined
  if (is_string($this->_gw_form_parameter_callback)) {
    if (method_exists($this, $this->_gw_form_parameter_callback)) {
      $this->_gw_params = call_user_func(array(&$this, $this->_gw_form_parameter_callback), $this->_gw_params);
    }
  }

  foreach ($this->_gw_params as $key => $value) {
    if (in_array($key, $acceptable)) {
      $this->$key = $value;
    }
  }

  return true;
}

この関数は3つのステージで構成されているようだ
○「// call initialize method」
 init(初期化)関数があれば実行
○「// set acceptable form parameters to instance variable」
 デフォルトの受け入れ可能なクラス変数を取得
○「// call form parameter callback if defined」
 1.外部から渡された変数群にフィルター関数をかませて
 2.受け入れ可能な変数であれば、クラス変数に代入する

「あ゛」ここでフィルターがかけられるのか。わざわざ専用関数を書いてinit関数から呼び出していたよ(後日書き直すことにする)。で最後の「受け入れ可能な変数で・・・」なところさえ書き直せば、デフォルトで変数を定義していなくても使用できるようになりそうだ。

ということで上記のプログラムの最下部を以下のように書き換えた。

  foreach ($this->_gw_params as $key => $value) {
    if (in_array($key, $vars) && substr($key,0,1)==’_’) {
      continue;
    }
    $this->$key = $value;
  }

  return true;
}

これで「外部からの変数は何でも来い」の状態になってしまっている。当面は注意するという前提で、必要に応じて関数を上書きして使用することにする。

guesswork。新しいバージョンは出ないのだろうか。だったら派生させてオリジナルクラスを作るべきだろうな。超便利だから。

関数の呼び出し方(変数と括弧)

2008/04/02 | PHPの基本

以前、文字列操作関数substrの特別な場合として以下のような記述方法について記事を書いた。

$variable=’abcdefg';
print($valiable{3});
// 結果は「d」が表示される

変数名に{}をつけることで関数の代わりになるというお話しだった。
今回あるプログラムを読んでいて、こんな記述を見つけた。
$variable();

変数名に()って・・・今度は何?、と思って調べたらこれは以下のようなことだった。

$variable=’abcdefg';
$valiable();
// こちらはabcdefg()という関数が実行される

もちろんabcdefg()という関数が定義されていないとエラーになる。call_user_func関数の代わりに使うのだろうか。いずれにしてもプログラムの可読性が悪くなるような気がしないではない。

wp-cacheで本当に速くしたい

2008/04/01 | SNS/CMS/ブログ

WordPressが遅いのでwp-cacheを導入している。しかし思ったほど早くならないのはなぜか・・・。としばらく悩んでいた。
どのような作業をしたかというと、以下の通り。

(1) wp-cacheの導入
(2) 定期的にブログの主要ページにアクセスするようcronを設定(wgetで)

こうすれば、運が悪くなければ(タイミングが悪くなければ)、たいていはwgetが事前にキャッシュを作成してくれていて(もしくは検索エンジンのクローラーでもいい)、そのページを閲覧することになるわけだから、基本的には絶対高速なはず、と思っていた。しかし実際はそうではない。

wp-cacheはクライアントを識別して、クライアントごとにキャッシュを作成している。つまりAさんがトップページにアクセスしてキャッシュを作成しても、Bさんがアクセスすると、せっかくAさんが作ったキャッシュを使わず、Bさんようのキャッシュを作成するのだ。これはクッキーを使って実現されている。

具体的にはwp-cache-phase1.phpの23行目の記述。
$key = md5($_SERVER[‘SERVER_NAME’].preg_replace(‘/#.*$/’, ”, $_SERVER[‘REQUEST_URI’]).wp_cache_get_cookies_values());

md5ハッシュ値を生成している記述があるのだが、このハッシュ値がキャッシュのファイル名に使われている。つまりアクセスする相手が違うと違うキャッシュを探すのではないか、と思ったのだが・・・。

上記の記述をコメントアウトし、以下のように書き直した。
$key = md5($_SERVER[‘SERVER_NAME’].preg_replace(‘/#.*$/’, ”, $_SERVER[‘REQUEST_URI’]));

これで確かに同じキャッシュをみるようになった。さて、これで問題がないのかどうか、ということだが、それはwp_cache_get_cookies_values()関数の内容(つまりクッキーで保存されている内容)を調べないといけない。これを調べれば、なぜこのようにキャッシュを分けているのか理解できるはずだ。

しかし、まぁ、とりあえずこのままでいく。

cakePHP1.2はまだまだか

2008/03/31 | cakePHP

cakePHP1.2をいろいろ試してみた。その結果「まだまだ」という結論になった。現状では、素の状態で、基本機能だけを試しているのだが、それでもバグっぽい表示が出る(1.2.0.6311)。もちろんMySQLのバージョンにも依存する部分が大きいのだが、それでもやっぱりダメダメと判断した。

試したのは、bakeしたスクリプトを使ってデータの一覧・追加・修正・削除。データ削除をしようとすると、以下のエラーが出る。

(1) SQLのエラー(結果としてデータが削除できない)
Warning (512): SQL Error: 1066: Not unique table/alias: ‘Category’ [CORE/cake/libs/model/datasources/dbo_source.php, line 440]

(2) 必要なビューが作成されていない(もしくはコントローラの記述ミス)
Error: The view for CategoriesController::delete() was not found.

つまりbakeだけでは基本機能すらちゃんと動かないことになる。そもそもbakeが使えないのであれば、cakePHPを使うメリットが大きく削られるといってもいい。だからやっぱり今回は断念だ。いちおう1.2系を追っていこうとは思うが、当面は1.1系で開発するか、別のフレームワークを使うことになりそうだ。ちょっと残念・・・。

XREAでcakePHPを使う

2008/03/30 | cakePHP

最近何かと便利に使っているXREAだが、ここでcakePHPの開発を始めた。ちなみに借りているのはPHP5環境だ。自分の借りているサーバだけの問題なのかもしれないが、PHPがセーフモードらしく、cakePHPの適切なインストール手順を踏んでいくとエラーが出てしまう(realpath関数がどうとかこうとか)。なのでCGI環境で動作させてみた。インストールだけはうまくいっているようで、いつもの見慣れた画面が出てきた。今回は設定手順をメモ。

(1) 普通にcakePHPをインストール
 ファイルをアップロードして、パーミッションとかデータベース設定とか。
(2) ドキュメントルートにある.htaccessファイルの末尾に1行追加
 AddHandler application/x-httpd-phpcgi .php
(3) 以下のファイルの1行目でセッション保存場所を設定
 session_save_path(‘/PathToSessionDir/’);

これで見慣れた画面は出た(とりあえず)。この先はどうなんだろうか、と少し不安ではあるが、これで開発を進めることにする。


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