Đối với những người quan tâm, tôi đã mở rộng chủ đề này thành một bài viết nhỏ, cung cấp thông tin dưới đây ở dạng có cấu trúc tốt hơn một chút: Hướng dẫn cuối cùng cho Isset của PHP
IMHO, bạn nên nghĩ đến việc không chỉ làm cho ứng dụng "tương thích với E_NOTICE" mà còn phải cơ cấu lại toàn bộ. Có hàng trăm điểm trong mã của bạn thường xuyên cố gắng sử dụng các biến không tồn tại nghe có vẻ giống như một chương trình có cấu trúc khá tồi. Việc cố gắng truy cập các biến không tồn tại sẽ không bao giờ xảy ra, các ngôn ngữ khác gặp khó khăn tại thời điểm biên dịch. Thực tế là PHP cho phép bạn làm điều đó không có nghĩa là bạn nên làm như vậy.
Những cảnh báo này là để giúp bạn, không làm phiền bạn. Nếu bạn nhận được cảnh báo "Bạn đang cố gắng làm việc với thứ không tồn tại!" , phản ứng của bạn sẽ là "Rất tiếc, lỗi của tôi, hãy để tôi sửa lỗi đó càng sớm càng tốt." Làm thế nào khác bạn sẽ phân biệt sự khác biệt giữa "các biến hoạt động tốt không xác định" và mã sai trung thực có thể dẫn đến lỗi nghiêm trọng ? Đây cũng là lý do tại sao bạn luôn, luôn luôn phát triển với báo cáo lỗi được chuyển thành 11 và tiếp tục cắm đầu vào mã của bạn cho đến khi không còn một lỗi nàoNOTICE
được phát hành. Việc tắt báo cáo lỗi chỉ dành cho môi trường sản xuất, để tránh rò rỉ thông tin và cung cấp trải nghiệm người dùng tốt hơn ngay cả khi đối mặt với mã lỗi.
Để giải thích:
Bạn sẽ luôn cần isset
hoặc empty
ở đâu đó trong mã của mình, cách duy nhất để giảm sự xuất hiện của chúng là khởi tạo các biến của bạn đúng cách. Tùy thuộc vào tình huống, có những cách khác nhau để làm điều đó:
Đối số hàm:
function foo ($bar, $baz = null) { ... }
Không cần để kiểm tra xem $bar
hoặc $baz
được thiết lập bên trong hàm vì bạn chỉ cần cài đặt chúng, tất cả các bạn cần phải lo lắng về là nếu đánh giá lại giá trị của mình để true
hoặc false
(hoặc bất kỳ người nào khác).
Các biến chính quy ở bất kỳ đâu:
$foo = null;
$bar = $baz = 'default value';
Khởi tạo các biến của bạn ở đầu khối mã mà bạn sẽ sử dụng chúng. Điều này giải quyết !isset
vấn đề, đảm bảo rằng các biến của bạn luôn có giá trị mặc định đã biết, cung cấp cho người đọc ý tưởng về những gì mã sau sẽ hoạt động và do đó cũng đóng vai trò như một loại tài liệu tự học.
Mảng:
$defaults = array('foo' => false, 'bar' => true, 'baz' => 'default value');
$values = array_merge($defaults, $incoming_array);
Tương tự như trên, bạn đang khởi tạo mảng với các giá trị mặc định và ghi đè chúng bằng các giá trị thực.
Trong các trường hợp còn lại, giả sử một mẫu mà bạn đang xuất ra các giá trị có thể được đặt bởi bộ điều khiển, bạn sẽ chỉ phải kiểm tra:
<table>
<?php if (!empty($foo) && is_array($foo)) : ?>
<?php foreach ($foo as $bar) : ?>
<tr>...</tr>
<?php endforeach; ?>
<?php else : ?>
<tr><td>No Foo!</td></tr>
<?php endif; ?>
</table>
Nếu bạn thấy mình thường xuyên sử dụng array_key_exists
, bạn nên đánh giá xem bạn đang sử dụng nó để làm gì. Lần duy nhất nó tạo ra sự khác biệt là ở đây:
$array = array('key' => null);
isset($array['key']); // false
array_key_exists('key', $array); // true
Như đã nêu ở trên, nếu bạn đang khởi tạo đúng cách các biến của mình, bạn không cần phải kiểm tra xem khóa có tồn tại hay không, bởi vì bạn biết nó có. Nếu bạn nhận được các mảng từ một nguồn bên ngoài, giá trị sẽ hầu như không thể null
nhưng ''
, 0
, '0'
, false
hoặc một cái gì đó giống như nó, tức là một giá trị mà bạn có thể đánh giá bằng isset
hoặc empty
, tùy thuộc vào ý định của bạn. Nếu bạn thường xuyên đặt một khóa mảng null
và muốn nó có ý nghĩa gì khác false
, nhưng nếu trong ví dụ trên, các kết quả khác nhau isset
và array_key_exists
tạo ra sự khác biệt cho logic chương trình của bạn, bạn nên tự hỏi tại sao. Sự tồn tại đơn thuần của một biến không nên quan trọng, chỉ giá trị của nó mới là hệ quả. Nếu khóa là một cờ true
/ false
, thì hãy sử dụngtrue
hoặc false
, không null
. Ngoại lệ duy nhất cho điều này sẽ là các thư viện của bên thứ 3 muốn null
có ý nghĩa gì đó, nhưng vì null
rất khó phát hiện trong PHP nên tôi vẫn chưa tìm thấy bất kỳ thư viện nào thực hiện điều này.