PHP-Funktion mit optionalen Parametern

107

Ich habe eine PHP-Funktion geschrieben, die 10 Parameter akzeptiert, aber nur 2 sind erforderlich. Manchmal möchte ich den achten Parameter definieren, aber ich möchte keine leeren Zeichenfolgen für jeden der Parameter eingeben, bis ich den achten erreicht habe.

Eine Idee, die ich hatte, war, eine abstrahierte Funktion mit einem Array von Parametern zu übergeben, die sie an die reale Funktion weitergibt.

Gibt es eine bessere Möglichkeit, die Funktion so einzurichten, dass ich nur die gewünschten Parameter übergeben kann?

user481826
quelle
4
Siehe auch
Pekka
Das ist seltsam. Integrierte Funktionen in PHP können optionale Parameter haben. Warum können wir solche Funktionen nicht erstellen?
Rodrigo
2
Beachten Sie, dass viele dieser Antworten veraltet sind ... PHP unterstützt jetzt Funktionen mit Argumentlisten mit variabler Länge .
Ashleedawg

Antworten:

62

Lassen Sie die Funktion einen Parameter annehmen: ein Array. Übergeben Sie die tatsächlichen Parameter als Werte im Array.


Bearbeiten: Der Link in Pekkas Kommentar fasst es fast zusammen.

Matt Ball
quelle
1
Das ist seltsam. Integrierte Funktionen in PHP können optionale Parameter haben. Warum können wir solche Funktionen nicht erstellen?
Rodrigo
1
@ Rodrigo es ist absolut machbar, Funktionen wie diese zu definieren. Sie sind jedoch positionell optional, was für alles, was über einen einzelnen optionalen Parameter hinausgeht, ziemlich mies ist.
Matt Ball
1
Ok, ich habe es mit [] versucht, jetzt sehe ich hier, wie es geht: stackoverflow.com/a/34869/1086511
Rodrigo
Es kann noch mehr getan werden, als nur den Vorschlag "Array verwenden" - werfen Sie einen Blick auf Walfs Antwort auf eine ähnliche Frage und das ausführlichere Beispiel im selben Thread
DJDave
63

In diesem Fall habe ich ein Array übergeben, wobei der Schlüssel der Parametername und der Wert der Wert ist.

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

function func($required, $requiredTwo, $optional) {
  if(isset($optional["param2"])) {
    doWork();
  }
}
Rabbott
quelle
Müsste in Ihrem Beispiel nicht $ optional innerhalb der Funktion global festgelegt werden?
user481826
1
global? Nein..? Sie erstellen dieses Array, bevor Sie die Funktion aufrufen, und übergeben es. Mein Code ist ein Beispiel für die Beschreibung von Matt Balls, was zu tun ist.
Rabbott
Es kann noch mehr getan werden, als nur die Vorschläge "Array verwenden" - werfen Sie einen Blick auf Walfs Antwort auf eine ähnliche Frage und das ausführlichere Beispiel im selben Thread
DJDave
45

Um das zu erreichen, was Sie wollen, verwenden Sie ein Array, wie Rabbot sagte (obwohl dies bei übermäßiger Verwendung zu einem Problem beim Dokumentieren / Verwalten werden kann). Oder verwenden Sie einfach die traditionellen optionalen Argumente.

//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');

Normalerweise stelle ich jedoch fest, dass wenn ich anfange, eine Funktion / Methode mit so vielen Argumenten zu schreiben - meistens handelt es sich um einen Codegeruch, der in etwas viel Saubereres umgewandelt / abstrahiert werden kann.

//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');
Kayla Rose
quelle
Im Jahr 2010 waren Begriffe wie "Codegeruch", "Refactoring" oder "Codepflege" in unserer Community nicht beliebt. Sie hatten einen Schritt vor den meisten von uns :)
Billal Begueradj
15

In PHP 5.6 und höher können Argumentlisten das Token ... enthalten, um anzuzeigen, dass die Funktion eine variable Anzahl von Argumenten akzeptiert. Die Argumente werden als Array an die angegebene Variable übergeben. beispielsweise:

Beispiel Verwenden von ..., um auf variable Argumente zuzugreifen

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

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

Das obige Beispiel gibt Folgendes aus:

