
Lambda functions and closures

Prior to PHP 5.3, defining lambda functions was possible, but they could not be called complete. Now I will give a couple of examples and continue to consider these concepts.
Of course, the dynamic creation of functions does not solve all the problems, but sometimes writing such a one-time function can be useful. You can expand our example:
query = $query;
$this->prefix = $prefix;
}
public function replaceCallback( $match ) {
return ( preg_match('/^{(.*)}$/',$match[1],$m)
? ( empty($this->prefix) ? $m[1] : "{$this->prefix}_$m[1]" )
: $match[1]
);
}
public function build($query) {
static $regExp = '/([^{"\']+|\'(?:\\\\\'.|[^\'])*\'|"(?:\\\\"|[^"])*"|{[^}{]+})/';
return preg_replace_callback($regExp, array(&$this, "replaceCallback"), $query);
}
};
$builder = new Builder(‘cms’);
echo $builder->build(“SELECT * FROM {documents}”);
//Выведет SELECT * FROM cms_documents
?>
The concept of closure is probably familiar to JavaScript programmers, as well as programmers in many other languages. A closure is a function that spans or closes the current scope. To understand all this, consider an example:
As you may have noticed, the function does not have a name and the result is assigned to a variable. A lambda function created in this way returns a value in the form of an object of type closure.
In PHP 5.3, it has become possible to call objects as if they were functions. Namely, the magic __invoke () method is called every time the class is called as a function.
Variables are not available inside the function, unless they are declared global, as well as variables from the child context are not available unless the reserved word use is used. Typically, in PHP, variables are passed to the closure with a value, this behavior can be changed using the ampersand before the variable in the use statement. Consider an example:
multiplier = $multilier;
}
public function getClosure() {
$mul = &$this->multiplier;
return function( $number ) use( &$mul ) {
return $mul * $number;
};
}
}
$test = new ClosureTest(10);
$x = $test->getClosure();
echo $x(8); // Выведет 80
$test->multiplier = 2;
echo $x(8); // Выведет 16
?>
If you remove the ampersands, then 80 will be displayed both times, because the $ mul variable inside the closure will be a copy, not a link.
So, it remains only to find out how this can be applied in practice.
Consider an example:
$arg )
$argv[$i] = mysql_escape_string($arg);
array_unshift($argv, $self->build($query));
return call_user_func_array( “sprintf”, $argv);
};
}
};
$builder = new QueryBuilder();
$deleteBook = $builder->getQueryObject(“DELETE FROM {documents} WHERE id=%d”);
$deleteBook( $_GET[‘id’] );
?>
This example can already be used for quite flexible prototyping. It is enough to declare methods for all SQL operations with the object.
The author does not urge everyone to adhere to this practice, nor does he believe that it is better, all of the above is just an example of use, and perhaps not the most technical and interesting, and nothing more.
UPD Speaking of that very long regular expression, I did not sign it in the comments and decided to put it here. It only looks for strings in single and double quotes, as well as table names and escapes them.