可変数の引数をPHP関数に渡す方法


115

可変数の引数をとるPHP関数があります(func_num_args()およびを使用func_get_args())が、関数に渡したい引数の数は配列の長さに依存します。可変数の引数でPHP関数を呼び出す方法はありますか?


1
新しいphp5.6のスプラット演算子について学ぶために私の答えを確認してください:stackoverflow.com/a/23163963/1090562
サルバドールダリ

回答:


132

配列に引数がある場合は、 call_user_func_array関数に。

渡す引数の数が配列の長さに依存する場合は、おそらくそれらを配列にパックして、その引数をの2番目のパラメーターに使用できることを意味します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つのパラメータ。関数がこのように呼び出されたのとまったく同じです:

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

1
はい、ありがとうございます。call_user_func_array()はまさに私が探していた関数です。
nohat

オブジェクトメソッドの呼び出しでcall_user_func_array()を使用することは可能ですか?
nohat

6
@nohat:どういたしまして:-) ;; オブジェクトのメソッドの使用について:はい、できます。array($ obj、 'methodName')のようなものを最初のパラメーターとして使用します;; 実際には、必要な「コールバック」をその関数に渡すことができます。コールバックの詳細については、php.net
Pascal MARTIN

58

これは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
ダニエレオーランド


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を正しく理解している場合、問題はパラメーターを受け取っていないが、可変数のパラメーターを使用して関数呼び出していることです。
パスカルマルタン

1
その時、私はOPを正しく理解していませんでした。それなら、アレイは間違いなく進むべき道でしょう。次に、彼は配列を直接test()に渡すことができますか?
ドニーC

1
実際、配列を渡すことも解決策になるかもしれません-もし私が正しく理解していれば^^
Pascal MARTIN

1
古い質問ですがfyi、配列は正常に機能しますが、実際の引数を渡すことにより、NULL引数にPHPのデフォルト値を使用できるため、配列に特定の値が含まれているかどうかを確認するための醜いチェックを大幅に省くことができます。
エンドファージ


1

古い質問ですが、ここでの回答はどれも、単に質問に答えるだけの良い仕事をするものではありません。

私はphpで遊んだところ、解決策は次のようになります。

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

この関数は2つのことを実行できます。

必要なパラメータのみで呼び出された場合:myFunction("Hi") 「Hi default」が出力されます

しかし、オプションのパラメーターを指定して呼び出された場合:myFunction("Hi","me") 「Hi me」と出力されます。

これが将来これを探しているすべての人に役立つことを願っています。


2
質問を理解できませんでした。OPは、関数のシグネチャで明示的に定義する必要のない引数について尋ねていましたが、関数への引数として値を渡すことができます。例えば、関数シグネチャは持っていない任意の引数(オプションかどうか)が定義され、彼は、それを必要とする場合、OPは、関数の引数として、45個の異なる値を送信することができます。
a20 18/04/02

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_arrayに2009年のトップ投票の回答で述べられているように使用しています。多分__invokeそれを余分にラップする意味があるかもしれません-私はそれを見ません。
a20
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.