10

Argument mit variabler Länge listet die PHP-Dokumentation auf

Mentos1386
quelle
Diese Antwort verdient mehr Punkte. Nicht für mein spezielles Szenario geeignet, aber gute Informationen und einfach zu verstehen. PHP 7.3 kommt in Kürze! 5.6 und 7 sind EOL.
AdheneManx
12

Sie können den Standardwert einfach auf null setzen.

<?php
function functionName($value, $value2 = null) {
// do stuff
}
Blake Stevenson
quelle
2
Die beste Antwort, aber bitte durch nulldie Nicht-Bits des Datumstyps ersetzen . Zum Beispiel array()für Arrays
Mohamed Hesham
Danke ... Das habe ich gesucht
Davide De Maestri
12

HINWEIS: Dies ist eine alte Antwort für PHP 5.5 und niedriger. PHP 5.6+ unterstützt Standardargumente

In PHP 5.5 und niedriger können Sie dies mit einer der beiden folgenden Methoden erreichen:

  • Verwenden der Funktionen func_num_args () und func_get_arg () ;
  • Verwenden von NULL-Argumenten;

Wie benutzt man

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

Ich bevorzuge die zweite Methode, weil sie sauber und leicht zu verstehen ist, aber manchmal benötigen Sie möglicherweise die erste Methode.

Daniel Loureiro
quelle
1
Sie benötigen hier das doppelte "=", sonst geben alle Ausdrücke true zurück. Außerdem geben die Ausdrücke im zweiten Beispiel immer true zurück, da eine Variable immer gleich sich selbst ist.
ChuckieDub
Guter Punkt, aber das funktioniert tatsächlich. In PHP gibt dieser Code $x = null; if ($x) echo "true"; else echo "false";"false" aus, auch wenn $ x var einen Wert hat ("null" in diesem Code). Außerdem verwenden wir in beiden Methoden den ternären Operator, sodass nur ein "=" verwendet wird. Wenn Sie mit testen method(); method(1); method(1, 2);, ordnet der erste Aufruf arg1 und arg2 den Standardwerten zu, der zweite Aufruf ordnet das zweite arg dem Standardwert und "1" für das erste Argument zu. Beim letzten Aufruf werden keine Standardwerte zugeordnet.
Daniel Loureiro
1
Funktion method_2 ($ arg1 = "default_value_fot_arg1", $ arg2 = "default_value_fot_arg2") {so php Deal mit dem Parameter Sachen und auch Sie können null als Parameter übergeben (warum Menschen null verwende ich weiß nicht)
nerkn
1
@nerkn, Sie haben Recht, PHP unterstützt derzeit Standardargumente. Lol, ich erinnere mich, als wir viele Problemumgehungen vornehmen mussten, um einfache Dinge zu erreichen. Gute Zeiten: P Sie können diese Ansätze jedoch immer noch in alten Codes (vor 5.5) sehen.
Daniel Loureiro
4

Ich denke, Sie können Objekte auch als Parameter-Transporte verwenden.

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

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

Natürlich müssen Sie in dieser Funktion Standardwerte für "optParam8" und "optParam2" festlegen. In anderen Fällen erhalten Sie "Hinweis: Undefinierte Eigenschaft: stdClass :: $ optParam2".

Wenn Sie Arrays als Funktionsparameter verwenden, möchte ich auf diese Weise Standardwerte festlegen:

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']."!";
}
psad
quelle
2

Wenn nur zwei Werte erforderlich sind, um das Objekt mit einem gültigen Status zu erstellen, können Sie einfach alle anderen optionalen Argumente entfernen und Setter für sie bereitstellen (es sei denn, Sie möchten nicht, dass sie zur Laufzeit geändert werden). Instanziieren Sie dann einfach das Objekt mit den beiden erforderlichen Argumenten und legen Sie die anderen nach Bedarf über den Setter fest.

Weiterführende Literatur

Gordon
quelle
2

Ich weiß, dass dies ein alter Beitrag ist, aber ich hatte ein Problem wie das OP und das habe ich mir ausgedacht.

Beispiel für ein Array, das Sie übergeben könnten. Sie können dies erneut bestellen, wenn eine bestimmte Bestellung erforderlich ist. Bei dieser Frage wird jedoch das getan, was gefragt wird.

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

