Các kiểu trả về không thể xóa trong PHP7


159

PHP 7 giới thiệu khai báo kiểu trả về . Điều đó có nghĩa là bây giờ tôi có thể chỉ ra giá trị trả về là một lớp, giao diện, mảng, có thể gọi được hoặc một trong các loại vô hướng mới có thể gợi ý, như có thể cho các tham số hàm.

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

Thông thường, giá trị không phải lúc nào cũng xuất hiện và bạn có thể trả về một loại nào đó hoặc null. Mặc dù bạn có thể làm cho các tham số trở nên rỗng bằng cách đặt mặc định của chúng thành null ( DateTime $time = null), nhưng dường như không có cách nào để làm điều này cho các kiểu trả về. Đó thực sự là trường hợp, hoặc tôi bằng cách nào đó không tìm thấy làm thế nào để làm điều đó? Những thứ này không hoạt động:

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

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

8
PHP7 sẽ không cho phép các kiểu trả về nullable, nhưng có một RFC nhằm giải quyết vấn đề này trong PHP 7.1 tại đây . Ký hiệu được dự đoán sau đó sẽ làfunction returnString(?string $stringNull) : ?string { return $stringNull;}
Elias Van Ootegem

1
Bây giờ tôi đã kết thúc việc mô phỏng tính vô hiệu bằng cách lạm dụng các ngoại lệ trong ứng dụng của mình. Nếu bạn cũng ổn với việc ngớ ngẩn, điều này có thể được sử dụng: github.com/JeroenDeDauw/OhMyPhp/blob/master/src/
Lỗi

Có lẽ nó có ý nghĩa hơn khi sử dụng Trowablegiao diện PHP7 (cụ thể là mở rộng TypeError)
Elias Van Ootegem

Câu trả lời:


258

PHP 7.1 Bây giờ hỗ trợ các kiểu trả về nullable . RFC đầu tiên tôi liên kết đến là RFC họ đã tham gia:

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

câu trả lời cũ:

Vì nhận xét của tôi thực sự là một câu trả lời cho câu hỏi:

PHP 7 sẽ không hỗ trợ các kiểu trả về vô giá trị, nhưng có một RFC để giải quyết vấn đề đó, nó nhằm mục đích hạ cánh trong PHP 7.1. Nếu nó vượt qua, cú pháp sẽ ảnh hưởng đến tất cả các gợi ý kiểu (cả kiểu trả về và gợi ý kiểu):

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

Ngoài ra còn có một RFC cạnh tranh để thêm các loại kết hợp, có thể làm điều tương tự, nhưng sẽ khác:

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

Tuy nhiên, bây giờ, bạn sẽ phải viết:

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

Hoặc chỉ trả về một chuỗi trống để phù hợp với loại trả về và kiểm tra giá trị giả:

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- vâng, RFC, "chưa". Đừng hiểu sai ý tôi - Tôi thực sự là người dùng PHP nặng nề kể từ thời PHP3 thực sự nhảm nhí cho đến bây giờ, không có lỗ hổng nào, nhưng khi tôi thấy tất cả các RFC này họ đã từ chối trong 7, ấn tượng của tôi chỉ là "WTF?!". Người dùng nhìn thấy sự lộn xộn và sẵn sàng dọn dẹp nó theo cách tương thích ngược và họ chỉ nhận được "không". Làm sạch phương pháp đặt tên lộn xộn? Sửa nulllỗi không phải là công dân quá đặc biệt? Không, không cần thiết. Thêm tùy chọn để làm cho tất cả các trường hợp công cụ nhạy cảm? Không .. Và sau đó, bất ngờ rằng mọi người chuyển đổi.
Marcin Orleansowski

1
@MarcinOrlowski: Một gợi ý loại trả về vô giá trị sẽ có ý nghĩa. Tôi đã theo dõi một vài RFC trong 7 và tôi đã đồng ý phần lớn với việc họ từ chối rất nhiều trong số họ. Những thay đổi họ tập trung vào ngôn ngữ không giống với ngôn ngữ thời gian chạy và trình biên dịch. Đối với một số RFC đã bị từ chối, đáng để đọc qua các chủ đề thảo luận để hiểu lý do tại sao họ chọn không thực hiện những thay đổi đó (ví dụ như phản đối var). Điều đáng tiếc là thay vào đó, họ đã chấp nhận quá nhiều thứ tốt đẹp (ví dụ như nhà điều hành tàu vũ trụ)
Elias Van Ootegem

Các loại @EliasVanOotegem Nullable hiện được hỗ trợ chính xác, vì 7.1 đã được phát hành vào ngày 1 tháng 12.
cô đơn

@lonesomeday: Thật vậy, đã thêm liên kết + ví dụ cơ bản vào cuối câu trả lời của tôi
Elias Van Ootegem

mmm là một loại tốt để cập nhật câu trả lời này! tức là loại kết hợp dường như không được hỗ trợ trong PHP 7.1
Dennis

67

Các loại không thể có sẵn trong PHP 7.1.

Đây là một ví dụ cú pháp:

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

PHP 7.1 hiện là GA và bạn có thể nâng cấp từ PHP 7.0 (chỉ có một vài thay đổi không tương thích ngược mà bạn phải kiểm tra)


22
IMO đó là một trò đùa để cung cấp khai báo loại trả về mà không thực hiện "nullable". Các kiểu trả về không thể sử dụng được cho đến khi tính năng "nullable" được triển khai.
joonas.fi

2
@ joonas.fi IMO được gõ đúng các giá trị trả về phải luôn thuộc loại đó, trả về null không giữ cho hợp đồng đó và thay vào đó nên ném một ngoại lệ có ý nghĩa hơn đối với lý do giá trị null.
Steve Buzonas

8
@SteveBuzonas nếu bạn xem xét một phương thức getAgeInYears () trên một đối tượng đại diện cho một Người, bạn sẽ mô hình hóa một người chưa nói với chúng tôi về tuổi của anh ấy / cô ấy như thế nào? Trả về null? Trả về 0? Trả về null về mặt ngữ nghĩa có nghĩa là "chúng tôi không biết", trong khi 0 về mặt ngữ nghĩa có nghĩa là "người đó 0 tuổi". Do đó, tôi sẽ tranh luận getAgeInYears () :? Int là thiết kế tốt nhất. Ném ngoại lệ nên được dành riêng cho ... trường hợp đặc biệt. Không biết tuổi của một người trong hầu hết các hệ thống không nên được coi là một trường hợp ngoại lệ.
joonas.fi

@ joonas.fi rất đúng, và đó là một thực tế phổ biến. Tuy nhiên, việc triển khai của bạn bây giờ cần phải biết rằng trường này là null và xử lý rõ ràng cho phù hợp. Điều này rất có thể được thực hiện x trừ khi null có thể dễ dàng thực hiện với một lần thử / bắt. Hơn nữa, nếu một người thực sự yêu cầu một giá trị trong trường nullable đó để tiếp tục thực thi, một ngoại lệ có thể là một lựa chọn tốt hơn.
Steve Buzonas

Tôi đã nhận thấy rằng cú pháp này khiến PHPMD có rất nhiều lỗi. Hy vọng họ sẽ sửa nó sớm.
Tom Jowitt

0

Nó hoạt động với bất kỳ loại.
Thí dụ:

public function getOpportunity(): ?Opportunity
{
    return $this->opportunity;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.