Подтвердить что ты не робот

Функция PHP с неограниченным количеством параметров

Как написать функцию, которая может принимать неограниченное количество параметров?

Что нужно сделать, так это создать функцию внутри класса, которая обертывает следующее:

$stmt->bind_param('sssd', $code, $language, $official, $percent);
4b9b3361

Ответ 1

Вышеприведенные предложения хороши, но я не думаю, что они будут подходящими для вашей ситуации.

$stmt->bind_param('sssd', $code, $language, $official, $percent);

Если вы хотите обернуть эту функцию, вам нужно будет передать ссылки на исходные переменные аргумента функции bind_param. Я не думаю, что func_get_args() дает вам это, он дает вам значения. Таким образом, невозможно будет использовать их для перехода к родительской функции. Я сражался с подобной проблемой, пытаясь расширить mysqli_stmt и никогда не получал удовлетворительного решения.

На самом деле это не ответ на ваш вопрос, я боюсь, просто предупреждение о том, что другие аргументы могут не работать в вашем конкретном приложении произвольного количества аргументов.

Ответ 2

Вы взглянули на 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, поскольку код, вероятно, более читабельный и, что более важно, менее вероятно, приведет к ошибкам из-за отсутствия переменной формата.

Ответ 3

Раньше вы должны были использовать func_get_args(), но в php 5.6 вы можете использовать ... operator.

Так, например, вы можете написать функцию, которая возвращает вам сумму всех чисел, отправленных функции:

function bind_param(...$params){
   var_dump($params);
}

Ваш params представляет собой массив всех элементов.

Ответ 4

Используйте func_get_args():

function my_func() {
  $args = func_get_args();
  foreach ($args as $arg) {
    echo "Arg: $arg\n";
  }
}

Ответ 5

В 5 параметрах этот дизайн начинает демонстрировать AntiPattern Слишком много параметров ". Это предполагает рефакторинг, называемый " Объект параметров ", объект или структура с элементами данных, представляющими аргументы, которые должны быть переданы. Однако избегайте создания a Magic Container.

См. также Внедрить объект параметров, рефакторинг на сайте refactoring.com.

Ответ 6

Если вы используете 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);
?>

Ответ 7

Существует функция, называемая 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

Ответ 8

Ответы с 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";
}