#php #function-calls
Вопрос:
Я пишу конструкцию на PHP, в которой синтаксический анализатор определяет, какую функцию вызывать динамически, примерно так:
// The definition of what to call
$function_call_spec = array( "prototype" => "myFunction",
"parameters" => array( "first_par" => "Hello",
"second_par" => "World"));
// Dispatch
$funcPrototype = $function_call_spec["prototype"];
$funcPrototype(); // Here we call function 'myFunction'.
Все это прекрасно и шикарно. Но теперь наступает следующий шаг, передача параметров, которые я действительно не знаю, возможно ли это так, как я хочу это сделать. Однако меня никогда не перестает удивлять, на что способны языки сценариев в наши дни, так что вот:
Можно было бы передать параметры функции следующим образом:
// Here we call function 'myFunction' with the array of parameters.
$funcPrototype( $function_call_spec["parameters"] );
Однако я хочу правильно объявить «myFunction» с четкими аргументами и т. Д:
function myFunction( $first_par, $second_par )
{
}
Затем следует вопрос: Существует ли какой — либо способ динамически передавать параметры функции, просто проходя по массиву параметров?
Чтобы уточнить, я не хочу делать это так:
$funcPrototype( $function_call_spec["parameters"]["first_par"],
$function_call_spec["parameters"]["second_par"] );
Потому что для этого требуется, чтобы мой код статически знал подробности о моей функции, что противоречит всей идее.
Вместо этого я бы хотел сделать это каким-то образом, возможно, так:
// Special magic PHP function which can be used for invoking functions dynamically
InvokeFunction( $funcPrototype, $function_call_spec["parameters"] );
Что затем приводит к вызову функции myFunction, и все параметры в массиве передаются каждой отдельной переменной параметра в прототипе.
Любые комментарии приветствуются.
С уважением.
/R
PS: Ни один код в этом посте не был протестирован на наличие опечаток и т.д.
Ответ №1:
Вы должны использовать call_user_func_array
, который может вызывать любую функцию или метод и принимать параметры из массива.
В качестве альтернативы вы можете использовать ReflectionFunction::invokeArgs
, но в этом нет никакой пользы call_user_func_array
, если вы уже не используете этот класс для чего-то другого (например, для проверки того, принимает ли вызываемая вами функция соответствующее количество и типы аргументов).
Ответ №2:
call_user_func_array($funcPrototype, $function_call_spec["parameters"]);
Возможно, вам захочется создать оболочку, которая назовет функцию в соответствии с вашими предпочтениями, например:
function InvokeFunction($function, $args = array()) {
return call_user_func_array($function, (array)$args);
}
С помощью этой функции вы можете вызвать ее 3 различными способами:
$return = InvokeFunction('doStuff');
$return = InvokeFunction('doStuff', $single_arg);
$return = InvokeFunction('doStuff', $multiple_args);
Ответ №3:
call_user_func_array()
это лучший выбор, если вам не нужно обеспечивать соблюдение контракта, в противном случае используйте ReflectionFunction
.
Ответ №4:
http://us2.php.net/create_function
Когда вы используете create_function(), ваши аргументы не оцениваются до выполнения. Довольно мило.