I'm scratching my head at some PHP code. I can't tell if it logically works yet, as I'm quite new to PHP and it won't execute yet due to a syntax error: syntax error, unexpected 'use' (T_USE), expecting '{'
The syntax error is tripping up on a use
, despite the PHP version fully supporting it, and the syntax (as far as I can tell) being correct.
The code checks which database implementation is specified, and it'll define the functions for whichever one it is. Because I can't define functions returned from other functions as global functions, I store it in them in variables, 'wrapping' access via global functions that capture the variables from their outer scopes, or at least they should do.
The two lines yielding errors have been marked:-
function query_escaper($element_escaper) {
return function($query, $values) use ($element_escaper) {
return join(array_map(
function($query_elem, $value) {
return isset($value)
? $query_elem . $element_escaper($value)
: $query_elem
;
},
explode('?', $query),
$values
));
};
}
function define_postgresql_functions() {
[...]
$escape_query = query_escaper('pg_escape_literal');
#
# XXX The error occurs here :-
#
function escape_query() use ($escape_query) {
return call_user_func_array($escape_query, func_get_args());
}
[...]
}
function define_mysql_functions() {
[...]
$escape_query = query_escaper(function($str) {
return use_database(function($database) use ($str) {
return $database->real_escape_string($str);
});
});
#
# XXX The same error also occurs here :-
#
function escape_query() use ($escape_query) {
return call_user_func_array($escape_query, func_get_args());
}
[...]
}
switch ($database_info['type']) {
case 'postgresql':
define_postgresql_functions();
break;
case 'mysql':
define_mysql_functions();
break;
default:
throw new DatabaseNotImplementedException();
}
I'm looking for two possible solutions: either being able to capture those variables from the outer scope, or another way of defining global functions as functions returned from other functions.
The pattern function\s+\w+
always declares a function in the global scope, meaning you have to use the global syntax. This means you can't name the function if you're creating a closure. So this is invalid:
function escape_query() use ($escape_query) {
But this would work fine:
$escape_function = function() use ($escape_query) {
There are a few different ways to accomplish what you want. eval
comes to mind, as does using a static variable in the function, or the OOP solution.
I think the OOP solution is probably the easiest:
class Escaper {
public static $escape_function;
}
// in your function
Escaper::$escape_function = function() use ($escape_query) { //...
// later
Escaper::$escape_function('a','b','c');