Динамические функции, переменные входы

Прямо сейчас, скажем, у меня есть код, похожий на этот...

$some_var=returnsUserInput();

function funcA($a) {...}
function funcB($a,$b) {...}
function funcC($a,$b,$c) {...}

$list[functionA] = "funcA";
$list[functionB] = "funcB";
$list[functionC] = "funcC";

$temp_call = list[$some_var];

//Not sure how to do this below, just an example to show the idea of what I want.
$temp_call($varC1,varC2,$varC3);
$temp_call($varB1,varB2);
$temp_call($varA1);

Моя проблема начинается здесь, как я могу указать правильные переменные в аргументах в зависимости от них? У меня есть несколько мыслей, таких как создание списка для каждой функции, в которой они указаны, но мне бы очень хотелось увидеть элегантное решение для этого.


person Incognito    schedule 12.07.2010    source источник
comment
Как вы ожидаете, что funcC() будет обрабатывать вызов с одним аргументом?   -  person Ignacio Vazquez-Abrams    schedule 12.07.2010
comment
возможный дубликат Как может ли функция принимать неограниченное количество параметров в PHP?   -  person John Conde    schedule 12.07.2010
comment
@Igancio Вот о чем я спрашиваю. У меня есть логика для выбора каждой функции на основе другой логики, но я хочу иметь возможность назначать функцию и вызывать ее с правильными аргументами.   -  person Incognito    schedule 12.07.2010
comment
@ Джон Нет, я не об этом спрашиваю. У меня есть определенный набор данных из запроса, который я хочу передать определенным функциям (уже определенным в массиве), но я хочу иметь возможность создать функцию с переменным числом переменных, которая также динамически назначается и предоставляет определенные аргументы.   -  person Incognito    schedule 12.07.2010
comment
Я не понимаю вопрос. $temp_call($var, $var, $var) в PHP абсолютно нормально.   -  person NikiC    schedule 13.07.2010
comment
Будьте более конкретны в том, что у вас есть, чего вы хотите и как вы готовы к этому. Для начала, почему бы вам просто не сделать то, что вы сделали в своем примере кода?   -  person salathe    schedule 13.07.2010
comment
Это грязный способ делать что-то, однако я считаю, что он пытается создать систему, которая будет принимать любое количество аргументов и не выдавать ошибку. Итак, что-то вроде: ?func=functionA&varC1=test&varC2=test2 (конечно, если это вызывается для функции из этого массива, которая принимает только 1 параметр, тогда он получит сообщение об ошибке) Существует несколько вариантов, таких как func_get_args и передача массива вместо отдельных параметров.   -  person Kieran Allen    schedule 13.07.2010
comment
Нет, он не получит ошибку, если передаст слишком много аргументов. PHP выдает ошибку только в том случае, если он передает слишком мало аргументов.   -  person NikiC    schedule 13.07.2010
comment
@kieran это очень близко к тому, что я пытаюсь сделать. Это в основном централизованная страница для целей: масштабируемости, безопасности, удобства обслуживания... Коротким массивом значений можно легко манипулировать, как если бы это был файл конфигурации. Мне больше не нужно беспокоиться о том, как это работает в более крупной системе, если я могу сделать это очень динамичным. Причина, по которой я не опубликовал код, заключается в том, что он затрагивает слишком много других областей, таких как проверка ввода и очистка, а также то, как он связывается с более крупной системой входа в систему, группами безопасности и т. д.   -  person Incognito    schedule 13.07.2010


Ответы (3)


Вам нужно использовать call_user_func или call_user_func_array.

<?php
// if you know the parameters in advance.
call_user_func($temp_call, $varC1, $varC2);
// If you have an array of params.
call_user_func_array($temp_call, array($varB1, $varB2));
?>
person David Pratte    schedule 12.07.2010
comment
Это выглядит как шаг в правильном направлении. После того, как я поиграю с этим некоторое время, я дам вам знать. Спасибо. - person Incognito; 13.07.2010
comment
И, пожалуйста, не используйте call_user_func материал, если вы не вызываете метод динамически, потому что у него есть две проблемы: он может не пройти по ссылке и он медленный ;) - person NikiC; 13.07.2010
comment
Спасибо, я собираюсь использовать call_user_func_array, просто к вашему сведению. - person Incognito; 13.07.2010

Вы хотите что-то вроде следующего?

function test()
{
    $num_args   =   func_num_args();

    $args       =   func_get_args();

    switch ($num_args) {
        case 0:
            return 'none';
        break;


        case 1: 
            return $args[0];

        break;

        case 2:
            return $args[0] . ' - ' . $args[1];
        break;

        default:

            return implode($args, ' - ');
        break;
    }
}

echo test(); // 'none'
echo test(1); // 1
echo test(1, 2); // 1 - 2
echo test(1, 2, 3); // 1 - 2 - 3

Это будет своего рода методом делегирования.

Или как насчет того, чтобы просто принять массив, а не параметры?

function funcA($params) 
{
  extract($params);

  echo $a;
}

function funcB($params) 
{
  extract($params);

  echo $a, $b;
}

function funcC($params) 
{
  extract($params);

  echo $a, $b, $c;
}


$funcs = array('funcA', 'funcB', 'funcC');

$selected = $funcs[0];


$selected(array('a' => 'test', 'b' => 'test2'));

// or something like  (beware of security issues)
$selected($_GET);
person Kieran Allen    schedule 12.07.2010
comment
Нет, это 3 функции, а не 1. Все они делают очень разные вещи. - person Incognito; 13.07.2010
comment
Я думал о принятии массива, но мне пришлось бы изменить, вероятно, половину базы кода, чтобы заставить его работать с этим, а затем я решаю проблемы, когда у меня могут быть вариативные функции и т. д. - person Incognito; 13.07.2010

Вы не можете, и, может быть, это хорошо. Вы можете найти количество аргументов с помощью if/else.

if($temp_call == "funcA") { .....} elseif(...)...

person Stijn Leenknegt    schedule 12.07.2010
comment
Дело не в подсчете аргументов. Это не var1, var2 и var3. Это varA1, varA2, varA3 как серия, varB1, varB2 как серия и varC1 как отдельная серия. Я мог бы иметь VarQ1, varQ2 и super_duper в виде серии. - person Incognito; 13.07.2010