クラス内でコールバック関数を使ったときの失敗

コールバック関数はとっても便利だ。しかし、今回、とあるプログラム作成で思いっきりはまった事象があったのでメモする。今回はarray_walkという関数を使用した。array_walk関数は指定された配列の全ての要素に対して、コールバックで与えられた関数を適用する、という関数だ。

bool array_walk ( array &array, callback funcname [, mixed userdata] )

まず一つ目は単なる備忘録。「callback funcname」には関数名をしているのだが、クラス内で使用する場合は配列の形で関数名を渡してやる。具体的にはこんな感じ。

array($this,’_callbackfunction’)

別のクラス内にある関数を使う場合には上記の「$this」がクラス名(もしくはオブジェクト名)になる。
これは大したことない。問題は次。

とあるクラスの関数内でarray_walkを使用し、全ての要素に対して特定のチェックをかけるルーチンを記述したかった。当然チェックをかけるルーチンはコールバック関数で記述する。

ここでコールバック関数を以下のように書いてみた。
function _check($value,$key,$check){
  if($value==$check){
    $this->checked[]=$key;
  }
}

array_walkの第3引数で「$check」を渡しておき、コールバック関数内で値と「$check」を比較し、同じならクラス内のメンバ変数$checkedに配列の要素として追加していく、というものだ。
しかしこれ、プログラムを実行し、最後にメンバ変数$checkedを出力しても、何も格納されないのだ。何回やっても、代入の仕方を変えてもダメ。何をやっても空だ。

そしてふと気づいた。これって単に関数として呼び出してるだけで、オブジェクトには何の関係もないのでは・・・、もしそうならメンバ変数とか、コールバック関数内から別の関数を呼ぶことも出来ない。

ということだった。
結局array_walkはやめて、単にループで回してチェックをかけることで解決した。まだまだ技量も知識も足りないらしい。

正規表現でhtmlからのタグ抽出

2007/08/09 | PHPで正規表現

<div>ab</div><div>cd</div><div>ef</div>

こういう文字列があるとする。ここから正規表現でab、cd、efという文字列を抽出したいのだが、正規表現の記述で悩んだのでメモ。

(1) 最初はこのような正規表現を書いてみた。
!<div>(.*)</div>!

しかしこれだとなぜか一番最初の<div>と一番最後の</div>にマッチしてしまう。なぜ?。

(2) そこで数時間調べに調べてこんな正規表現に行き着いた。
!<div>(.*?)</div>!

見てのとおり「?」が一つついただけ。しかしたったそれだけで期待する結果を配列で得ることが出来た。「.」は任意の1文字で「*」は0回以上の繰り返し、「?」は0回または1回で「()」はパターンを表す・・・。で結局「(.*)」と「(.*?)」とでは何が違うのか・・・全然わからない。

まだまだ修行が足りないということなのだが、両者の違いを明確に教えていただける人がいれば、是非解説をお願いします。

Xoops と Xoops Cube

2007/08/08 | XOOPS

今まで使わなかったがXoops Cubeというソフトウェアがある。元々はXoopsは1本の開発の流れがあったが、そこから分家したソフトだ。先日とうとう安定版がでたとのアナウンスを見かけたので、早速インストールしてみた。

んで驚いた。
だって全然中身が違うんだもん。

Xoops Cubeは日本独自のバージョンとのことだが、そういえば昔、本家でのマルチバイト対応の問題でもめてた時期があったなぁ、と思い出しだ。開発者は日本人なのにおかしな話だ。おそらくあのときの遺恨を引きずって、分家したのだろう。

しかし困った。この数ヶ月で覚えたことが水の泡、というわけではないけれど戸惑うところは多々ある。
まず、管理画面のインターフェースが変わった。正直なれるのには時間がかかる。どこに何があるのかわからないのだ。
そしてモジュール。ユーザ登録などはモジュール化されてしまっている(これはいいことかもしれない)。結局ここはハックする方法を再検討しなくてはならない。
あと、管理画面もテンプレート化された模様。これはちょっとうれしい。

さて、白扇後継モジュールの作成をどうするか考えないといけない。これはちょっとペンディングにしたほうがよさそうだ。少し動向を見守ってから開発に着手することにする。

redirectの仕様

2007/08/07 | cakePHP

以前「redirectメソッドは使えない」という趣旨の投稿をしたが、故あってソースを読んでみた。別に「使えない」ということはなさそう・・・。
まず「別ホストへのリダイレクト」。これはhttpから始まるURL(URI)を引数で与えることで、問題なくリダイレクトできる。
問題は「同じホスト内でのリダイレクト」の中にある。例えば一つのホスト内で以下のような構成で使うような場合だ。

(1) public_html–cake(cakePHPはこちらのディレクトリの中で動作させる)
(2) public_html–misc(cakePHP関連以外のページはこちらに配置)

(1)へのアクセスはhttp://example.com/cake/。
(2)へのアクセスはhttp://example.com/misc/。

となる。ここでredirectの引数に「/cont/func」等と与える。そうするとこれは(1)のURL配下でリダイレクトされる。つまり以下のURLだ。
http://example.com/cake/cont/func

httpから始まらない(正確に言うと引数の中に「://」がない)ときはcakePHP配下でリダイレクトされるということだ。
よって(2)のようにcakePHPの配下でないページに遷移しようとする場合は、たとえ同一ホストであってもhttpから始まる正しいURLを引数として与えないといけない。

これで少しすっきりした。でも結局はphpのheader関数を使ってリダイレクトするわけだから関数の最後はexitして欲しい。exitしないのには何か理由があるのだろうか。

余談だが、このredirect関数。第2引数にhttpのレスポンスコードを入れると、リダイレクトではなく、レスポンスコードとメッセージを返してくれるようだ。ウェブアプリを作りこむ場合は、いろいろ作りこむので純粋にレスポンスコードを返すこともないとは思うのだが・・・。307とか返すときに使うのかなぁ。

cakePHPでの認証モジュール(その2)

2007/08/05 | cakePHP

sdAuthに追加開発をしてしまおうかと思ってたら、ちゃんとそういうコンポーネントが公開されてました。

obAuth

グループ管理も出来て優れもの。今後は小規模開発ならsdAuth、複数ユーザ管理ならobAuthという流れになりそうだ。
さすがにobAuthは少し複雑な流れになるので、詳しい日本語解説が欲しいところだが、ちゃんとレビューしてるサイトがありました。

TOYOSYSTEM

結構詳しく書かれてるし、足りない機能の追加とかまでしてある。
勉強になりました。


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