SmartyのPOSTフィルターが適用されない

2008/01/20 | Smarty

SmartyはPHPで一番メジャーなテンプレートエンジンということもあり、各種フレームワークと組み合わせて使うことも多い。しかし時折、うまく動かないこともある。
今回遭遇した問題は「SmartyのPOSTフィルターが動作しない」ということ。

Smartyはその処理の前後で、フィルター処理をかけることができる。たとえば文字コードを変換するとか、特定の文字列を置換するとか・・・。便利な機能だ。
とあるフレームワークを使っていて、上記の問題が発生した。POSTフィルターは動作しないがPREフィルターは動作するのだ。なぜ???。

結論として、これはフレームワークを併用して使用していることが原因だった。では、その理由は何か?。

フレームワークでは、通常Smartyを、Smartyの正規の手順にそって呼び出す。つまりSmartyクラスからオブジェクトを生成して、そのオブジェクトを持ちまわって、変数の割り当て処理等をおこなうのだ。
正規の手順で変数割り当て処理までおこなうのだから、当然この時点で終了しているであろうはずのPREフィルター処理は完了しているはずだ。

しかし描画処理はというと、Smartyの機能で完結しているわけではない。たいていのフレームワークでは、変数等の割り当てられたHTMLをfetchし、それをフレームワークの機能を使って出力していることが多い。つまりSmartyの正規の手順を踏まずにHTMLを出力していることになる。であれば、Smartyで最後におこなわれる処理(POSTフィルター)は実行されないまま、出力がおこなわれると考えることができるわけだ。

本来ならフレームワーク側で、Smartyの処理を最後まで面倒を見ないといけないはずなのだが、フレームワークによっては省略していることも多いようだ。

本件、ソースコードをじっくりみたわけではないのだが、おそらく上記のような理由で間違いないだろう。かなりはまってしまったのでメモ。

渡された値に対して、常に同じ処理をかける

2008/01/15 | guesswork

年末・年始・・・気がつけば2週間ブログの更新をお休みしてた。

フレームワーク「guesswork」。好調に開発を進めている。かなり使いやすい。まもなくPHP4のサポート期限が切れるので、PHP5対応の新バージョンが待たれるところだ。いちおう原稿バージョン(0.0.3)でもPHP5で動作するとのことなので、さほど気にはしていないのだが・・・。

guessworkで、外部からGETやPOSTで渡された変数に共通した処理を加える機能を実装した。やり方としては、適当な名前でControllerクラスを継承したクラスを作成し、その中に共通処理を記述した。以後、基本的に、この新しく作ったクラスを読み込んで継承していく作りとなる。

<?php
require_once(dirname(__FILE__).’/../Guesswork.php’);
class myController extends Controller
{
  function init()
  {
    $this->cleanup();
    // DB接続などはここに記述
  }

  function cleanup()
  {
    $this->_gw_params=$this->recursiveCleanUp($this->_gw_params);
  }

  function recursiveCleanUp($params)
  {
    foreach($params as $param => $value){
      if(is_array($value)){
        $value=$this->recursiveCleanUp($value);
      }elseif(is_string($value)){
        $value=trim($value);  // ここに共通処理をかく
      }
      $params[$param]=$value;
    }
    return $params;
  }
}

配列で値が渡された際に、再帰的に処理しているところがミソ。あと、_gw_params変数を見つけたのがよかった。
快適。

軽量フレームワークguesswork

2007/12/26 | guesswork

今回新たな開発案件でguessworkを採用することにした。
データベースアクセスや認証については、外部のライブラリに頼らないといけないが、本当に必要最小限のMVCをルールにのっとって操作できるというところが素敵なフレームワークだ。
たいていのフレームワークの場合、ディレクトリ構成をきちんとルール付けすることによって、余計な設定ファイルを記述しなくてもいいようになっているわけだが、このguessworkは別。基本的にファイルを自由自在に配置できるようになっている。
ウェブアプリの開発には2種類あって、ウェブサイトの管理そのものを開発者だけ(+理屈のわかっているコーダ)が管理するタイプと、開発者が管理にかかわるが、コーダがどんどん勝手にコーディングも更新してしまうタイプ。前者の場合は、サイトを管理する立場の人はいろんなタイプはあるけれど、基本的に「ルールを理解してくれる人」で構成されている。後者はたいていの場合「複雑なルールは面倒」と思う人で構成されている。前者の場合は、フレームワークでありがちな制約を理解してくれる可能性が高いが、後者の場合は、自由にファイルを配置したい、と思う人が多いはずだ。
今回の案件では、どちらかというと後者のタイプで開発を進めるほうがよいと判断したのだ。
軽量で、機能を極力減らしてあるフレームワークだけあって、理解するのは簡単だ。現在は「テンプレートエンジンを使用せず(デフォルトはSmarty)」、「データベースはADODBで」開発している。認証ロジックはまだ検討中だ。

