Bei Verwendung von Typhinweisen kann kein Nullargument übergeben werden

190

Der folgende Code:

<?php

    class Type {

    }

    function foo(Type $t) {

    }

    foo(null);

?>

zur Laufzeit fehlgeschlagen:

PHP Fatal error:  Argument 1 passed to foo() must not be null

Warum darf nicht wie in anderen Sprachen null übergeben werden?

Abdullah
quelle

Antworten:

353

PHP 7.1 oder neuer (veröffentlicht am 2. Dezember 2016)

Sie können eine Variable explizit für nulldiese Syntax deklarieren

function foo(?Type $t) {
}

Dies führt zu

$this->foo(new Type()); // ok
$this->foo(null); // ok
$this->foo(); // error

Wenn Sie also ein optionales Argument wünschen, können Sie der Konvention folgen. Type $t = nullWenn Sie ein Argument dazu bringen müssen, beide nullund seinen Typ zu akzeptieren , können Sie dem obigen Beispiel folgen.

Sie können mehr lesen hier .


PHP 7.0 oder älter

Sie müssen einen Standardwert wie hinzufügen

function foo(Type $t = null) {

}

Auf diese Weise können Sie einen Nullwert übergeben.

Dies ist im Abschnitt im Handbuch über Typdeklarationen dokumentiert :

Die Deklaration kann so erfolgen, dass NULLWerte akzeptiert werden, wenn der Standardwert des Parameters auf gesetzt ist NULL.

DonCallisto
quelle
10
Warum ist null nicht das Null-Objekt ?
Pacerier
4
In den meisten Sprachen kann null einen beliebigen Typ haben. In diesem Szenario.
Henry
24
Meiner Meinung nach ist dies ein schlechtes Sprachkonstrukt. 1. In anderen Sprachen kann null von jedem Typ sein, wodurch null in diesem Fall zu einem gültigen Argument wird. 2: Php verwendet einen Standardwert für ein Argument, um anzugeben, dass null zulässig ist. Dies ist unklar und macht einen obligatorischen Parameter unmöglich, selbst wenn der Entwickler die explizite Übergabe einer Null erzwingen möchte.
Henry
2
Ich stimme @Henry zu, außerdem sieht es seltsam aus, nach einem optionalen Parameter erforderliche Parameter zu haben.
Force Hero
6
Ich stimme @Henry nur am 2. zu. In Bezug auf 1 ist die Tatsache, dass Sie nicht null übergeben können, function foo(Type $t)eine SEHR gute Sache; siehe Null Referenzen: Der Milliarden-Dollar-Fehler
Constantin Galbenu
35

Ab PHP 7.1 stehen nullfähige Typen als Funktionsrückgabetypen und Parameter zur Verfügung. Der Typ ?Tkann Werte des angegebenen Typs haben T, oder null.

Ihre Funktion könnte also folgendermaßen aussehen:

function foo(?Type $t)
{

}

Sobald Sie mit PHP 7.1 arbeiten können, sollte diese Notation vorgezogen werden function foo(Type $t = null), da der Aufrufer dennoch gezwungen ist, explizit ein Argument für den Parameter anzugeben $t.

TheOperator
quelle
12

Versuchen:

function foo(Type $t = null) {

}

Überprüfen Sie die Argumente der PHP-Funktion .

SeanWM
quelle
11
Das Problem, das ich damit habe, ist, dass es die Definition der Funktion ändert. Jetzt ist der Parameter optional - was nicht wirklich das ist, was der Autor beabsichtigt hat (obwohl er implizit optional ist, wenn er ihn null übergibt).
Crush
7

Wie bereits erwähnt, ist dies nur möglich, wenn Sie dies angeben null als Standardwert .

Die sauberste typsichere objektorientierte Lösung wäre jedoch ein NullObject :

interface FooInterface
{
    function bar();
}
class Foo implements FooInterface
{
    public function bar()
    {
        return 'i am an object';
    }
}
class NullFoo implements FooInterface
{
    public function bar()
    {
        return 'i am null (but you still can use my interface)';
    }
}

Verwendung:

function bar_my_foo(FooInterface $foo)
{
    if ($foo instanceof NullFoo) {
        // special handling of null values may go here
    }
    echo $foo->bar();
}

bar_my_foo(new NullFoo);
Fabian Schmengler
quelle
1
Dieser Ansatz ist oft unpraktisch, da Sie anstelle von 1 Klasse jetzt 3 benötigen. Außerdem wird der Verfasser NullFoogezwungen, abstrakte Methoden zu überschreiben, obwohl sie (per Definition von null) keine Bedeutung haben .
TheOperator
1
Nach meiner Erfahrung kann das NullObject-Muster praktisch sein, wenn Sie im Allgemeinen sehr streng und klassisch OO arbeiten. In der Antwort wird imo das NullObject-Muster etwas missbraucht, da es insbesondere dazu if (something is null)gedacht ist, Überprüfungen zu vermeiden , da das NullObject das gesamte Verhalten eines nicht vorhandenen Werts abdecken soll und kein externer Mitarbeiter daran interessiert sein sollte, ob ein Objekt ist nicht vorhanden (null) oder nicht.
verlor am