Неможливо передати нульовий аргумент при використанні підказки типу


193

Наступний код:

<?php

    class Type {

    }

    function foo(Type $t) {

    }

    foo(null);

?>

не вдалося виконати час:

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

Чому заборонено пропускати null так само, як і інші мови?

Відповіді:


357

PHP 7.1 або новішої версії (випущено 2 грудня 2016 року)

Ви можете явно оголосити змінну nullтакою синтаксисом

function foo(?Type $t) {
}

це призведе до

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

Отже, якщо ви хочете необов'язковий аргумент, ви можете слідувати умові, Type $t = nullтоді як якщо вам потрібно зробити аргумент, прийміть і те, і іншеnull і його тип, ви можете слідувати вищенаведеному прикладу.

Більше ви можете прочитати тут .


PHP 7.0 або новіші

Ви повинні додати значення за замовчуванням, як-от

function foo(Type $t = null) {

}

Таким чином, ви можете передати це нульове значення.

Це задокументоване у розділі посібника про Декларації типів :

Декларація може бути прийнята для прийняття NULLзначень, якщо для параметра за замовчуванням встановлено значення NULL.


10
То чому ж не є нульовим об’єктом ?
Pacerier

4
Більшість мов дозволяють нулю мати будь-який тип. У цьому сценарії.
Генрі

24
На мою думку, це погана мовна конструкція. 1. В інших мовах null має можливість будь-якого типу, таким чином робить null вагомим аргументом у цьому випадку. 2: Php використовує значення аргументу за замовчуванням для аргументу, щоб вказати, що нуль допустимий, це незрозуміло і це робить обов'язковий параметр неможливим, навіть якщо розробник хоче примусити нуль бути явно переданим.
Генрі

2
Я погоджуюся з @Henry, окрім того, дивно виглядає необхідна парами після того, як це виглядає як необов'язковий парам.
Герой сили

6
Я погоджуюся з @Henry лише 2. Що стосується 1, той факт, що ви не можете передати null function foo(Type $t), це ДУЖЕ хороша річ; див. Null References: Помилка
мільярду

36

Починаючи з PHP 7.1, доступні зведені типи , як обидва, так і параметри повернення. Тип ?Tможе мати значення вказаного типу T, або null.

Отже, ваша функція може виглядати приблизно так:

function foo(?Type $t)
{

}

Як тільки ви зможете працювати з PHP 7.1, це позначення слід function foo(Type $t = null)віддати перевагу , оскільки воно все ж змушує абонента чітко вказати аргумент для параметра $t.


12

Спробуйте:

function foo(Type $t = null) {

}

Перевірте аргументи функції PHP .


11
Проблема, яку я маю з цим, полягає в тому, що вона змінює визначення функції. Тепер параметр є необов’язковим - що насправді не те, що автор задумав (хоча, якщо він передає його нульовим, він неявно необов’язковий).
розчавити

7

Як і інші відповіді, про які вже говорилося, це можливо лише в тому випадку, якщо ви вказали null як значення за замовчуванням.

Але найчистішим безпечним для об'єктів орієнтованим на рішення рішенням буде 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)';
    }
}

Використання:

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
Цей підхід часто недоцільний, тому що замість 1 класу вам зараз потрібен 3. Крім того, він змушує письменника NullFooпереосмислити абстрактні методи, хоча вони не мають значення (за визначенням null).
Оператор

1
На мій досвід, модель NullObject може бути практичною, якщо ви працюєте в цілому дуже суворим, класичним способом OO. У відповідь imo модель NullObject трохи зловживається, оскільки це особливо призначене для уникнення if (something is null)перевірок, оскільки NullObject призначений для покриття будь-якої поведінки неіснуючого значення, а будь-який зовнішній співпрацівник не повинен бути зацікавлений у тому, чи об'єкт не існує (нульовий) чи ні.
програв
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.