PHP7'de boş değerli dönüş türleri


159

PHP 7, dönüş türü bildirimleri sunar . Bu da, dönüş değerinin işlev parametreleri için mümkün olduğunca belirli bir sınıf, arabirim, dizi, çağrılabilir veya yeni sonlanabilir skaler tiplerden biri olduğunu gösterebileceğim anlamına gelir.

function returnHello(): string {
    return 'hello';
}

Genellikle bir değer her zaman mevcut değildir ve bir tür veya boş bir değer döndürebilirsiniz. Parametreleri varsayılan değerlerini null ( DateTime $time = null) olarak ayarlayarak nullable yapabilirsiniz , ancak dönüş türleri için bunu yapmanın bir yolu yoktur. Gerçekten de öyle mi, yoksa nasıl yapılacağını bulamıyor muyum? Bunlar çalışmıyor:

function returnHello(): string? {
    return 'hello';
}

function returnHello(): string|null {
    return 'hello';
}

8
PHP7 henüz boş değerli dönüş türlerine izin vermiyor, ancak burada PHP 7.1'de bunu ele almayı amaçlayan bir RFC var . function returnString(?string $stringNull) : ?string { return $stringNull;}
Propinged

1
Şimdilik başvurumdaki istisnaları kötüye kullanarak nullabilite taklit ettim. Aptallık konusunda da iyiyseniz
Jeroen De Dauw

Belki de PHP7 Trowablearayüzünü kullanmak daha mantıklı olabilir (özellikle, genişletmek TypeError)
Elias Van Ootegem

Yanıtlar:


258

PHP 7.1 Şimdi nullable dönüş türlerini destekliyor . Bağlantı kurduğum ilk RFC, gittikleri şey:

function nullOrString(int $foo) : ?string
{
    return $foo%2 ? "odd" : null;
}

eski cevap:

Yorumum aslında soruya bir cevap olduğu için:

PHP 7 henüz sıfırlanabilir dönüş türlerini desteklemeyecek, ancak bunu ele almak için bir RFC çıkışı var, PHP 7.1'e inmeyi hedefliyor. Geçerse, sözdizimi tüm tür ipuçlarını etkiler (hem dönüş türleri hem de tür ipuçları):

public function returnStringOrNull(?array $optionalArray) : ?string
{
    if ($optionalArray) {
        return implode(', ', $optionalArray);//string returned here
    }
    return null;
}

Aynı şeyi yapabilen, ancak farklı görünecek sendika türleri eklemek için rakip bir RFC de var :

public function returnStringOrNull(array|null $optionalArray) : string|null
{
    if ($optionalArray) {
        return implode(', ', $optionalArray);//string returned here
    }
    return null;
}

Şimdilik şimdilik şunu yazmanız gerekecek:

public function returnStringOrNull( array $optionalArray = null)
{
    if ($optionalArray) {
        return implode(', ', $optionalArray);
    }
}

Veya dönüş türüyle tutarlı olması için boş bir dize döndürün ve yanlış değeri kontrol edin:

public function returnStringOrNull( array $optionalArray = null) : string
{
    if ($optionalArray) {
        return implode(', ', $optionalArray);
    }
    return '';
}
//call
$string = $x->returnStringOrNull();
if (!$string) {
    $string = $x->returnStringOrNull(range(1, 10));
}

5
PHP 7 won't support nullable return-types just yet, but there's an RFC out to address just that- evet, RFC, "henüz". Beni yanlış anlamayın - Ben gerçekten şimdiye kadar PHP3 kez gerçekten berbat PHP kullanıcı beri hiçbir boşluklar, ama tüm bu RFCs 7 için reddetti görünce, benim izlenim sadece "WTF ?!" oldu. Kullanıcılar karışıklık görmek ve geriye dönük uyumlu bir şekilde temizlemek için istekli ve sadece "hayır" olsun. Karmaşık adlandırma yöntemleri temiz mi? nullÇok özel vatandaş olmama sorunu düzeltildi mi? Hayır, gerek yok. Ekle seçeneği tüm malzeme harf duyarlı yapmak için? Hayır .. Ve sonra, insanların değişmesi şaşırtıcı.
Marcin Orlowski

