Tür ipucu kullanılırken null argümanı iletilemiyor


193

Aşağıdaki kod:

<?php

    class Type {

    }

    function foo(Type $t) {

    }

    foo(null);

?>

çalışma zamanında başarısız oldu:

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

Diğer diller gibi null değerinin geçmesine izin verilmiyor?

Yanıtlar:


357

PHP 7.1 veya daha yenisi (2 Aralık 2016'da çıktı)

nullBu sözdizimiyle bir değişkeni açıkça bildirebilirsiniz

function foo(?Type $t) {
}

bu sonuçlanacak

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

İsteğe bağlı argüman istiyorsanız Yani, kongre takip edebilirsiniz Type $t = nullyapmak gerekirse bir argüman hem kabul oysanull türünü de türünü yukarıdaki örneği takip edebilirsiniz.

Daha fazlasını buradan okuyabilirsiniz .


PHP 7.0 veya üstü

Gibi varsayılan bir değer eklemelisiniz

function foo(Type $t = null) {

}

Bu şekilde, boş bir değer iletebilirsiniz.

Bu, kılavuzdaki Tip Beyanları ile ilgili bölümde belgelenmiştir :

NULLParametrenin varsayılan değeri olarak ayarlanmışsa, değerleri kabul etmek için bildirim yapılabilir NULL.


10
Öyleyse neden null nesnesi null değil ?
Pacerier

4
Çoğu dil null'un herhangi bir türe sahip olmasına izin verir. Bu senaryoda.
Henry

24
Bence bu zayıf bir dil yapısı. 1. Diğer dillerde null herhangi bir türden olma özelliğine sahiptir, bu nedenle null'u bu durumda geçerli bir argüman yapar. 2: Php, null değerine izin verileceğini belirtmek için bağımsız değişken için varsayılan bir değer kullanıyor, bu belirsizdir ve geliştirici bir null değerini açıkça geçmeye zorlamak istese bile zorunlu bir parametreyi imkansız hale getirir.
Henry

2
@Henry ile hemfikirim, ek olarak isteğe bağlı bir param gibi görünen şeylerden sonra paramlere ihtiyaç duymak garip görünüyor.
Force Hero

6
Sadece 2 ile @Henry ile katılıyorum. 1 null için geçemez gerçeği ile ilgili olarak function foo(Type $t)çok iyi bir şey olduğunu; bkz. Sıfır Referanslar: Milyar Dolarlık Hata
Constantin Galbenu

36

PHP 7.1'den başlayarak, hem işlev dönüş tipleri hem de parametreler olarak null olabilecek türler mevcuttur. Tipi ?Tbelirtilen Türü değerlere sahip olabilir T, ya da null.

Yani, fonksiyonunuz şöyle görünebilir:

function foo(?Type $t)
{

}

PHP 7.1 ile çalışabildiğiniz anda, bu gösterimi tercih etmelisiniz function foo(Type $t = null), çünkü hala arayanı parametre için bir argüman belirlemeye zorlar $t.


12

Deneyin:

function foo(Type $t = null) {

}

PHP işlev argümanlarına göz atın .


11
Bununla ilgili sorun, işlevin tanımını değiştirmesidir. Şimdi parametre isteğe bağlıdır - ki bu gerçekten yazarın amaçladığı şey değildir (eğer boşsa, örtük olarak isteğe bağlıdır).
ezmek

7

Daha önce de belirtildiği gibi, bu sadece belirttiğinizde mümkündür null varsayılan değer olarak .

Ancak en temiz tip-güvenli nesne yönelimli çözüm bir NullObject olacaktır :

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

Kullanımı:

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
Yerine 1 sınıf, artık 3. Ayrıca, bu yazarını zorlar gerektiğinden bu yaklaşım, genellikle pratik değildir NullFooonlar (tanımından anlamı yoktur rağmen soyut yöntemler geçersiz kılmak için null).
TheOperator

1
Deneyimlerime göre, genel olarak çok katı, klasik bir OO tarzında çalışırsanız, NullObject deseni pratik olabilir. Yanıtta, imo NullObject kalıbı biraz istismar edilmiştir, çünkü özellikle if (something is null)kontrollerden kaçınması amaçlanmıştır , çünkü NullObject mevcut olmayan bir değerin tüm davranışlarını kapsamak içindir ve herhangi bir dış işbirlikçinin bir nesne mevcut değil (boş) veya yok.
kaybetti
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.