2009-10-16 19 views
16

Wie schreibe ich eine Funktion, die eine unbegrenzte Anzahl von Parametern akzeptieren kann?PHP-Funktion mit unbegrenzter Anzahl von Parametern

Was zu tun, ich versuche, ist eine Funktion innerhalb einer Klasse erstellen, die die folgenden Packungen:

$stmt->bind_param('sssd', $code, $language, $official, $percent); 
+0

Sie können es ohne mühselige Anstrengungen nicht. Ich würde vorschlagen, entweder eine übliche Abfrage zu erstellen, oder zu PDO wechseln, wenn Sie native vorbereitete Anweisungen um jeden Preis wollen. Sie haben bindValue, wohlgemerkt –

+0

Danke für die Info. Unglücklicherweise scheint PDO mit noch mehr Aufwand und Vorliebe übertrieben zu sein, verglichen mit dem Schreiben meiner eigenen einfachen Sachen. –

+0

Für die einfachen Sachen können Sie eine lib von meiner Benutzerinfo verwenden.Es ist wirklich einfach. –

Antwort

4

Die oben legt nahe, sind alle gut, aber ich glaube nicht, dass sie für Ihre Situation geeignet.

$stmt->bind_param('sssd', $code, $language, $official, $percent); 

Wenn Sie diese Funktion wickeln wollen, müssen Sie Referenzen auf die ursprünglichen Argumentvariablen auf die bind_param Funktion zu übergeben. Ich denke func_get_args() gibt dir das nicht, es gibt dir stattdessen Werte. Daher wird es nicht möglich sein, diese zu verwenden, um an die Elternfunktion zu übergeben. Ich habe mit einem ähnlichen Problem gekämpft, als ich versucht habe, mysqli_stmt zu erweitern und nie zu einer befriedigenden Lösung gekommen bin.

Dies ist nicht wirklich eine Antwort auf Ihre Frage, ich fürchte, nur eine Warnung, dass andere Argumente möglicherweise nicht in Ihrer bestimmten Anwendung einer beliebigen Anzahl von Argumenten funktionieren.

+1

In der Tat. Als ich das letzte Mal (vor 1+ Jahren) überprüfte, gab es keine Möglichkeit, 'bind_param()' einzubinden/zu erweitern, weil 'func_get_args()' keine Referenzen zurückliefert. –

23

Sie einen Blick auf func_get_args genommen, func_get_arg und func_num_args

So zum Beispiel:

function foo(){ 
    if (func_num_args() > 0){ 
     var_dump(func_get_args()); 
    } 
} 

oder:

function bind_param(){ 
    if (func_num_args() <= 1){ 
     return false; //not enough args 
    } 
    $format = func_get_arg(0) 
    $args = array_slice(func_get_args(), 1) 

    //etc 
} 

EDIT
Bezüglich Ewan Todds Kommentar:
Ich habe keine Kenntnissen auf der Basis API Sie den Wrapper für erstellen, aber eine weitere Alternative kann etwas mit Chaining-Funktionen, damit Ihre resultierende Schnittstelle Aussehen zu tun so etwas wie:

$var->bind()->bindString($code) 
      ->bindString($language) 
      ->bindString($official) 
      ->bindDecimal($percent); 

was ich über die Verwendung von func_get_args als Code bevorzugen würde, ist wahrscheinlich besser lesbar und was noch wichtiger ist weniger wahrscheinlich, dass Fehler aufgrund der das Fehlen einer Formatvariable verursachen.

+0

Ich benutze func_get_args von Zeit zu Zeit. Es macht es schwierig, auf einen Blick zu sehen, was die Eingaben der Methode sind. Plus, es führt einen Block von hässlich hässlicher Syntax in Ihren Code ein. Ich würde diesen Ansatz nur als letzten Ausweg empfehlen. Bevorzugen Sie das Refactoring des Parameterobjekts. –

+0

Ich stimme dir zu, dass es eine schlechte Art ist, variable Argumente zu machen. Ich habe eine alternative Idee zu meiner Antwort hinzugefügt – Yacoby

+0

Ich mag die "chaining Funktionen" Vorschlag besser als func_get_args. Ich kenne dieses Design als FLUENT-Schnittstelle. Dies wird erreicht, indem bindString(), bindDecimal() usw. "return $ this;" als ihre letzte Zeile. Die FLUENT-Schnittstelle ist eine großartige Option für bestimmte Fabriktypen. –

0

Es gibt eine Funktion namens func_get_args(), die ein Array aller an die Funktion übergebenen Argumente ist.

Beispiel aus PHP.net

