2013-12-06 3 views
0
Class Base { 
    function processAction($methodName, $params) { 
    call_user_func_array(array($this,$methodName), $params); 

    } 
} 

class Child1 extends Base { 
    function getData($param1, $param2, $timestamp) {} 
} 

class Child2 extends Base { 
    function getInfo($param1) {} 
} 

Я буду вызывать processAction для вызова методов дочерних классов.Как использовать call_user_func_array для необязательных параметров

У меня есть несколько дочерних классов с различными сигнатурами методов. Я хочу передать $ timestamp некоторым из них. Проблема в том, что я не хочу делать timestamp необязательным параметром для методов, которые не требуют. Я хочу иметь возможность передавать в методе $ timestamp только соответствующие методы. Как я это сделаю?

EDIT Я планирую добавить $ timestamp непосредственно перед вызовом cal_user_func_array().

$array_push($params, $timestamp); 

Но это означало бы, что каждый метод ожидал бы $ timestamp, чего я не хочу.

+1

Я не уверен, что понимаю, чего вы хотите.вы говорите, что хотите, чтобы вы выбрали исключение или что-то подобное, если, например, вы пытаетесь вызвать 'getInfo()' с более чем 1 arg? –

+0

, например, ваш метод 'Child2 :: getInfo' имеет один параметр' $ param1'. Если бы вы сделали это: 'Child2 :: getInfo ('foo', 'bar');', он просто проигнорировал бы этот второй параметр. Это не похоже на c/C++, где он должен соответствовать сигнатуре. Поэтому мой предыдущий вопрос о том, хотите ли вы бросить исключение, если вы * сделаете * передать дополнительные аргументы, что метод будет просто игнорировать иначе –

+0

Мне не нужно бросать исключение. Позвольте мне попробовать. Если это то, что вы говорите, я закрою этот вопрос. Спасибо – kushan85

ответ

4

Как упоминалось в моих комментариях, php заботится только о том, чтобы вы передали достаточно аргументов, чтобы соответствовать количеству объявленных параметров. Если вы устанавливаете значение по умолчанию для параметра, то это даже не заботится об этом.

Функция «игнорирует» любые дополнительные параметры, которые вы передаете ей, в том смысле, что php не заботится и не будет вызывать ошибку. Однако обратите внимание, что любые дополнительные аргументы, переданные вашей функции , являются, которые подвергаются функции. Например, вы можете использовать func_get_args(), чтобы получить массив значений, переданных функции, независимо от того, сколько параметров было фактически объявлено.

Пример 1:

function myFunc() {} 
myFunc(); // good 
myfunc('foo'); // good 

Пример 2:

function myFunc($p1) {} 
myFunc(); // bad 
myfunc('foo'); // good 
myfunc('foo','bar'); // good 

Пример 3:

function myFunc($p1='') {} 
myFunc(); // good 
myfunc('foo'); // good 

Пример 4:

function myFunc() { 
    print_r(func_get_args()); 
} 
myFunc('foo','bar'); 
/*output: 
Array 
(
    [0] => foo 
    [1] => bar 
) 
*/ 

Теперь, скажем, для чертовых и усмехается вы на самом деле хотите обеспечить только прохождение соответствующей арг к методам. Существует несколько способов обеспечения этого, в зависимости от того, что вы в конечном итоге хотите сделать. Если вы хотите сделать так, чтобы именованные аргументы были переданы, вам придется перестроить свой код, чтобы принять ассоциативный массив параметров. Затем вы можете написать некоторые условия, чтобы выяснить, какие из них были переданы, передать их или выбросить исключение или что-то еще. Если вас интересует только количество аргументов, это будет проще, потому что вы можете более или менее оставить свою структуру кода as-is и подсчитать количество переданных параметров.

Теперь, насколько важно выяснить, сколько параметров имеет данный метод. Ниже приведен пример использования класса Reflection, чтобы направить вас в правильном направлении:

Class Base { 
    function processAction($methodName, $params) { 

    // setup a reflection method object 
    $refMeth = new ReflectionMethod(get_class($this).'::'.$methodName); 

    // get a list of the parameter names, if you want to go the 'named' route 
    foreach($refMeth->getParameters() as $param) { 
     $sigParams[] = $param->getName(); 
    } 

    // echo out as example 
    print_r($sigParams); 
    // or just get the number of params for the method 
    echo $refMeth->getNumberOfParameters(); 

    call_user_func_array(array($this,$methodName), $params); 

    } 
} 

class Child1 extends Base { 
    function getData($param1, $param2, $timestamp) {} 
} 

class Child2 extends Base { 
    function getInfo($param1) {} 
} 

// example: 
$x = new Child1(); 
$x->processAction('getData',array('foo','bar','12345')); 

/*output 
Array 
(
    [0] => param1 
    [1] => param2 
    [2] => timestamp 
) 
3 
*/ 

Таким образом, есть пример того, как выяснить ожидаемый Params для данного метода, так что вы можете сравнить прошла арг и явный вызов call_user_func_array с только соответствующими значениями, чтобы дополнительные функции (даже если php «игнорировали» их) даже не будут отображаться, или вместо этого исключают исключение и т. Д.

+0

Это имеет смысл. Спасибо, что объяснили это примерами. Я собираюсь отметить это как правильный ответ – kushan85

Смежные вопросы