ชนิดส่งคืนที่ Nullable ใน PHP7


159

PHP 7 เปิดตัวส่งกลับชนิดประกาศ ซึ่งหมายความว่าตอนนี้ฉันสามารถระบุว่าค่าตอบแทนเป็นคลาสอินเทอร์เฟซอาร์เรย์ callable หรือหนึ่งในประเภทสเกลาร์ที่บอกใบ้ได้ใหม่ซึ่งเป็นไปได้สำหรับพารามิเตอร์ฟังก์ชัน

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

บ่อยครั้งที่มันเกิดขึ้นที่ค่าไม่ได้มีอยู่เสมอและคุณอาจส่งคืนบางสิ่งบางอย่างหรือเป็นโมฆะ ในขณะที่คุณสามารถทำให้พารามิเตอร์เป็นโมฆะได้โดยการตั้งค่าเริ่มต้นเป็นโมฆะ ( DateTime $time = null) ดูเหมือนจะไม่เป็นเช่นนั้นสำหรับวิธีการส่งคืน เป็นเช่นนั้นจริงหรือฉันไม่พบวิธีที่จะทำหรือไม่? สิ่งเหล่านี้ใช้ไม่ได้:

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

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

8
PHP7 จะไม่อนุญาตให้กลับประเภท nullable แต่มีการ RFC ที่มีวัตถุประสงค์เพื่อที่อยู่นี้ใน PHP 7.1 ที่นี่ สัญกรณ์ propesed นั้นจะfunction returnString(?string $stringNull) : ?string { return $stringNull;}
Elias Van Ootegem

1
ฉันสิ้นสุดการลอกเลียนแบบโมฆะโดยการใช้ข้อยกเว้นในแอปพลิเคชันของฉันในตอนนี้ หากคุณไม่เป็นคนโง่ก็อาจใช้สิ่งนี้ได้: github.com/JeroenDeDauw/OhMyPhp/blob/master/src/ ......
Jeroen De Dauw

บางทีมันอาจจะเหมาะสมกว่าที่จะใช้Trowableอินเทอร์เฟซPHP7 (โดยเฉพาะการขยายTypeError)
Elias Van Ootegem

คำตอบ:


258

PHP 7.1 ขณะนี้สนับสนุนกลับประเภท nullable RFC แรกที่ฉันเชื่อมโยงกับสิ่งที่พวกเขาทำเพื่อ:

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

คำตอบเก่า:

เนื่องจากความคิดเห็นของฉันเป็นคำตอบสำหรับคำถาม:

PHP 7 จะยังไม่สนับสนุนประเภทคืนค่าที่ไม่สามารถใช้งานได้ แต่มีRFCออกมาเพื่อแก้ไขปัญหาดังกล่าวโดยมีเป้าหมายที่จะลงจอดใน PHP 7.1 หากผ่านไวยากรณ์จะส่งผลต่อคำใบ้ทุกประเภท (ทั้งประเภทการคืนสินค้าและคำใบ้ประเภท):

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

นอกจากนี้ยังมี RFC ที่แข่งขันกันเพื่อเพิ่มประเภทยูเนี่ยนซึ่งจะสามารถทำสิ่งเดียวกัน แต่จะแตกต่างกัน:

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

แม้ว่าตอนนี้คุณจะต้องเขียน:

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

หรือเพียงแค่คืนค่าสตริงว่างเปล่าเพื่อให้สอดคล้องกับชนิดส่งคืนและตรวจสอบค่าที่ผิดพลาด:

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- ใช่ RFC "เพิ่ง" อย่าเข้าใจฉันผิด - ฉันเป็นผู้ใช้ PHP หนักมากตั้งแต่ตอนที่ PHP3 เส็งเคร็งจนถึงตอนนี้ไม่มีช่องว่าง แต่เมื่อฉันเห็น RFCs ทั้งหมดที่พวกเขาปฏิเสธมาเป็นเวลา 7 ความประทับใจของฉันก็คือ "WTF ?!" ผู้ใช้เห็นความยุ่งเหยิงและยินดีที่จะทำความสะอาดในวิธีที่เข้ากันได้แบบย้อนหลังและพวกเขาเพิ่งได้รับ "ไม่" วิธีทำความสะอาดวิธีการตั้งชื่อระเบียบ? คงnullไม่ได้เป็นพลเมืองที่พิเศษเกินไปเหรอ? ไม่ไม่จำเป็น เพิ่มตัวเลือกเพื่อให้ทุกกรณีเป็นเรื่องที่ละเอียดอ่อนใช่ไหม ไม่ .. แล้วก็แปลกใจที่ผู้คนเปลี่ยน
Marcin Orlowski

