Accessing outside variable using anonymous function as params

PhpClosuresScope

Php Problem Overview


Basically I use this handy function to processing db rows (close an eye on PDO and/or other stuff)

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

With this function I can simply do:

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

Let's say now I need to concatenate all $r['title'] in a var (this is just an example).

How could I do that? I was thinking something like this, but it's not very elegant:

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

echo $result;

Php Solutions


Solution 1 - Php

You have to use use as described in docs:

> Closures may also inherit variables from the parent scope. Any such > variables must be declared in the function header. Inheriting > variables from the parent scope is not the same as using global > variables. Global variables exist in the global scope, which is the > same no matter what function is executing.

Code:

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

But beware (taken from one of comments in previous link):

> use() parameters are early binding - they use the variable's value at > the point where the lambda function is declared, rather than the point > where the lambda function is called (late binding).

Solution 2 - Php

What about rewriting 'fetch' to call $func only once ?

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

This way you would call $func only once and re-process the array once fetched? Not sure about the performance even tho calling 200 times a function doesn't sound like a good idea.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiondynamicView Question on Stackoverflow
Solution 1 - PhpXaerxessView Answer on Stackoverflow
Solution 2 - Phpuser103307View Answer on Stackoverflow