web-dev-qa-db-ja.com

匿名関数をパラメーターとして使用して外部変数にアクセスする

基本的に、この便利な関数を使用して、db行を処理します(PDOや他のものに注目してください)

function fetch($query,$func) {
    $query = mysql_query($query);   
    while($r = mysql_fetch_assoc($query)) {
        $func($r);
    }
}

この機能を使用すると、次のことが簡単にできます。

fetch("SELECT title FROM tbl", function($r){
   //> $r['title'] contains the title
});

今、すべての$r['title']をvarに連結する必要があるとしましょう(これは単なる例です)。

どうすればそれができますか?私はこのようなことを考えていましたが、それほどエレガントではありません:

$result = '';
fetch("SELECT title FROM tbl", function($r){
   global $result;
   $result .= $r['title'];
});

echo $result;
89
dynamic

useドキュメントで説明 として使用する必要があります。

クロージャーは、親スコープから変数を継承する場合もあります。そのような変数はすべて、関数ヘッダーで宣言する必要があります。親スコープから変数を継承することは、グローバル変数を使用することと同じではありません。グローバル変数はグローバルスコープに存在しますが、どの関数が実行されていても同じです。

コード:

$result = '';
fetch("SELECT title FROM tbl", function($r) use (&$result) {
   $result .= $r['title'];
});

ただし、注意してください(前のリンクのコメントの1つから引用)。

use()パラメータは事前​​バインディングです-ラムダ関数が呼び出されるポイントではなく、ラムダ関数が宣言されるポイントで変数の値を使用します(遅延バインディング)。

178
Xaerxess

$ fetchを1回だけ呼び出すように 'fetch'を書き換えるのはどうですか?

function fetch($query,$func) {
    $query = mysql_query($query);   
    $retVal = array();
    while($r = mysql_fetch_assoc($query)) {
        $retVal[] = $r;
    }
    $func($retVal);
}

この方法では、$ funcを1回だけ呼び出し、フェッチされた配列を再処理しますか?関数を200回呼び出してもパフォーマンスがわからないのは良い考えではありません。

0
user103307