Tuần trước, chúng tôi đã sử dụng Bản đồ yếu để giải quyết trường hợp một cạnh. Hôm nay, chúng tôi đơn giản hóa trường hợp cạnh phổ biến và khó chịu nhất. của hư vô
Hãy thành thật mà nói, các giá trị null thật tệ. Chúng được gọi là sai lầm tỷ đô, nhưng các lập trình viên ở hầu hết các ngôn ngữ vẫn phải đối mặt với nó. (Trừ các bạn làm ở Rust. ) Chúng đặc biệt tệ khi bạn có một biến có thể là một đối tượng hoặc null. Nếu nó là một đối tượng, có lẽ bạn biết nó là loại gì và nó có thể làm gì;
Cách tiêu chuẩn để giải quyết tình huống đó là phân nhánh bằng cách sử dụng kiểm tra có điều kiện, mẫu "if null" cùng tên
getAddress(); if (!is_null($address)) { $state = $address->state; If (!is_null($state)) { // And so on. } } }Tất nhiên, điều này là thô thiển và khó đọc, nhưng cần thiết nếu bạn muốn tránh lỗi Call to a member function on null đáng sợ
Trong một thế giới lý tưởng, chúng ta có thể cấu trúc mã của mình sao cho null là không thể. Đáng buồn thay, chúng ta không sống trong một thế giới lý tưởng, đặc biệt là khi chúng ta phải xử lý mã của người khác. Vì lý do đó, một số ngôn ngữ có cái được gọi là "toán tử nullsafe. " Và, kể từ phiên bản 8. 0, PHP là một trong số đó
Toán tử nullsafe thực sự là một công cụ sửa đổi khi truy cập đối tượng, thuộc tính hoặc lệnh gọi phương thức. Nếu một trong hai điều đó đứng trước một ?, thì nó có tác dụng tương tự như bao quyền truy cập trong một séc if (!is_null)). Chẳng hạn, ví dụ trên trở thành
getAddress()?->state;Trong ví dụ này, giá trị được trả về bởi get_user() là một đối tượng User hoặc null. Giá trị được trả về bởi User::getAddress() là một đối tượng Address hoặc null. Nếu get_user() trả về null, thì ? bắt nó và trả về null, bỏ qua toàn bộ phần còn lại của dòng. Điều tương tự cũng xảy ra với getAddress()?->state;2. Cuối cùng, getAddress()?->state;3 là một giá trị trạng thái hợp lệ được lấy từ thuộc tính getAddress()?->state;4 của địa chỉ hoặc nó không có giá trị
Toán tử nullsafe làm đoản mạch phần còn lại của đường dây khi gặp giá trị null lần đầu tiên. Điều đó có nghĩa là ngay cả các cuộc gọi động hoặc cuộc gọi lỗi sau này trong quy trình cũng không xảy ra. Ví dụ
getProducts(get_seasonal_type())?->mostPopular(10)[5];Nếu getAddress()?->state;5 là null, thì getAddress()?->state;6 sẽ không được gọi. Toàn bộ chuỗi dừng lại sau khi phát hiện ra rằng getAddress()?->state;5 là null và đặt getAddress()?->state;8 thành null. Tương tự, nếu getAddress()?->state;9 trả về getProducts(get_seasonal_type())?->mostPopular(10)[5];0, thì getProducts(get_seasonal_type())?->mostPopular(10)[5];1 không bao giờ được gọi. Tuy nhiên, điều đó không mở rộng đến mảng. Nếu getProducts(get_seasonal_type())?->mostPopular(10)[5];1 vẫn được gọi và nó trả về null, bạn sẽ vẫn gặp lỗi getProducts(get_seasonal_type())?->mostPopular(10)[5];3
Tất nhiên, có một số hạn chế đối với toán tử nullsafe. Nó chỉ hoạt động để đọc các thuộc tính hoặc phương thức, không phải để ghi vào các giá trị. Nó cũng không xử lý các tham chiếu, bởi vì các tham chiếu yêu cầu giá trị thực. (Điều này phù hợp với các ngôn ngữ khác có toán tử nullsafe. )
Nó cũng không cung cấp dấu hiệu cho biết bước nào trong chuỗi trả về giá trị rỗng. ; . Không có cách nào để nói. Đôi khi điều đó tốt. Tuy nhiên, nếu bạn cần nói sự khác biệt, nullsafe sẽ không giúp bạn. Để làm được điều đó, bạn thực sự cần một Đơn vị Hoặc, nhưng đó là một chủ đề cho một thời điểm rất khác
Tuy nhiên, nullsafe có thể giúp giảm số lượng mã soạn sẵn trôi nổi xung quanh chuỗi phương thức hướng đối tượng của bạn. Chúng tôi có Ilija Tovilo để cảm ơn vì RFC nullsafe
Hãy theo dõi phần tiếp theo của chúng tôi, khi chúng tôi đề cập đến một loạt các cải tiến nhỏ hơn sẽ giúp PHP 8. 0 nói chung là dễ chịu hơn khi sống
Bạn có thể dùng thử các bản phát hành trước của PHP 8. 0 hôm nay trên Nền tảng. sh, chỉ với một thay đổi một dòng. Hãy thử và cho chúng tôi biết các tính năng yêu thích của bạn là gì
Một mảng trống được chuyển đổi thành null bằng cách so sánh '==' bằng nhau không nghiêm ngặt. Sử dụng is_null() hoặc ‘===’ nếu có thể lấy mảng trốngXem đoạn mã sau
<?php // app.php $a = array(); if($a == null) { echo 'First NULL'; } if($a === null) { echo 'Second NULL'; } if(is_null($a)) { echo 'Third NULL'; }Xem đầu ra
Vì vậy, So sánh không nghiêm ngặt '==' trả về bool(true)
Hãy xem một ví dụ khác. Xem đoạn mã sau.
<?php // app.php $foo = NULL; var_dump(is_null($foo));Xem đầu ra
Hiệu suất
Trong PHP 7 (phpng), is_null nhanh hơn rất nhiều so với ===, mặc dù sự khác biệt về hiệu suất giữa hai loại nhỏ hơn nhiều
PHP5. 5. 9
is_null – float(2. 2381200790405)
=== – float(1. 0024659633636)
=== nhanh hơn ~100ns mỗi cuộc gọi
PHP7. 0. 0-dev (được xây dựng. 19 Tháng năm 2015 10. 16. 06)
is_null – float(1. 4121870994568)
=== – float(1. 4577329158783)
is_null nhanh hơn ~5ns mỗi cuộc gọi
Sử dụng === NULL thay vì is_null() hữu ích trong một số trường hợp, chẳng hạn như các tình huống máy chủ được tải trong đó bạn có hàng trăm hoặc hàng nghìn yêu cầu đến mỗi giây
Tiết kiệm micro giây cho nhiều thao tác “đơn giản” trong toàn bộ chuỗi thực thi PHP thường dẫn đến việc có thể phục vụ nhiều trang hơn mỗi giây với cùng tốc độ hoặc giảm mức sử dụng CPU của bạn. Nhưng thật không may, những người