タイプヒントを使用している場合、null引数を渡すことはできません


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以降(2016年12月2日リリース)

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パラメータのデフォルト値がに設定されてNULLいる場合は、値を受け入れるように宣言できます。


10
では、なぜnullオブジェクトを nullにしないのですか?
Pacerier 2013

4
ほとんどの言語では、nullに任意の型を使用できます。このシナリオでは。
Henry

24
私の意見では、これは貧弱な言語構成です。1.他の言語では、nullは任意の型になることができるため、この場合nullは有効な引数になります。2:PHPは、引数にデフォルト値を使用してnullが許容されることを指定しています。これはあいまいであり、開発者がnullを明示的に渡そうとする場合でも必須パラメーターを不可能にします。
ヘンリー

2
私は@Henryに同意します。さらに、オプションのパラメーターのように見えるものの後に必要なパラメーターがあるのは奇妙に見えます。
Force Hero

6
@Henryについては2にのみ同意します。1に関してfunction foo(Type $t)は、nullを渡すことができないという事実は非常に良いことです。Null References:The Billion Dollar Mistake
Constantin Galbenu

36

PHP 7.1以降、関数の戻り値の型とパラメーターの両方として、null許容型が利用できます。タイプに?Tは、指定されたType Tまたはの値を含めることができますnull

したがって、関数は次のようになります。

function foo(?Type $t)
{

}

PHP 7.1で作業できるようになったらすぐに、この表記法を使用することをお勧めします。これfunction foo(Type $t = null)は、呼び出し側がパラメーターの引数を明示的に指定する必要があるため$tです。


12

試してください:

function foo(Type $t = null) {

}

PHP関数の引数を確認してください。


11
私がこれに関して持っている問題は、それが関数の定義を変えるということです。パラメータはオプションになりました-これは実際に作成者が意図したものではありません(ただし、nullを渡した場合、暗黙的にオプションになります)。
2013年

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)意味がない場合でも、の作成者は抽象メソッドをオーバーライドする必要があります。
TheOperator

1
私の経験では、非常に厳密で古典的なオブジェクト指向の方法で一般的に作業している場合、NullObjectパターンは実用的です。if (something is null)NullObjectは存在しない値のすべての動作をカバーすることを目的としているため、NullObjectパターンは少し乱用されています。外部のコラボレーターは、オブジェクトが存在しない(null)かどうか。
敗退
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.