İsteğe Bağlı Parametrelerle PHP İşlevi


107

10 parametre kabul edebilen bir PHP işlevi yazdım, ancak yalnızca 2 tane gerekli. Bazen sekizinci parametreyi tanımlamak istiyorum, ancak sekizinci değere ulaşana kadar her bir parametre için boş dizeler yazmak istemiyorum.

Aklıma gelen bir fikir, soyutlanmış bir işlevi, onu gerçek işleve geçiren bir dizi parametreyle geçirmekti.

Yalnızca istediğim parametreleri geçirebilmem için işlevi kurmanın daha iyi bir yolu var mı?



Bu garip. Php'deki yerleşik işlevler isteğe bağlı parametrelere sahip olabilir. Öyleyse neden böyle işlevler inşa edemiyoruz?
Rodrigo

2
O Not Bu yanıtlardan birçok OUTDATED edilir ... PHP şimdi destekler ile işlevlerini sayısı değişken listeleri .
ashleedawg

Yanıtlar:


62

Fonksiyonun bir parametre almasını sağlayın: bir dizi. Gerçek parametreleri dizideki değerler olarak geçirin.


Düzenleme: Pekka'nın yorumundaki bağlantı hemen hemen özetliyor.


1
Bu garip. Php'deki yerleşik işlevler isteğe bağlı parametrelere sahip olabilir. Öyleyse neden böyle işlevler inşa edemiyoruz?
Rodrigo

1
@Rodrigo, bunun gibi işlevleri tanımlamak kesinlikle yapılabilir. Yine de konumsal isteğe bağlıdırlar ve bu, tek bir isteğe bağlı parametrenin ötesinde herhangi bir şey için oldukça kötüdür.
Matt Ball

1
Tamam, [] ile deniyordum, şimdi nasıl yapılacağını burada görüyorum: stackoverflow.com/a/34869/1086511
Rodrigo

Sadece "bir dizi kullan" önerisinden daha fazlası yapılabilir - Walf'ın benzer bir soruya verdiği yanıta ve aynı başlıktaki daha ayrıntılı örneğe bir göz atın
DJDave

63

Bu durumda yaptığım şey, anahtarın parametre adı ve değerin değer olduğu bir dizi geçirmektir.

$optional = array(
  "param" => $param1,
  "param2" => $param2
);

function func($required, $requiredTwo, $optional) {
  if(isset($optional["param2"])) {
    doWork();
  }
}

Örneğiniz için, işlev içinde $ isteğe bağlı global olarak ayarlanması gerekmez mi?
user481826

1
küresel? Hayır..? Fonksiyonu çağırmadan önce bu diziyi yaratırsınız ve onu geçirirsiniz. Kodum, Matt Balls'un ne yapılması gerektiğine dair bir açıklama örneğidir.
Rabbott

Sadece "bir dizi kullan" önerilerinden daha fazlası yapılabilir - Walf'ın benzer bir soruya verdiği yanıta ve aynı başlıktaki daha ayrıntılı örneğe bir göz atın
DJDave

45

İstediğinizi başarmak için, Rabbot'un dediği gibi bir dizi kullanın (ancak bu, aşırı kullanılırsa belgelemek / sürdürmek için bir acıya dönüşebilir). Veya sadece geleneksel isteğe bağlı bağımsız değişkenleri kullanın.

//My function with tons of optional params
function my_func($req_a, $req_b, $opt_a = NULL, $opt_b = NULL, $opt_c = NULL)
{
  //Do stuff
}
my_func('Hi', 'World', null, null, 'Red');

Bununla birlikte, genellikle bu kadar çok argümanla bir işlev / yöntem yazmaya başladığımda - çoğu zaman bir kod kokusu olduğunu ve çok daha temiz bir şeye yeniden faktörlendirilebileceğini / soyutlanabileceğini buluyorum.

//Specialization of my_func - assuming my_func itself cannot be refactored
function my_color_func($reg_a, $reg_b, $opt = 'Red')
{
  return my_func($reg_a, $reg_b, null, null, $opt);
}
my_color_func('Hi', 'World');
my_color_func('Hello', 'Universe', 'Green');

2010'da, 'kod kokusu', 'yeniden düzenleme' veya 'kod bakımı' gibi kavramlar topluluğumuzda popüler değildi.
Çoğumuzun

15

PHP 5.6 ve sonrasında, bağımsız değişken listeleri, işlevin değişken sayıda bağımsız değişken kabul ettiğini belirtmek için ... belirtecini içerebilir. Argümanlar verilen değişkene bir dizi olarak aktarılacaktır; Örneğin:

Değişken argümanlarına erişmek için ... kullanma örneği

<?php
function sum(...$numbers) {
    $acc = 0;
    foreach ($numbers as $n) {
        $acc += $n;
    }
    return $acc;
}

echo sum(1, 2, 3, 4);
?>

Yukarıdaki örnekte çıktı:

10

Değişken uzunluklu bağımsız değişken, PHP Belgelerini listeler