function foo() 
{ 
    $numargs = func_num_args(); 
    echo "Number of arguments: $numargs<br />\n"; 
    if ($numargs >= 2) { 
     echo "Second argument is: " . func_get_arg(1) . "<br />\n"; 
    } 
    $arg_list = func_get_args(); 
    for ($i = 0; $i < $numargs; $i++) { 
     echo "Argument $i is: " . $arg_list[$i] . "<br />\n"; 
    } 
} 

foo(1, 2, 3); 

Das obige Beispiel wird ausgegeben:

Zahl der Argumente: 3
Zweites Argument ist: 2
Argument 0: 1
Argument 1 ist : 2
Argument 2 ist: 3

5

Verwendung func_get_args():

function my_func() { 
    $args = func_get_args(); 
    foreach ($args as $arg) { 
    echo "Arg: $arg\n"; 
    } 
} 
+0

Dies funktioniert nicht, wenn die Parameter nicht festgelegt sind und dann als Referenz übergeben werden, um in der Funktion festgelegt zu werden. func_get_args versucht auf die nicht gesetzte Variable zuzugreifen, die einen Fehler auslöst. – Danack

2

Bei 5 Parametern beginnt dieser Entwurf das Anti-Pattern "Too Many Parameters" zu zeigen.Dies deutet auf das Refactoring namens Parameter Object hin, ein Objekt oder eine Struktur mit Datenelementen, die die Argumente darstellen, die übergeben werden sollen. Vermeiden Sie es jedoch, es zu einem Magic Container zu machen.

Siehe auch Introduce Parameter Object Refactoring bei refactoring.com.

0

Die Antworten mit func_get_args() funktionieren gut für Nicht-Referenzparameter. Es gibt jedoch einen Trick, um Parameter für übergebene Referenz zu erhalten. Auch ist es technisch eine Funktion, die unbegrenzte Parameter akzeptiert, aber einfach irgendeine beliebig große Zahl, sagen wir einhundert.

Was Sie tun können, ist eine Funktion zu definieren, die eine große Anzahl von Argumenten akzeptiert und standardmäßig auf null setzt. Dann fügen Sie innerhalb dieser Funktion jede Nicht-NULL-Referenz an ein Array an, die dann verwendet wird, um * bind_param() * mit * call_user_func_array() * aufzurufen.

function my_bind_param(&$stmt, $types, &$arg1, &$arg2 = null, &$arg3 = null, ...) 
{ 
    $vars = array($types); 
    $vars[] = $arg1; 

    if ($arg2 != null) 
     $vars[] = &$arg2; 
    if ($arg3 != null) 
     $vars[] = &$arg3; 
    ... 

    if (!call_user_func_array(array($stmt, "bind_param"), $vars)) 
    { 
     if ($stmt->errno == 0) 
      return array(-1, "Unknown error binding parameters."); 
     else 
      return array(-1, "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error); 
    } 

    return array(0, ""); 
} 

Der eigentliche Trick ist, dass Sie dieses Ding nicht von Hand schreiben wollen. Machen Sie einfach ein anderes Skript, das den Körper dieser Funktion (alles zwischen den Squiggle-Klammern) als * my_bind_param_body.php * ausgeben wird. Definieren Sie dann einfach den Header der Funktion in Ihrer Hauptdatei und fügen Sie den Body in diese Funktionsdefinition ein. heißt

function my_bind_param(&$stmt, $types, &$arg1, &$arg2 = null, &$arg3 = null, ...) 
{ 
    return include "my_bind_param_wrapper_body.php"; 
} 
8

Zuvor sollten Sie func_get_args() verwendet haben, aber in der PHP 5.6, können Sie ... operator verwenden.

So zum Beispiel können Sie die Funktion schreiben, die Ihnen eine Summe aller Zahlen zurückgibt, an die Funktion gesendet:

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

Ihr params ist eigentlich ein Array aller Elemente.

2

Wenn Sie PHP 5.6 oder höher Version verwenden, Argument-Listen können die ... Token zu bezeichnen sind, dass die Funktion eine variable Anzahl von Argumenten akzeptiert. Die Argumente werden als Array an die angegebene Variable übergeben. Einfach mit ... können Sie auf unbegrenzte variable Argumente zugreifen.

zum Beispiel:

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

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

Wenn Sie mit PHP Version < = 5,5 dann können Sie unbegrenzt zugreifen parameterusing die func_num_args(), func_get_arg() und func_get_args() Funktionen.

Zum Beispiel:

<?php 
function foo() 
{ 
    $numargs = func_num_args(); 
    echo "Number of arguments: $numargs \n"; 
    if ($numargs >= 2) { 
     echo "Second argument is: " . func_get_arg(1) . "\n"; 
    } 
    $arg_list = func_get_args(); 
    for ($i = 0; $i < $numargs; $i++) { 
     echo "Argument $i is: " . $arg_list[$i] . "\n"; 
    } 
} 

foo(1, 2, 3); 
?> 
Verwandte Themen