가변 개수의 인수를 PHP 함수에 전달하는 방법


115

가변 개수의 인수 ( func_num_args()및 사용 func_get_args())를 받는 PHP 함수가 있지만 함수를 전달하려는 인수의 수는 배열의 길이에 따라 다릅니다. 가변 개수의 인수로 PHP 함수 를 호출 하는 방법이 있습니까?


1
새 php5.6의 splat 연산자에 대해 알아 보려면 내 대답을 확인하십시오. stackoverflow.com/a/23163963/1090562
Salvador Dali

답변:


132

배열에 인수가있는 경우 call_user_func_array함수에 관심이있을 수 있습니다 .

전달하려는 인수의 수가 배열의 길이에 따라 달라진다면 아마도 배열 자체로 압축하여의 두 번째 매개 변수에 사용할 수 있음을 의미 할 것입니다 call_user_func_array.

전달한 배열의 요소는 함수에서 고유 한 매개 변수로 수신됩니다.


예를 들어이 기능이있는 경우 :

function test() {
  var_dump(func_num_args());
  var_dump(func_get_args());
}

다음과 같이 매개 변수를 배열로 압축 할 수 있습니다.

$params = array(
  10,
  'glop',
  'test',
);

그런 다음 함수를 호출합니다.

call_user_func_array('test', $params);

이 코드는 다음을 출력합니다.

int 3

array
  0 => int 10
  1 => string 'glop' (length=4)
  2 => string 'test' (length=4)

즉, 3 개의 매개 변수; iof 함수가 다음과 같이 호출 된 것과 똑같습니다.

test(10, 'glop', 'test');

1
네 감사합니다. call_user_func_array ()는 정확히 제가 찾고 있던 함수입니다.
nohat

객체 메서드 호출과 함께 call_user_func_array ()를 사용할 수 있습니까?
nohat

6
@nohat : 천만에요 :-) ;; 객체의 메서드를 사용하는 방법 : 예, 가능합니다. array ($ obj, 'methodName') 같은 것을 첫 번째 매개 변수로 사용할 수 있습니다. ;; 실제로 원하는 "콜백"을 해당 함수에 전달할 수 있습니다. 콜백에 대한 더 자세한 내용을 참조 php.net/callback#language.types.callback
파스칼 MARTIN

58

이제 ... 연산자 (일부 언어에서는 splat 연산자라고도 함)를 사용하여 PHP 5.6.x 에서 가능합니다 .

예:

function addDateIntervalsToDateTime( DateTime $dt, DateInterval ...$intervals )
{
    foreach ( $intervals as $interval ) {
        $dt->add( $interval );
    }
    return $dt;
}

addDateIntervaslToDateTime( new DateTime, new DateInterval( 'P1D' ), 
        new DateInterval( 'P4D' ), new DateInterval( 'P10D' ) );

1
입력 변수 인수 목록에 도입 된 기능입니다 PHP 7 .
Daniele Orlando

46

새로운에서 PHP는 5.6 , 당신이 사용할 수있는 ... operator사용하는 대신 func_get_args().

따라서 이것을 사용하여 전달하는 모든 매개 변수를 얻을 수 있습니다.

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

3
여기에 더 많은 정보 : php.net/manual/en/...
fracz

@fracz 링크에서 OP는 "가변 함수"를 만들려고합니다.
나단 아서

40

PHP 5.6 부터는 변수 인자 목록을 ...연산자 로 지정할 수 있습니다 .

function do_something($first, ...$all_the_others)
{
    var_dump($first);
    var_dump($all_the_others);
}

do_something('this goes in first', 2, 3, 4, 5);

#> string(18) "this goes in first"
#>
#> array(4) {
#>   [0]=>
#>   int(2)
#>   [1]=>
#>   int(3)
#>   [2]=>
#>   int(4)
#>   [3]=>
#>   int(5)
#> }

보시다시피 ...연산자는 배열에서 인수의 변수 목록을 수집합니다.

변수 인수를 다른 함수에 전달해야하는 경우 ...에도는 여전히 도움이 될 수 있습니다.