基本的にはcakePHPで通しておきたいというのもあるが、やはり臨機応変でその場に適したフレームワークを使うというのが一番ベストだと思う。PHPのフレームワーク自体は基本的にmojaviからスタートしているわけだから制約がたくさんある(制約から抜け出すためには理解する知識が必要)。内容を理解しなくても、ある程度のアプリを書くことができるguessworkは、ある意味おさえておきたいPHPフレームワークのひとつだろう。

今後は開発していく上ででてきたTips等々を紹介することにする。

PostgreSQLの状態を知る

2007/12/18 | PostgreSQL

とあるクライアントから「データベースのソート結果が変なんだけど」という連絡をいただいた。自分が構築したシステムではないので完全にお気楽モードで調べて差し上げることにした。データベースはPostgreSQL、プログラム言語はPHP。他人が作ったデータベースを触るのは基本的に嫌だが、それでも頼っていただける、というのはありがたい。ということで・・・。
まずはプログラムのバグを疑った。しかし、それらしい問題というのは見当たらない。SQL出力を確かめたり、取得したデータを確かめたり。しかしいずれも整合性が取れている(整合性が取れているにもかかわらず、データの並びがおかしいとはこれ如何に)。
データベースのダンプも預かっていたので、画面に出力させたSQLを自分の環境でも実行してみた。

ん?、ん?、ん???。

先方のサーバと自分のサーバで表示される順番が違う???。なぜ???。
バージョンもほとんど同じなのだからこんなことないはずなのに、と思ったら思いついた点がひとつ。ロケール(locale)の設定だ。データベースで日本語を使用する場合はロケール設定を無効(というかCを指定)にしなければいけない、とかなんとかいう設定があったはず。

で、現在の状態を調べるにはどうすればよいのか調べてみた。
pg_controldata /var/lib/pgsql/data/

このコマンドでいろいろわかる!。ちなみに引数ではデータの場所を指定する。結果として、表示される値のうち「LC_CTYPE:」の値が「C」ではなかった。どうやら、データベースの初期化をきっちりやっていないことが原因らしい。「忘れた」のか「知らなかった」のかわからないけど、クライアントにはいちおう状態を説明。どんな反応をされるのか・・・。少しクライアントがかわいそう。構築した業者さん・・・ハズレだったんだなぁ。

自分へのアクセスができない

「定期的な処理」といえばcronだ。共用のレンタルサーバだと使えないところがほとんどだが、これは便利な機能だ。この機能を使いたいがゆえに、使おうとするサーバは、一応きっちり調査する。ちなみに今、割と使っているのは海外サーバのここ。

3iX

cPanelという管理画面が提供されていて、その中でcronの設定ができる。日本ではあまりメジャーではないが割と使える管理画面だ。あとは、今回の本題PLESKでも使える。

さて定期的に動作させたいプログラムだが、PHPしかできない人にとってはやっぱりPHPで書きたいところ。PHPではコマンドライン版があるので、PHPで完結できるところもありがたい。しかしウェブ用の設定とコマンドライン版の設定が異なることもあったりするし、コマンドライン版そのものが使えないところもあるから厄介。そういうときは、通常通りウェブ用にプログラムを書いておいて、wgetやlynxなどのコマンドラインから使えるブラウザでアクセスするよう設定してやると、定期的な処理ができるようになる。ちなみにwgetなどのブラウザが使えない場合は・・・普通はCGIが使えることが多いので、CGI版PHPで簡単なブラウザを書いてしまう。
だったらCGI版PHPで処理書けば・・・という話になるのだが、これもやはり設定がモジュール版と違うことがあるから・・・。

で、本題。上記の処理を入れたのだが、うまくアクセスしてくれない。PLESKサーバに設置したのだが、なぜか自分へのアクセスで失敗する。
しばらく悩んだ末、自ドメインの名前解決ができていないのでは?、と考えた。で、nslookup・・・。なんと自ドメインのAアドレスが127.0.0.1と返されてしまった。これじゃぁダメだよね(というか、これで動作するように設定してあれば別なんだけど)。仕方ないので/etc/hostsの該当箇所の記述を削除した。これで問題解決。

他のところに影響が出なければいいのだけれど。


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