Bu yanıt daha fazla puanı hak ediyor. Benim özel durum senaryom için uygun değil ama iyi bilgi ve anlaşılması kolay. PHP 7.3 yakında geliyor! 5.6 ve 7 EOL'dir.
AdheneManx

12

Varsayılan değeri null olarak ayarlayabilirsiniz.

<?php
function functionName($value, $value2 = null) {
// do stuff
}

2
En iyi yanıt, ancak lütfen nulltarih türünün bit olmayanları ile değiştirin . örneğin array()diziler için
Mohamed hesham

Teşekkürler ... Aradığım şey bu
Davide De Maestri

12

NOT: Bu eski bir cevaptır. PHP 5.5 ve altı . PHP 5.6+ varsayılan argümanları destekler

PHP 5.5 ve altında, aşağıdaki 2 yöntemden birini kullanarak bunu başarabilirsiniz:

  • kullanılarak (func_num_args) ve func_get_args () işlevleri;
  • NULL bağımsız değişkenler kullanarak;

Nasıl kullanılır

function method_1()
{
  $arg1 = (func_num_args() >= 1)? func_get_arg(0): "default_value_for_arg1";
  $arg2 = (func_num_args() >= 2)? func_get_arg(1): "default_value_for_arg2";
}

function method_2($arg1 = null, $arg2 = null)
{
  $arg1 = $arg1? $arg1: "default_value_for_arg1";
  $arg2 = $arg2? $arg2: "default_value_for_arg2";
}

Temiz ve anlaşılması kolay olduğu için ikinci yöntemi tercih ederim, ancak bazen ilk yönteme ihtiyacınız olabilir.


1
Burada "=" çiftine ihtiyacınız var, yoksa tüm ifadeler doğru olarak dönecektir. Ayrıca, 2. örnekteki ifadeler her zaman doğru döndürür çünkü bir değişken her zaman kendisine eşittir.
chuckieDub

iyi nokta, ama bu gerçekten işe yarıyor. PHP'de bu kod $x = null; if ($x) echo "true"; else echo "false";, $ x var bir değere sahip olsa bile (bu kodda "null") "false" yazacaktır. Ayrıca, her iki yöntemde de üçlü operatörü kullanıyoruz, bu nedenle doğru olarak yalnızca bir "=" kullanın. method(); method(1); method(1, 2);İle test ederseniz , ilk çağrı arg1 ve arg2'yi varsayılan değerlerle ilişkilendirir, ikinci çağrı ikinci argümanı varsayılan değerle ve birinci argüman için "1" ile ilişkilendirir. Son arama varsayılan değerleri ilişkilendirmeyecektir.
Daniel Loureiro

