Bir Diziyi PHP'de Dizi olarak Değil Bağımsız Değişkenler Olarak Aktarma


151

PHP'de bir diziyi bir işlev için bir argüman listesi olarak geçirmenin, diziyi standart func($arg1, $arg2)biçime aktarmanın bir yolu olduğunu hatırlıyorum . Ama şimdi nasıl yapılacağı konusunda kayboldum. Gönderime göre geçirme şeklini, gelen parametrelerin nasıl "glob" yapılacağını hatırlıyorum ... ama diziyi bir argüman listesine nasıl listeden çıkaracağımı hatırlamıyorum.

Bu kadar basit olabilir func(&$myArgs), ama eminim öyle değil. Ancak ne yazık ki php.net kılavuzu şu ana kadar hiçbir şeyi açıklamadı. Bu özelliği son bir yıldır kullanmak zorunda olduğumdan değil.

Yanıtlar:


182

1
Bir önek karakteri gibi işlevsiz olduğuna da yemin edebilirdim. Teşekkürler.
Robert K

8
Ama Python bilmiyorum! Yanlışlıkla psişik olmalıyım ...: D
Robert K

46
Paket açma argümanı adı verilen argüman PHP 5.6'ya eklenecektir ( wiki.php.net/rfc/argument_unpacking ). 'Uyarıcı operatör': '...' kullanacaktır. Sözdizimi: $args = [1,2,3]; function(...$args){}
arothuis

4
ama ya çağırmak istediğiniz işlev, global uzaydaki bir işlev adı değil, nesne üzerindeki bir örnek yöntemse?
ahnbizcad

6
@ahnbizcad daha sonra callable, aynı şeyi kullanan call_user_func_array, yalnızca ilk öğenin nesne ve ikinci öğenin yöntem olduğu dizi ile kullanmalısınız . Örneğincall_user_func_array([$object, 'method'], $myArgs);
SteveB

154

Belirtildiği gibi, PHP 5.6+ itibariyle, bir dizi bağımsız değişkenle bir işlevi kolayca çağırmak için ...belirteci ("splat operatörü" olarak da bilinir, değişken işlevlerin bir parçası olarak ) kullanabilirsiniz (gerekir!) :

<?php
function variadic($arg1, $arg2)
{
    // Do stuff
    echo $arg1.' '.$arg2;
}

$array = ['Hello', 'World'];

// 'Splat' the $array in the function call
variadic(...$array);

// 'Hello World'

Not: dizi öğeleri, anahtarlarına göre değil dizideki konumlarına göre bağımsız değişkenlere eşlenir .

Gereğince CarlosCarucce yorumuyla , argüman veri açma bu formu arayla en hızlı yöntemdir her durumda. Bazı karşılaştırmalarda 5 kattan daha hızlıdır call_user_func_array.

Bir yana

Çünkü bunun gerçekten yararlı olduğunu düşünüyorum (soruyla doğrudan ilgili olmasa da): aktarılan tüm değerlerin belirli bir türle eşleştiğinden emin olmak için işlev tanımınızda splat operatör parametresini yazabilirsiniz.

(Bunu yapmanın , tanımladığınız son parametre OLMALIDIR ve işleve aktarılan tüm parametreleri diziye paketlediğini unutmayın.)

Bu, bir dizinin belirli bir türden öğeler içerdiğinden emin olmak için harikadır:

<?php

// Define the function...

function variadic($var, SomeClass ...$items)
{
    // $items will be an array of objects of type `SomeClass`
}

// Then you can call...

variadic('Hello', new SomeClass, new SomeClass);

// or even splat both ways

$items = [
    new SomeClass,
    new SomeClass,
];

variadic('Hello', ...$items);

7
Bunun üzerinde büyük bir performans artışı var call_user_func_array. Yani php 5.6+ kullanıyorsanız bunu tavsiye ederim. İşte resmi php
wiki'de

2
Bu işaretli cevap olmaması gerçekten talihsizlik. Kesinlikle daha iyi
affedilmeyen1987

Bu gerçekten işaretli cevaptan daha iyi bir cevaptır, ancak dürüst olmak gerekirse, soru genel olarak PHP hakkındadır, PHP 5.6 veya daha yenisi ile ilgili değildir ve call_user_func_array PHP'nin tüm sürümlerinde çalışır. Bu cevabı oyladım.
PHP Guru

82

Ayrıca, bir diziye örnek yöntemi uygulamak istiyorsanız, işlevi şu şekilde iletmeniz gerektiğini unutmayın:

call_user_func_array(array($instance, "MethodName"), $myArgs);

4
@understack Bağlantılı sayfadaki$foo->bar() örnek, olması gerektiğini gösteriyor . array($instance, "MethodName")
Paul Calcraft

11
Harika, bunu bir alt sınıfta yapıcı argümanlarını kopyalamaktan kaçınmak için kullandım :)call_user_func_array(array(parent, "__construct"), func_get_args());
Jason

10

Eksiksizlik adına, PHP 5.1'den itibaren bu da çalışır:

<?php
function title($title, $name) {
    return sprintf("%s. %s\r\n", $title, $name);
}
$function = new ReflectionFunction('title');
$myArray = array('Dr', 'Phil');
echo $function->invokeArgs($myArray);  // prints "Dr. Phil"
?>

Bakınız: http://php.net/reflectionfunction.invokeargs

Yöntemler için bunun yerine ReflectionMethod :: invokeArgs kullanırsınız ve nesneyi ilk parametre olarak iletirsiniz.


Aslında aradığım şey bu!
Dejv
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.