Dies ist überschaubar, leicht zu lesen und die Datenextraktionspunkte können jederzeit an einer beliebigen Stelle in der Codierung hinzugefügt und entfernt werden, ohne dass ein massives Umschreiben erforderlich ist. Ich habe Ganzzahlschlüssel verwendet, um mit der ursprünglichen OP-Frage übereinzustimmen, aber Zeichenfolgenschlüssel konnten genauso einfach verwendet werden. In der Tat würde ich es aus Gründen der Lesbarkeit empfehlen.

Stecken Sie dies zur Vereinfachung in eine externe Datei

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

Setzen Sie dies am Anfang, wenn die Datei.

$argument_set = array(); 

Verwenden Sie diese einfach, um das nächste Datenelement zuzuweisen. Verwenden Sie die Nummerierung / Benennung entsprechend der Herkunft der Daten.

$argument_set[1][] = $some_variable; 

Und schließlich das Array übergeben

unknown_number_arguments($argument_set);
Chris
quelle
1
function yourFunction($var1, $var2, $optional = Null){
   ... code
}

Sie können eine reguläre Funktion erstellen und dann Ihre optionalen Variablen hinzufügen, indem Sie ihnen einen Standardwert von Null geben.

Eine Null ist immer noch ein Wert. Wenn Sie die Funktion nicht mit einem Wert für diese Variable aufrufen, ist sie nicht leer, also kein Fehler.

Antoine Serry
quelle
2
Können Sie das alles weiter erklären? Der angegebene Code ist syntaktisch ungültig, da Variablennamen nicht mit einer Zahl beginnen können
Nico Haase
0

Wenn Sie normalerweise nur den 8. Wert übergeben, können Sie Ihre Parameter neu anordnen, sodass dies der erste ist. Sie müssen nur Parameter bis zum letzten festlegen, den Sie einstellen möchten.

Wenn Sie unterschiedliche Werte verwenden, haben Sie zwei Möglichkeiten.

Eine Möglichkeit besteht darin, eine Reihe von Wrapper-Funktionen zu erstellen, die unterschiedliche Parameter verwenden und die Standardeinstellungen für die anderen festlegen. Dies ist nützlich, wenn Sie nur wenige Kombinationen verwenden, aber schnell sehr unordentlich werden können.

Die andere Option besteht darin, ein Array zu übergeben, in dem die Schlüssel die Namen der Parameter sind. Sie können dann einfach mit einem Schlüssel prüfen, ob das Array einen Wert enthält, und wenn nicht, den Standardwert verwenden. Aber auch dies kann chaotisch werden und viel zusätzlichen Code hinzufügen, wenn Sie viele Parameter haben.

Alan Geleynse
quelle
0

PHP erlaubt Standardargumente ( Link ). In Ihrem Fall können Sie alle Parameter von 3 bis 8 je nach Funktionscode als NULL oder als leere Zeichenfolge "" definieren. Auf diese Weise können Sie die Funktion nur mit den ersten beiden Parametern aufrufen.

Beispielsweise:

<?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;}
}
Andrés Luna
quelle
Interessante Idee ... aber Ihr Vorschlag löst das Problem nicht. Wenn Sie Informationen darüber hinzufügen, welches Argument wiedergegeben wird (z. B. mithilfe von echo " this is arg3: " . $arg3;usw.), wird der Aufruf z . B. yourFunction(3, 2, $arg8=5);gedruckt 32 this is arg3: 5. Das Problem besteht darin, dass die Parameterposition weiterhin wichtig ist, wenn optionale Parameter in PHP ... Parameternamen übergeben werden reichen nicht aus , um Parameterwerte Parameternamen
zuzuordnen
0

Setzen Sie einfach Null, um Parameter zu ignorieren, die Sie nicht verwenden möchten, und stellen Sie dann den erforderlichen Parameter entsprechend der Position ein.

 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" );
FERNANDO BARAZZETTI
quelle
-4
func( "1", "2", default, default, default, default, default, "eight" );
Flinsch
quelle
1
Dies ist kein gültiges PHP. defaultist ein Schlüsselwort in PHP .
Pang