1
@MarcinOrlowski: คำใบ้ชนิดส่งคืนค่า null จะสมเหตุสมผล ฉันติดตามสอง RFC สำหรับ 7 และฉันเห็นด้วยส่วนใหญ่กับพวกเขาปฏิเสธพวกเขามาก การเปลี่ยนแปลงที่พวกเขาเพ่งความสนใจไปที่ไม่ได้มีมากในภาษาที่พวกเขาอยู่ในรันไทม์และคอมไพเลอร์ สำหรับ RFC บางส่วนที่ถูกปฏิเสธควรอ่านผ่านหัวข้อการสนทนาเพื่อทำความเข้าใจว่าทำไมพวกเขาถึงเลือกที่จะไม่ใช้การเปลี่ยนแปลงเหล่านั้น (เช่นการคัดค้านvar) สิ่งที่น่าพิศวงคือว่าพวกเขายอมรับหนึ่งในผู้
ใจดีที่

@EliasVanOotegem รองรับประเภท Nullable ได้อย่างถูกต้องแล้วเนื่องจากมีการเผยแพร่ 7.1 เมื่อวันที่ 1 ธันวาคม
lonesomeday

@lonesomeday: อันที่จริงมันก็ไม่เพิ่มการเชื่อมโยง + ตัวอย่างพื้นฐานไปที่ด้านล่างของคำตอบของฉัน
อีเลียสแวน Ootegem

mmm เป็นประเภทที่ดีในการอัปเดตคำตอบนี้! เช่นประเภทยูเนี่ยนไม่ได้รับการสนับสนุนใน PHP 7.1
Dennis

67

ประเภท Nullableมีอยู่ใน PHP 7.1

นี่คือตัวอย่างของไวยากรณ์:

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

PHP 7.1 คือตอนนี้ GA และคุณสามารถอัพเกรดจาก PHP 7.0 (มีการเปลี่ยนแปลงที่เข้ากันไม่ได้ย้อนหลังเพียงเล็กน้อยที่คุณต้องตรวจสอบ)


22
IMO มันเป็นเรื่องตลกที่จะส่งประกาศประเภทผลตอบแทนโดยไม่ต้องใช้ "nullable" ประเภทการส่งคืนจะไม่สามารถใช้งานได้จนกว่าจะมีการใช้งานคุณสมบัติ "nullable"
joonas.fi

2
@ joonas.fi IMO ที่พิมพ์ค่าส่งคืนอย่างเคร่งครัดควรเป็นประเภทนั้นเสมอการคืนค่า Null ไม่ถือเป็นสัญญานั้นและควรทิ้งข้อยกเว้นที่ให้ความหมายกับเหตุผลของค่า Null มากกว่า
Steve Buzonas

8
@SteveBuzonas ถ้าคุณพิจารณาวิธีการ getAgeInYears () บนวัตถุที่เป็นตัวแทนของบุคคลคุณจะสร้างแบบจำลองบุคคลที่ไม่ได้บอกอายุของเขากับเราได้อย่างไร ส่งคืน null หรือไม่ ส่งคืน 0 การคืนค่า null หมายถึง "เราไม่รู้" ในขณะที่ 0 หมายถึง "บุคคลนั้นมีอายุ 0 ปี" ดังนั้นฉันจะเถียง getAgeInYears (): int เพื่อการออกแบบที่ดีที่สุด การโยนข้อยกเว้นควรถูกสงวนไว้สำหรับ ... กรณีพิเศษ ไม่ทราบอายุของบุคคลในระบบส่วนใหญ่ไม่ควรพิจารณาเป็นกรณีพิเศษ
joonas.fi

@ joonas.fi จริงมากและนั่นก็เป็นเรื่องธรรมดา อย่างไรก็ตามการใช้งานของคุณตอนนี้จำเป็นต้องทราบว่าฟิลด์นั้นเป็นโมฆะและจัดการอย่างชัดเจน ซึ่งดีมากอาจทำ x ยกเว้นเมื่อเป็นโมฆะซึ่งสามารถนำมาใช้อย่างง่ายดายด้วยลอง / จับ นอกจากนี้หากจำเป็นต้องใช้ค่าจริงในฟิลด์ที่สามารถ null ได้เพื่อดำเนินการต่อข้อยกเว้นน่าจะเป็นตัวเลือกที่ดีกว่า
Steve Buzonas

ฉันสังเกตเห็นว่ารูปแบบนี้ทำให้ PHPMD มีข้อผิดพลาดมากมาย หวังว่าพวกเขาจะแก้ไขมันในไม่ช้า
Tom Jowitt

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.