익명 함수를 매개 변수로 사용하여 외부 변수에 액세스


93

기본적으로이 편리한 기능을 사용하여 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']변수 를 연결해야한다고 가정 해 봅시다 (이것은 단지 예입니다).

어떻게 할 수 있습니까? 나는 이와 같은 것을 생각하고 있었지만 그다지 우아하지는 않습니다.

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

echo $result;

답변:


188

당신은 사용이 use같은 문서에 설명 :

클로저는 부모 범위에서 변수를 상속 할 수도 있습니다. 이러한 변수는 함수 헤더에서 선언해야합니다. 상위 범위에서 변수를 상속하는 것은 전역 변수를 사용하는 것과 동일하지 않습니다. 전역 변수는 전역 범위에 존재하며 어떤 함수가 실행 되든 동일합니다.

암호:

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

그러나주의하십시오 (이전 링크의 주석 중 하나에서 가져옴).

use () 매개 변수는 초기 바인딩입니다. 람다 함수가 호출되는 지점 (후기 바인딩)이 아닌 람다 함수가 선언 된 지점에서 변수 값을 사용합니다.


1
글로벌 감속을 제거해야하지 않습니까?
aziz punjani 2011

19
+1을 강조합니다 early binding. 그러나 위의 예에서 use (&$result)참조로 전달되는 경우 실제로 중요하지 않은 것 같습니다.
Dimitry K

4
@DimitryK 예, 여기서 참조는 기본 동작 (초기 바인딩)을 우회하는 데 사용됩니다.
Xaerxess

3
@machineaddict 기본 use 초기 바인딩입니다. 늦은 바인딩에 대한 해결 방법을 의미하는 경우- use참조로 변수를 전달합니다. &=>를 사용하여 변수를 use (&$result)변경 $result하고 익명 함수 (또는이를 호출하는 것)를 호출하기 전에 변수를 변경 합니다
jave.web

1
클래스 인스턴스는 항상 참조로 전달되므로 &를 사용할 필요가 없습니다. (인스턴스를 완전히 덮어 쓰지 않는 한).
조엘 Harkes

0

$ func를 한 번만 호출하도록 'fetch'를 다시 작성하는 것은 어떻습니까?

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

이렇게하면 $ func를 한 번만 호출하고 일단 가져온 배열을 다시 처리 할 수 ​​있습니까? 함수를 200 번 호출해도 성능이 확실하지 않은 것은 좋은 생각처럼 들리지 않습니다.


네, 맞아요. 그러나 여기저기서 몇 ms를 얻는 데 관심이 있다면 mysql_fetch_assoc () 대신 mysql_fetch_row ()를 사용할 수 있습니다. 열 위치를 알아야하므로 처리하기가 매우 어렵습니다. 이렇게하면 각각 30 개 행의 2000 개 요청에 대해 0.205에서 0.180으로 전달됩니다.
user103307
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.