Impossibile passare l'argomento null quando si utilizza il tipo di suggerimento


193

Il seguente codice:

<?php

    class Type {

    }

    function foo(Type $t) {

    }

    foo(null);

?>

fallito in fase di esecuzione:

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

Perché non è consentito passare null come le altre lingue?

Risposte:


357

PHP 7.1 o versioni successive (rilasciato il 2 dicembre 2016)

È possibile dichiarare esplicitamente una variabile in base nulla questa sintassi

function foo(?Type $t) {
}

questo comporterà

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

Quindi, se si desidera un argomento facoltativo, è possibile seguire la convenzione, Type $t = nullmentre se è necessario fare in modo che un argomento accetti entrambinull e il suo tipo, è possibile seguire l'esempio sopra.

Puoi leggere di più qui .


PHP 7.0 o precedente

Devi aggiungere un valore predefinito come

function foo(Type $t = null) {

}

In questo modo, puoi passargli un valore nullo.

Questo è documentato nella sezione del manuale relativa alle dichiarazioni di tipo :

La dichiarazione può essere fatta per accettare NULLvalori se il valore predefinito del parametro è impostato su NULL.


10
Quindi perché null non è l' oggetto null ?
Pacerier,

4
La maggior parte delle lingue consente a null di avere qualsiasi tipo. In questo scenario.
Henry,

24
Secondo me questo è un costrutto linguistico scarso. 1. In altre lingue null ha la capacità di essere di qualsiasi tipo, rendendo così null un valido argomento in questo caso. 2: Php utilizza un valore predefinito per un argomento per specificare che è consentito null, questo è oscuro e rende impossibile un parametro obbligatorio anche se lo sviluppatore vuole forzare il passaggio esplicito di un null.
Henry,

2
Sono d'accordo con @Henry, inoltre sembra strano aver richiesto parametri dopo quello che sembra un parametro opzionale.
Force Hero

6
Sono d'accordo con @Henry solo su 2. Per quanto riguarda 1, il fatto che non si possa passare a null function foo(Type $t)è una cosa MOLTO buona; vedi riferimenti Null: L'errore di miliardi di dollari
Constantin Galbenu,

36

A partire da PHP 7.1, sono disponibili tipi nullable , sia come tipi di ritorno della funzione che parametri. Il tipo ?Tpuò avere valori del Tipo specificato To null.

Quindi, la tua funzione potrebbe apparire così:

function foo(?Type $t)
{

}

Non appena puoi lavorare con PHP 7.1, questa notazione dovrebbe essere preferita function foo(Type $t = null), perché costringe ancora il chiamante a specificare esplicitamente un argomento per il parametro $t.


12

Provare:

function foo(Type $t = null) {

}

Scopri gli argomenti della funzione PHP .


11
Il problema che ho con questo è che cambia la definizione della funzione. Ora il parametro è facoltativo, il che non è proprio quello che l'autore intendeva (anche se, se lo sta passando null, è implicitamente facoltativo).
schiaccia il

7

Come altre risposte già menzionate, questo è possibile solo se specificato null come valore predefinito.

Ma la soluzione orientata agli oggetti più pulita e sicura per i tipi sarebbe un 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)';
    }
}

Uso:

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

1
Questo approccio è spesso poco pratico, perché invece di 1 classe, ora è necessario 3. Inoltre, forza lo scrittore NullFooa scavalcare i metodi astratti, anche se non hanno significato (per definizione di null).
Operatore

1
Nella mia esperienza, il modello NullObject può essere pratico, se lavori in generale in modo OO molto rigoroso e classico. Nella risposta, imo il modello NullObject è un po 'abusato, in quanto è appositamente pensato per evitare i if (something is null)controlli, poiché NullObject è destinato a coprire tutto il comportamento di un valore inesistente e qualsiasi collaboratore esterno non dovrebbe essere interessato a se un l'oggetto è inesistente (null) o no.
Perso
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.