216 Stimmen

Verwendung von Standardargumenten in einer Funktion

Ich bin verwirrt über Standardwerte für PHP-Funktionen. Angenommen, ich habe eine Funktion wie diese:

function foo($blah, $x = "some value", $y = "some other value") {
    // code here!
}

Was ist, wenn ich das Standardargument für $x verwenden möchte und ein anderes Argument für $y festlegen möchte?

Ich habe mit verschiedenen Möglichkeiten experimentiert und werde nur noch verwirrter. Zum Beispiel habe ich diese beiden versucht:

foo("blah", null, "test");
foo("blah", "", "test");

Aber bei beiden wird kein ordnungsgemäßes Standardargument für $x erzeugt. Ich habe auch versucht, es nach dem Variablennamen zu setzen.

foo("blah", $x, $y = "test");   

Ich hatte erwartet, dass so etwas funktioniert. Aber es funktioniert überhaupt nicht so, wie ich es erwartet habe. Es scheint, als ob ich, egal was ich tue, die Standardargumente beim Aufrufen der Funktion jedes Mal eingeben muss. Und ich muss etwas Offensichtliches übersehen.

214voto

drew010 Punkte 66884

Ich würde vorschlagen, die Funktionserklärung wie folgt zu ändern, damit du tun kannst, was du willst:

function foo($blah, $x = null, $y = null) {
    if (null === $x) {
        $x = "einiger Wert";
    }

    if (null === $y) {
        $y = "ein anderer Wert";
    }

    code hier!

}

Auf diese Weise kannst du einen Aufruf wie foo('blah', null, 'nicht standard y wert'); tätigen und es funktioniert so, wie du es möchtest, wobei der zweite Parameter $x immer noch seinen Standardwert erhält.

Mit dieser Methode bedeutet das Übergeben eines Nullwerts, dass Sie den Standardwert für einen Parameter möchten, wenn Sie den Standardwert für einen Parameter, der danach kommt, überschreiben möchten.

Wie in anderen Antworten angegeben,

Standardparameter funktionieren nur als letzte Argumente der Funktion. Wenn Sie die Standardwerte in der Funktionsdefinition deklarieren möchten, gibt es keine Möglichkeit, einen Parameter auszulassen und einen folgenden zu überschreiben.

Wenn ich eine Methode habe, die unterschiedliche Anzahlen von Parametern und Parameter von unterschiedlichen Typen akzeptieren kann, deklariere ich die Funktion oft ähnlich wie die Antwort von Ryan P. gezeigt.

Hier ist ein weiteres Beispiel (das beantwortet nicht deine Frage, soll aber hoffentlich informativ sein:

public function __construct($params = null)
{
    if ($params instanceof SOMETHING) {
        // einzelner Parameter, vom Typ Objekt SOMETHING
    } elseif (is_string($params)) {
        // einzelnes Argument als String übergeben
    } elseif (is_array($params)) {
        // params können ein Array von Eigenschaften sein wie array('x' => 'x1', 'y' => 'y1')
    } elseif (func_num_args() == 3) {
        $args = func_get_args();

        // 3 übergebene Parameter
    } elseif (func_num_args() == 5) {
        $args = func_get_args();
        // 5 übergebene Parameter
    } else {
        throw new \InvalidArgumentException("Konnte Parameter nicht ermitteln!");
    }
}

43voto

kitti Punkte 14422

Optionale Argumente funktionieren nur am Ende eines Funktionsaufrufs. Es gibt keine Möglichkeit, einen Wert für $ y in Ihrer Funktion anzugeben, ohne auch $ x anzugeben. Einige Sprachen unterstützen dies über benannte Parameter (zum Beispiel VB/C#), aber nicht PHP.

Sie können dies nachahmen, wenn Sie ein assoziatives Array für Parameter anstelle von Argumenten verwenden - d.h.

function foo(array $args = array()) {
    $x = !isset($args['x']) ? 'Standardwert x' : $args['x'];
    $y = !isset($args['y']) ? 'Standardwert y' : $args['y'];

    ...
}

Rufen Sie die Funktion dann wie folgt auf:

foo(array('y' => 'mein Wert'));

29voto

David Punkte 5800

Es ist tatsächlich möglich:

foo( 'blah', (new ReflectionFunction('foo'))->getParameters()[1]->getDefaultValue(), 'test');

Ob man das wirklich tun möchte, ist eine andere Geschichte :)


UPDATE:

Die Gründe, diese Lösung zu vermeiden, sind:

  • es ist (arguably) hässlich
  • es hat eine offensichtliche Overhead.
  • wie die anderen Antworten beweisen, gibt es Alternativen

Aber es kann tatsächlich nützlich sein in Situationen, wo:

  • man die Originalfunktion nicht ändern will/kann.

  • man die Funktion ändern könnte, aber:

    • die Verwendung von null (oder äquivalent) keine Option ist (siehe DiegoDD's Kommentar)
    • man auch weder mit einem assoziativen Array noch with func_num_args() gehen möchte
    • das Leben davon abhängt, ein paar LOCs zu sparen

In Bezug auf die Leistung zeigt ein sehr einfacher Test, dass die Verwendung der Reflection-API, um die Standardparameter zu erhalten, den Funktionsaufruf 25-mal langsamer macht, während es immer noch weniger als eine Mikrosekunde dauert. Du solltest wissen, ob du damit leben kannst.

Natürlich, wenn du beabsichtigst, es in einer Schleife zu verwenden, solltest du den Standardwert vorher erhalten.

10voto

zloctb Punkte 9390
function image(array $img)
{
    $defaults = array(
        'src'    => 'cow.png',
        'alt'    => 'Molkerei',
        'height' => 100,
        'width'  => 50
    );

    $img = array_merge($defaults, $img);
    /* ... */
}

6voto

AamirR Punkte 10468

PHP 8 mit benannten Argumenten

Was ist, wenn ich den Standardwert für das Argument $x verwenden und einen Wert für $y festlegen möchte? foo($blah, $x = "ein Wert", $y = "ein anderer Wert")

Verwendung-1:

foo(blah: "blah", y: "test");

Verwendung-2:

// Verwenden von Namen, um die letzten Argumente anzugeben
foo("blah", y: "test");

Auch native Funktionen werden diese Funktion nutzen

htmlspecialchars($string, double_encode: false);
// Das Gleiche wie
htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);

Über die Funktion und die Dokumentation

Benannte Argumente ermöglichen das Übergeben von Argumenten an eine Funktion basierend auf dem Parameternamen statt auf der Parameterposition. Dies macht die Bedeutung des Arguments selbstdokumentierend, macht die Argumente unabhängig von ihrer Reihenfolge und ermöglicht das willkürliche Überspringen von Standardwerten.

IDE-Unterstützung

Netbeans 12.3 unterstützt die Syntax von PHP 8.0 vollständig, einschließlich dieser Funktion, mit Ausnahme der Code-Vervollständigung für benannte Argumente.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X