Как написать функцию, которая может принимать неограниченное количество параметров?
Что нужно сделать, так это создать функцию внутри класса, которая обертывает следующее:
$stmt->bind_param('sssd', $code, $language, $official, $percent);
Как написать функцию, которая может принимать неограниченное количество параметров?
Что нужно сделать, так это создать функцию внутри класса, которая обертывает следующее:
$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(), но в php 5.6 вы можете использовать ... operator.
Так, например, вы можете написать функцию, которая возвращает вам сумму всех чисел, отправленных функции:
function bind_param(...$params){
var_dump($params);
}
Ваш params представляет собой массив всех элементов.
Используйте func_get_args():
function my_func() {
$args = func_get_args();
foreach ($args as $arg) {
echo "Arg: $arg\n";
}
}
В 5 параметрах этот дизайн начинает демонстрировать AntiPattern Слишком много параметров ". Это предполагает рефакторинг, называемый " Объект параметров ", объект или структура с элементами данных, представляющими аргументы, которые должны быть переданы. Однако избегайте создания a 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, "");
}
Настоящий трюк заключается в том, что вы не хотите писать эту вещь вручную. Просто создайте еще один script, который выведет тело этой функции (все между скобками сглаживания) как * my_bind_param_body.php *. Затем просто определите заголовок функции в вашем основном файле и включите тело в это определение функции. то есть.
function my_bind_param(&$stmt, $types, &$arg1, &$arg2 = null, &$arg3 = null, ...)
{
return include "my_bind_param_wrapper_body.php";
}