1
function method_2 ($ arg1 = "default_value_fot_arg1", $ arg2 = "default_value_fot_arg2") {bu yüzden php parametre maddeleri ile ilgilenir ve ayrıca parametre olarak null iletebilirsiniz (insanlar neden null kullanır bilmiyorum)
nerkn

1
@nerkn, haklısınız, PHP şu anda varsayılan argümanları destekliyor. Lol, basit şeyler başarmak için birçok geçici çözüm yapmamız gerektiğini hatırlıyorum. İyi zamanlar: P Yine de bu yaklaşımları eski kodlarda (5.5 öncesi) görebilirsiniz.
Daniel Loureiro

4

Bence nesneleri params-transportes olarak da kullanabilirsiniz.

$myParam = new stdClass();
$myParam->optParam2 = 'something';
$myParam->optParam8 = 3;
theFunction($myParam);

function theFunction($fparam){      
  return "I got ".$fparam->optParam8." of ".$fparam->optParam2." received!";
}

Elbette, bu işlevde "optParam8" ve "optParam2" için varsayılan değerleri ayarlamanız gerekir, diğer durumda "Not: Undefined property: stdClass :: $ optParam2" alırsınız.

Dizileri işlev parametreleri olarak kullanıyorsanız, varsayılan değerleri ayarlamak için şu yolu seviyorum:

function theFunction($fparam){
   $default = array(
      'opt1' => 'nothing',
      'opt2' => 1
   );
   if(is_array($fparam)){
      $fparam = array_merge($default, $fparam);
   }else{
      $fparam = $default;
   }
   //now, the default values are overwritten by these passed by $fparam
   return "I received ".$fparam['opt1']." and ".$fparam['opt2']."!";
}

2

Nesneyi geçerli bir duruma sahip oluşturmak için yalnızca iki değer gerekiyorsa, diğer tüm isteğe bağlı bağımsız değişkenleri kaldırabilir ve bunlar için ayarlayıcılar sağlayabilirsiniz (çalışma zamanında değiştirilmesini istemiyorsanız). Ardından, nesneyi gerekli iki bağımsız değişkenle somutlaştırın ve diğerlerini ayarlayıcı aracılığıyla gerektiği gibi ayarlayın.

daha fazla okuma


2

Bunun eski bir gönderi olduğunu biliyorum, ancak OP gibi bir sorun yaşıyordum ve bulduğum şey buydu.

Geçebileceğiniz dizi örneği. Belirli bir sipariş gerekiyorsa bunu yeniden sipariş edebilirsiniz, ancak bu soru için bu, isteneni yapacaktır.

$argument_set = array (8 => 'lots', 5 => 'of', 1 => 'data', 2 => 'here');

Bu yönetilebilir, okunması kolaydır ve veri çıkarma noktaları kodlamanın herhangi bir yerinde bir anda eklenebilir ve kaldırılabilir ve yine de büyük bir yeniden yazma işleminden kaçınabilir. OP orijinal sorusuyla hesaplamak için tamsayı anahtarları kullandım, ancak dize anahtarları da aynı şekilde kolayca kullanılabilir. Aslında okunabilirlik için tavsiye ederim.

Kolaylık için bunu harici bir dosyaya yapıştırın

function unknown_number_arguments($argument_set) {

    foreach ($argument_set as $key => $value) {

        # create a switch with all the cases you need. as you loop the array 
        # keys only your submitted $keys values will be found with the switch. 
        switch ($key) {
            case 1:
                # do stuff with $value
                break;
            case 2:
                # do stuff with $value;
                break;
            case 3:
                # key 3 omitted, this wont execute 
                break;
            case 5:
                # do stuff with $value;
                break;
            case 8:
                # do stuff with $value;
                break;
            default:
                # no match from the array, do error logging?
                break;
        }
    }
return;
}

dosya varsa bunu başına koyun.

$argument_set = array(); 

Bir sonraki veri parçasını, verilerin nereden geldiğine göre numaralandırma / adlandırma atamak için kullanın.

$argument_set[1][] = $some_variable; 

Ve sonunda diziyi geç

unknown_number_arguments($argument_set);

1
function yourFunction($var1, $var2, $optional = Null){
   ... code
}

Normal bir işlev yapabilir ve ardından isteğe bağlı değişkenlerinizi varsayılan bir Null değeri vererek ekleyebilirsiniz.

Bir Null hala bir değerdir, eğer işlevi o değişken için bir değerle çağırmazsanız, boş olmayacağından hata olmaz.


2
Daha fazlasını açıklayabilir misin? Değişken adları bir sayı ile başlayamaz olarak verilen kod sözdizimsel, geçersiz olduğu
Nico Haase

0

Genellikle sadece 8. değeri geçiyorsanız, parametrelerinizi ilk olacak şekilde yeniden sıralayabilirsiniz. Ayarlamak istediğiniz son parametreye kadar sadece parametreleri belirlemeniz gerekir.

Farklı değerler kullanıyorsanız, 2 seçeneğiniz vardır.

Bunlardan biri, farklı parametreler alan ve diğerlerinde varsayılanları ayarlayan bir dizi sarmalayıcı işlevi oluşturmak olabilir. Bu, yalnızca birkaç kombinasyon kullanıyorsanız kullanışlıdır, ancak çok hızlı bir şekilde dağınık olabilir.

Diğer seçenek, anahtarların parametrelerin adları olduğu bir dizi geçirmektir. Ardından, dizide anahtarlı bir değer olup olmadığını ve varsayılanı kullanmadığınızı kontrol edebilirsiniz. Ancak yine de, çok fazla parametreniz varsa, bu karmaşıklaşabilir ve çok fazla ekstra kod ekleyebilir.


0

PHP, varsayılan bağımsız değişkenlere ( bağlantı ) . Sizin durumunuzda, işlev kodunuza bağlı olarak 3'den 8'e kadar tüm parametreleri NULL veya boş bir dize "" olarak tanımlayabilirsiniz. Bu şekilde, işlevi yalnızca ilk iki parametreyi kullanarak çağırabilirsiniz.

Örneğin:

<?php
  function yourFunction($arg1, $arg2, $arg3=NULL, $arg4=NULL, $arg5=NULL, $arg6=NULL, $arg7=NULL, $arg8=NULL){
echo $arg1;
echo $arg2;
if(isset($arg3)){echo $arg3;}
# other similar statements for $arg4, ...., $arg5
if(isset($arg8)){echo $arg8;}
}

İlginç fikir ... ancak öneriniz sorunu çözmüyor. Aslında, hangi bağımsız değişkenin yankılandığına dair bilgi eklerseniz (örneğin kullanarak echo " this is arg3: " . $arg3;, vb., Örneğin çağrının yourFunction(3, 2, $arg8=5);yazdırılacağını görürsünüz 32 this is arg3: 5. Sorun şu ki, PHP ... parametre adlarında isteğe bağlı parametreleri iletirken parametre konumu hala önemlidir. parametre değerlerini parametre adlarına eşlemek için yeterli değildir .
mastropi

0

Kullanmak istemediğiniz parametreleri yok saymak için Null'u ayarlayın ve ardından gereken parametreyi konuma göre ayarlayın.

 function myFunc($p1,$p2,$p3=Null,$p4=Null,$p5=Null,$p6=Null,$p7=Null,$p8=Null){
    for ($i=1; $i<9; $i++){
        $varName = "p$i";
        if (isset($$varName)){
            echo $varName." = ".$$varName."<br>\n";
        }
    }
}   

myFunc( "1", "2", Null, Null, Null, Null, Null, "eight" );

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.