Как написать функцию, которая может принимать неограниченное количество параметров?
То, что я пытаюсь сделать, это создать функцию внутри класса, которая включает следующее:
$stmt->bind_param('sssd', $code, $language, $official, $percent);
Вышеприведенные предложения все хороши, но я не думаю, что они будут подходящими для вашей ситуации.
$stmt->bind_param('sssd', $code, $language, $official, $percent);
Если вы хотите обернуть эту функцию, вам нужно будет передать ссылки на исходные переменные аргумента функции bind_param. Я не думаю, что func_get_args () дает вам это, он дает вам значения. Таким образом, невозможно будет использовать их для перехода к родительской функции. Я сражался с подобной проблемой, пытаясь расширить mysqli_stmt и никогда не получал удовлетворительного решения.
На самом деле это не ответ на ваш вопрос, я боюсь, просто предупреждение о том, что другие аргументы могут не работать в вашем конкретном приложении произвольного количества аргументов.
Вы взглянули на func_get_args , func_get_arg и func_num_args
Так, например:
function foo(){ if ( func_num_args() > 0 ){ var_dump(func_get_args()); } }
или:
function bind_param(){ if ( func_num_args() <= 1 ){ return false; //not enough args } $format = func_get_arg(0) $args = array_slice(func_get_args(), 1) //etc }
РЕДАКТИРОВАТЬ
Относительно комментария Эвана Тодса:
У меня нет каких-либо знаний базового API, для которого вы создаете оболочку, но другой альтернативой может быть что-то сделать с функциями цепочки, чтобы ваш получившийся интерфейс выглядел примерно так:
$var->bind()->bindString($code) ->bindString($language) ->bindString($official) ->bindDecimal($percent);
Который я бы предпочел использовать func_get_args, поскольку код, вероятно, более читабельен и, что более важно, менее вероятно, приведет к ошибкам из-за отсутствия переменной формата.
Используйте func_get_args()
:
function my_func() { $args = func_get_args(); foreach ($args as $arg) { echo "Arg: $arg\n"; } }
Раньше вы должны были использовать func_get_args()
, но в php 5.6 вы можете использовать … оператор .
Так, например, вы можете написать функцию, которая возвращает вам сумму всех чисел, отправленных функции:
function bind_param(...$params){ var_dump($params); }
Ваши params
на самом деле являются массивом всех элементов.
При 5 параметрах эта конструкция начинает демонстрировать AntiPattern « Слишком много параметров ». Это предполагает рефакторинг, называемый Parameter Object , объект или структуру с элементами данных, представляющими аргументы, которые должны быть переданы. Однако избегайте превращать его в Magic Container .
См. Также Введение рефакторинга объектов параметров на сайте refactoring.com.
Если вы используете PHP 5.6 или более позднюю версию, списки аргументов могут включать ...
токен, чтобы обозначить, что функция принимает переменное количество аргументов. Аргументы будут переданы в заданную переменную в виде массива; Просто используя ...
вы можете получить доступ к неограниченным переменным аргументам.
например:
<?php function sum(...$numbers) { $sum = 0; foreach ($numbers as $n) { $sum += $n; } return $sum ; } echo sum(1, 2, 3, 4, 5); ?>
Если вы используете PHP версию <= 5.5, вы можете получить неограниченный параметр, используя функции func_num_args () , func_get_arg () и func_get_args () .
Например:
<?php function foo() { $numargs = func_num_args(); echo "Number of arguments: $numargs \n"; if ($numargs >= 2) { echo "Second argument is: " . func_get_arg(1) . "\n"; } $arg_list = func_get_args(); for ($i = 0; $i < $numargs; $i++) { echo "Argument $i is: " . $arg_list[$i] . "\n"; } } foo(1, 2, 3); ?>
Существует функция func_get_args (), которая представляет собой массив всех аргументов, переданных функции.
Пример из PHP.net
function foo() { $numargs = func_num_args(); echo "Number of arguments: $numargs<br />\n"; if ($numargs >= 2) { echo "Second argument is: " . func_get_arg(1) . "<br />\n"; } $arg_list = func_get_args(); for ($i = 0; $i < $numargs; $i++) { echo "Argument $i is: " . $arg_list[$i] . "<br />\n"; } } foo(1, 2, 3);
Вышеприведенный пример выводит:
Количество аргументов: 3
Второй аргумент: 2
Аргумент 0: 1
Аргумент 1: 2
Аргумент 2: 3
Ответы с func_get_args () будут отлично работать для параметров без ссылки. Тем не менее, есть трюк, чтобы получить параметры сквозной ссылки для работы. Кроме того, это технически не функция, которая принимает неограниченные параметры, а просто какое-то сколь угодно большое число, скажем, сто.
Что вы можете сделать, это определить функцию, которая принимает большое количество аргументов и по умолчанию имеет значение null. Затем внутри этой функции добавьте каждую ненулевую ссылку на массив, который затем будет использоваться для вызова * bind_param () *, используя * call_user_func_array () *.
function my_bind_param(&$stmt, $types, &$arg1, &$arg2 = null, &$arg3 = null, ...) { $vars = array($types); $vars[] = $arg1; if ($arg2 != null) $vars[] = &$arg2; if ($arg3 != null) $vars[] = &$arg3; ... if (!call_user_func_array(array($stmt, "bind_param"), $vars)) { if ($stmt->errno == 0) return array(-1, "Unknown error binding parameters."); else return array(-1, "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error); } return array(0, ""); }
Настоящий трюк заключается в том, что вы не хотите писать эту штуку вручную. Просто создайте еще один скрипт, который выведет тело этой функции (все между скобками сглаживания) как * my_bind_param_body.php *. Затем просто определите заголовок функции в вашем основном файле и включите тело в это определение функции. т.е.
function my_bind_param(&$stmt, $types, &$arg1, &$arg2 = null, &$arg3 = null, ...) { return include "my_bind_param_wrapper_body.php"; }