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

コールバック関数はとっても便利だ。しかし、今回、とあるプログラム作成で思いっきりはまった事象があったのでメモする。今回は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はやめて、単にループで回してチェックをかけることで解決した。まだまだ技量も知識も足りないらしい。

2件のコメント

  1. ikeda :

    使い方は間違ってないし、ちゃんとその用途で目的を達成できると思います。
    PHP4だとオブジェクトが参照されないので、array(&$this,’check’)とする必要があるかと思いますが。(手元にPHP4ないので未確認ですが。)

  2. かおるん :

    コメントありがとうございます。
    ・・・参照渡しですか・・・。失念しておりました。
    で、やってみて動作しました。
    まだまだ参照渡しに対する理解が低いようです。勉強になりました。

コメントを残す


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