function do_something($first, ...$all_the_others)
{
    do_something_else($first, ...$all_the_others);
    // Which is translated to:
    // do_something_else('this goes in first', 2, 3, 4, 5);
}

PHP 7 부터 , 인자의 변수 목록도 모두 같은 유형이 되도록 강제 할 수 있습니다.

function do_something($first, int ...$all_the_others) { /**/ }

11

이 작업을 수행하는 방법을 찾는 사람들을 위해 $object->method:

call_user_func_array(array($object, 'method_name'), $array);

변수 매개 변수를 사용하여 변수 method_name을 호출하는 구성 함수에서 성공했습니다.


2
당신은 또한 사용할 수 있습니다$object->method_name(...$array);
Yoann Kergall

사용, 참조로 전달하려면, 더 나아가$object->method_name(&...$args);
파비앙 Haddadi

4

그냥 부를 수 있습니다.

function test(){        
     print_r(func_get_args());
}

test("blah");
test("blah","blah");

산출:

어레이 ([0] => blah) 어레이 ([0] => blah [1] => blah)


OP를 올바르게 이해하면 문제는 매개 변수를 수신하지 않고 가변 개수의 매개 변수로 함수호출하는 것 입니다.
Pascal MARTIN

1
그렇다면 OP를 올바르게 이해하지 못했습니다. 그렇다면 배열은 확실히 갈 길일 것입니다. 그런 다음 다시 배열을 test ()에 직접 전달할 수 있습니다.
Donnie C

1
배열을 전달하는 것도 해결책이 될 수 있습니다.-내가 올바르게 이해했다면 ^^
Pascal MARTIN

1
오래된 질문이지만 배열은 잘 작동하지만 실제 인수를 전달하면 배열에 특정 값이 포함되어 있는지 확인하기 위해 많은 추악한 검사를 절약하는 널 인수에 대해 PHP의 기본값을 사용할 수 있습니다.
Endophage 2011 년


1

오래된 질문이지만 여기에있는 답변 중 어느 것도 단순히 질문에 대한 답변을 제대로 수행하지 못합니다.

방금 PHP로 놀았고 해결책은 다음과 같습니다.

function myFunction($requiredArgument, $optionalArgument = "default"){
   echo $requiredArgument . $optionalArgument;
}

이 함수는 두 가지 작업을 수행 할 수 있습니다.

필수 매개 변수 만 사용하여 호출하는 경우 : myFunction("Hi") "Hi default"를 인쇄합니다.

그러나 선택적 매개 변수로 호출 myFunction("Hi","me") 하면 "Hi me"가 인쇄됩니다.

나는 이것이 길 아래에서 이것을 찾는 모든 사람에게 도움이되기를 바랍니다.


2
당신은 질문을 이해하지 못했습니다. OP는 함수 시그니처 에 명시 적으로 정의 할 필요가없는 인수에 대해 질문 했지만 여전히 값을 함수에 인수로 전달할 수 있습니다. 예를 들어, 함수 서명이없는 모든 인수 (선택 사항 여부) 정의,하지만 그는을 필요로하는 경우, 영업 이익은 함수에 인수로 45 개 다른 값을 보낼 수 있습니다.
a20

0

다음은 매직 메서드 __invoke를 사용하는 솔루션입니다.

(php 5.3부터 사용 가능)

class Foo {
    public function __invoke($method=null, $args=[]){
        if($method){
            return call_user_func_array([$this, $method], $args);
        }
        return false;
    }

    public function methodName($arg1, $arg2, $arg3){

    }
}

같은 클래스 내부에서 :

$this('methodName', ['arg1', 'arg2', 'arg3']);

개체의 인스턴스에서 :

$obj = new Foo;
$obj('methodName', ['arg1', 'arg2', 'arg3'])

이것은 기본적으로 call_user_func_array2009 년 최우수 투표 답변에서 언급 한대로 사용 하고 있습니다. 아마도 그 __invoke주위를 추가로 감싸 야 할 요점이있을 수 있습니다. 그러나 나는 그것을 보지 못합니다.
a20
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.