Değişken sayıda bağımsız değişken bir PHP işlevine nasıl iletilir


115

Değişken sayıda argüman alan ( func_num_args()ve kullanarak func_get_args()) bir PHP fonksiyonum var , ancak fonksiyonu iletmek istediğim argümanların sayısı dizinin uzunluğuna bağlı. Değişken sayıda argüman içeren bir PHP işlevini çağırmanın bir yolu var mı ?


1
Yeni php5.6'da bir uyarma operatörü hakkında bilgi edinmek için cevabımı kontrol edin: stackoverflow.com/a/23163963/1090562
Salvador Dali

Yanıtlar:


132

Argümanlarınızı bir dizide tutarsanız, ilginizi çekebilir call_user_func_array fonksiyon .

İletmek istediğiniz bağımsız değişkenlerin sayısı bir dizinin uzunluğuna bağlıysa, bu muhtemelen onları bir diziye paketleyebileceğiniz ve bunu ikinci parametre için kullanabileceğiniz anlamına gelir. call_user_func_array .

Geçtiğiniz dizinin elemanları daha sonra işleviniz tarafından ayrı parametreler olarak alınacaktır.


Örneğin, bu işleve sahipseniz:

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

Parametrelerinizi aşağıdaki gibi bir diziye paketleyebilirsiniz:

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

Ve sonra işlevi çağırın:

call_user_func_array('test', $params);

Bu kod çıktı:

int 3

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

yani 3 parametre; tıpkı iof işlevinin bu şekilde adlandırılması gibi:

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

1
Evet teşekkür ederim. call_user_func_array () tam olarak aradığım işlev.
nohat

Call_user_func_array () işlevini bir nesne yöntemi çağrısıyla kullanmak mümkün müdür?
nohat

6
@nohat: rica ederim :-) ;; bir nesnenin yöntemini kullanma hakkında: evet, ilk parametre olarak array ($ obj, 'methodName') gibi bir şey kullanabilirsiniz ;; aslında, istediğiniz herhangi bir "geri aramayı" bu işleve iletebilirsiniz. Geri aramalar hakkında daha fazla bilgi için bkz. Php.net/callback#language.types.callback
Pascal MARTIN

58

Bu artık PHP 5.6.x ile mümkün ... operatörü kullanılarak (bazı dillerde splat operatörü olarak da bilinir):

Misal:

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
Yazılan Değişken parametreler listesi tanıtılan bir özelliktir PHP 7 .
Daniele Orlando

46

Yeni bir Php 5.6'da kullanmak ... operatoryerine kullanabilirsinizfunc_get_args() .

Yani, bunu kullanarak, geçirdiğiniz tüm parametreleri elde edebilirsiniz:

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

3
Daha fazla bilgi burada: php.net/manual/en/…
fracz

@Fracz bağlantısından, OP bir "değişken işlev" oluşturmaya çalışıyor.
Nathan Arthur

40

PHP 5.6'dan beri , ...operatörle bir değişken argüman listesi belirtilebilir .

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)
#> }

Gördüğünüz gibi, ...operatör bir dizideki değişken argüman listesini toplar.

Değişken bağımsız değişkenlerini başka bir işleve aktarmanız gerekirse ..., yine de size yardımcı olabilir.

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);
}

Yana PHP 7 , bağımsız değişken listesi olarak zorlanabilir tüm çok aynı türden.

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

11

Bunu yapmanın bir yolunu arayanlar için $object->method:

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

Değişken parametreli bir değişken yöntem_adı çağıran bir yapı işlevinde bununla başarılı oldum.


2
Ayrıca kullanabilirsiniz$object->method_name(...$array);
Yoann Kergall

Daha ileri gidersek, referansla geçmek istiyorsanız, şunu kullanın$object->method_name(&...$args);
Fabien Haddadi

4

Sadece arayabilirsin.

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

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

Çıktı:

Dizi ([0] => blah) Dizi ([0] => blah [1] => blah)


OP'yi doğru anlarsam, sorun parametreleri almak değil, değişken sayıda parametreli işlevi çağırmaktır .
Pascal MARTIN

1
O zaman OP'yi doğru anlamadım. Öyleyse, bir dizi kesinlikle gitmenin yolu olacaktır. Sonra tekrar, diziyi doğrudan test () 'e geçirebilir, değil mi?
Donnie C

1
Bir diziyi aktarmak da bir çözüm olabilir - Eğer doğru anladıysam ^^
Pascal MARTIN

1
Eski soru ama fyi, bir dizi iyi çalışıyor, ancak gerçek argümanlar için PHP'nin varsayılan değerlerini kullanmanıza izin veriyor, bu da dizinin belirli değerler içerip içermediğini görmek için çok sayıda çirkin denetimden kurtarıyor.
Endophage


1

Eski bir soru, biliyorum, ancak, buradaki cevapların hiçbiri soruyu cevaplamak için gerçekten iyi bir iş çıkarmıyor.

Sadece php ile oynadım ve çözüm şuna benziyor:

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

Bu işlev iki şey yapabilir:

Yalnızca gerekli parametre ile çağrılırsa: myFunction("Hi") "Hi default" yazdırır

Ancak isteğe bağlı parametre ile çağrılırsa: myFunction("Hi","me") "Merhaba ben" yazacaktır;

Umarım bu, yolda bunu arayan herkese yardımcı olur.


2
Soruyu anlamadın. OP, fonksiyon imzasında açıkça tanımlaması gerekmeyen argümanları soruyordu - yine de değerleri fonksiyona argümanlar olarak geçirebilir. Örneğin, fonksiyon imzasının tanımlanmış herhangi bir argümanı yoktur (isteğe bağlı olsun ya da olmasın), ancak bunu gerektirdiğinde OP fonksiyona argüman olarak 45 farklı değer gönderebilir.
a20

0

İşte __invoke sihirli yöntemini kullanan bir çözüm

(Php 5.3'ten beri mevcuttur)

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){

    }
}

Aynı sınıfın içinden:

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

Bir nesnenin örneğinden:

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

Bu, temelde call_user_func_array2009'da en çok oylanan cevapta belirtildiği gibi kullanılıyor . Belki __invokeetrafına fazladan bir şey koymanın bir anlamı olabilir - ama ben görmüyorum.
a20
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.