1
@MarcinOrlowski: Sıfırlanabilir bir geri dönüş tipi ipucu mantıklı olacaktır. RFC'lerin birkaçını 7 için takip ettim ve çoğunlukla onlardan birçoğunu reddetmelerini kabul ettim. Odaklandıkları değişiklikler, çalışma zamanı ve derleyicide olduğu kadar dilde değildi. Reddedilen bazı RFC'ler için, bu değişiklikleri neden uygulamamayı seçtiklerini anlamak için tartışma konuları üzerinden okumaya değer (örn var. Kullanımdan kaldırma ). Ne yazık ki, bunun yerine, çok fazla hoş olanı kabul ettiler (örneğin uzay gemisi operatörü)
Elias Van Ootegem

@EliasVanOotegem 7 Aralık 1 Aralık'ta piyasaya sürüldüğü için null olabilecek türler artık düzgün bir şekilde destekleniyor.
lonesomeday

@lonesomeday: Gerçekten öyle, cevabımın altına link + temel örnek ekledi
Elias Van Ootegem

mmm ish bu cevabı güncellemek için iyi bir tip! yani birleşim türü PHP 7.1'de desteklenmiyor gibi görünüyor
Dennis

67

Null olabilecek türler PHP 7.1'de mevcuttur.

Bu bir sözdizimi örneğidir:

public function getName(): ?string
{
    return $this->name; // name can be null
}

PHP 7.1 artık GA ve PHP 7.0'dan yükseltebilirsiniz ( kontrol etmeniz gereken sadece birkaç geriye dönük uyumsuz değişiklik var)


22
IMO, "geçersiz" uygulamadan geri dönüş tipi bildirimleri sunmak için bir şaka. "Nullable" özelliği uygulanana kadar dönüş türleri kullanılamaz.
joonas.fi

2
@ joonas.fi IMO kesinlikle yazılan dönüş değerleri her zaman bu tür olmalıdır, boş bir dönüş bu sözleşmeye uymaz ve bunun yerine boş değerin nedenine daha fazla anlam veren bir istisna atmalıdır.
Steve Buzonas

8
@SteveBuzonas, bir kişiyi temsil eden bir nesne üzerinde getAgeInYears () yöntemini düşünürseniz, bize yaşını söylememiş bir kişiyi nasıl modellersiniz? Boş döndürülsün mü? Dönüş 0? Anlamsal olarak boş değer döndürmek "bilmiyoruz" anlamına gelirken, 0 anlamsal olarak "kişi 0 yaşındadır" anlamına gelir. Bu nedenle getAgeInYears ():? İnt'in en iyi tasarım olduğunu iddia ediyorum. Atma istisnaları iyi ... istisnai durumlar için ayrılmalıdır. Çoğu sistemde bir kişinin yaşını bilmemek istisnai bir durum olarak görülmemelidir.
joonas.fi

@ joonas.fi çok doğru ve bu yaygın bir uygulamadır. Ancak, uygulamanızın artık alanın boş olabileceğinin ve açıkça buna göre işlendiğinin farkında olması gerekir. Hangi çok iyi olabilir bir x / try ile kolayca uygulanabilir null dışında dışında olabilir. Ayrıca, yürütülmeye devam etmek için bu boş alandaki bir değere gerçekten ihtiyaç duyulursa, istisna daha iyi bir seçenektir.
Steve Buzonas

Bu sözdiziminin PHPMD'nin birçok hata atmasına neden olduğunu fark ettim. Umarım yakında düzeltirler.
Tom Jowitt

0

Her tür ile çalışır.
Misal:

public function getOpportunity(): ?Opportunity
{
    return $this->opportunity;
}
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.