Kiểm tra xem var có tồn tại trước khi bỏ thiết lập trong PHP không?


88

Với báo cáo lỗi đang bật, hoặc thậm chí đối với thực tiễn tốt nhất, khi bỏ đặt một biến trong PHP, bạn nên kiểm tra xem nó có tồn tại trước không (trong trường hợp này không phải lúc nào nó cũng tồn tại) và bỏ đặt nó hay chỉ bỏ đặt nó?

<?PHP
if (isset($_SESSION['signup_errors'])){
    unset($_SESSION['signup_errors']);
}

// OR

unset($_SESSION['signup_errors']);
?>


1
Nó là hiệu quả hơn để NOTsử dụng isset. Hãy xem câu trả lời của tôi. Tôi đã thực hiện các bài kiểm tra để tìm ra sự khác biệt về tốc độ.
Dan Bray

Câu trả lời:


167

Chỉ cần gỡ bỏ nó, nếu nó không tồn tại, sẽ không có gì được thực hiện.


3
Tôi không biết liệu nó sẽ đưa ra một cảnh báo hay thông báo
JasonDavis

19
@SilentGhost Tôi đồng ý, có vẻ như một bài kiểm tra đơn giản như vậy, nhưng họ đang yêu cầu lời khuyên chuyên nghiệp và trong khi nhật ký lỗi có thể không có bất kỳ lỗi / cảnh báo / thông báo nào khi bỏ đặt một var không xác định, có thể có các vấn đề khác chưa được ghi. Ví dụ: chỉ gọi unset có nghĩa là PHP quét qua TẤT CẢ dữ liệu var vì nó không thể tìm thấy bất cứ thứ gì, trong khi việc sử dụng if setcó thể có một số lược đồ lập chỉ mục tốt hơn. (Chỉ là một ví dụ, trước đó có lẽ là cobblers và cả hai cách tiếp cận đều sử dụng cùng một phương pháp kiểm tra dữ liệu).
James

Đúng, và nó cũng hiệu quả hơn. Hãy xem câu trả lời của tôi vì tôi đã kiểm tra tốc độ sử dụng issetcác câu không sử dụng isset.
Dan Bray

bỏ phiếu xuống - bạn không thể bỏ đặt các khóa mảng chưa được xác định.
Behnam

1
@jascha Tôi đã nói, chúng tôi không thể!
Behnam

48

Từ Hướng dẫn sử dụng PHP :

Liên quan đến một số nhầm lẫn trước đó trong các ghi chú này về nguyên nhân khiến unset () kích hoạt thông báo khi hủy đặt các biến không tồn tại ....

Bỏ đặt các biến không tồn tại, như trong

<?php
unset($undefinedVariable);
?>

không kích hoạt thông báo "Biến không xác định". Nhưng

<?php
unset($undefinedArray[$undefinedKey]);
?>

kích hoạt hai thông báo, bởi vì mã này là để hủy thiết lập một phần tử của một mảng; Bản thân $ undefinedArray và $ undefinedKey đều không được đặt, chúng chỉ đơn thuần được sử dụng để định vị những gì nên không được đặt. Rốt cuộc, nếu họ tồn tại, bạn vẫn mong đợi cả hai sẽ ở bên nhau sau này. Bạn sẽ KHÔNG muốn toàn bộ mảng của mình biến mất chỉ vì bạn bỏ đặt () một trong các phần tử của nó!


41
Điều này cần được làm rõ hơn một chút. Bạn có thể hủy đặt các khóa mảng không được xác định miễn là mảng tồn tại.
kingmaple

@kristovaher Thật vậy - điều này không giải quyết được kịch bản cụ thể mà OP mô tả.
Mark Amery

21

Việc sử dụng unsettrên một biến không xác định sẽ không gây ra bất kỳ lỗi nào (trừ khi biến đó là chỉ số của một mảng (hoặc đối tượng) không tồn tại).

Do đó, điều duy nhất bạn cần xem xét, là cái gì là hiệu quả nhất. Sẽ hiệu quả hơn nếu không kiểm tra bằng 'Isset', vì thử nghiệm của tôi sẽ hiển thị.

Kiểm tra:

function A()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        unset($defined);
    }
}

function B()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        unset($undefined);
    }
}

function C()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        if (isset($defined))
            unset($defined);
    }
}

function D()
{
    for ($i = 0; $i < 10000000; $i++)
    {
        $defined = 1;
        if (isset($undefined))
            unset($undefined);
    }
}

$time_pre = microtime(true);
A();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function A time = $exec_time ";

$time_pre = microtime(true);
B();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function B time = $exec_time ";

$time_pre = microtime(true);
C();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function C time = $exec_time ";

$time_pre = microtime(true);
D();
$time_post = microtime(true);
$exec_time = $time_post - $time_pre;
echo "Function D time = $exec_time";
exit();

Các kết quả:

  1. Function A time = 1.0307259559631
    • Được xác định không có Isset
  2. Function B time = 0.72514510154724
    • Không xác định không có Isset
  3. Function C time = 1.3804969787598
    • Được xác định bằng cách sử dụng Isset
  4. Function D time = 0.86475610733032
    • Không xác định bằng cách sử dụng Isset

Phần kết luận:

Nó luôn luôn kém hiệu quả hơn để sử dụng isset, chưa kể đến việc mất thêm thời gian để viết. Việc thử unsetmột biến không xác định sẽ nhanh hơn là kiểm tra xem nó có thể được không unset.


1
Đây là cách tốt hơn câu trả lời được chấp nhận! Cảm ơn vì đã chạy các thử nghiệm này.
Adam Friedman

3

Nếu bạn muốn hủy đặt một biến thì bạn có thể sử dụng unset

unset($any_variable); // bool, object, int, string etc

Kiểm tra sự tồn tại của nó không có lợi khi cố gắng bỏ đặt một biến.

Nếu biến là một mảng và bạn muốn hủy đặt một phần tử, bạn phải đảm bảo rằng phần tử gốc tồn tại trước, điều này cũng áp dụng cho các thuộc tính đối tượng.

unset($undefined_array['undefined_element_key']); // error - Undefined variable: undefined_array

unset($undefined_object->undefined_prop_name); // error - Undefined variable: undefined_object

Điều này có thể dễ dàng giải quyết bằng cách gói unsettrong một if(isset($var)){ ... }khối.

if(isset($undefined_array)){
    unset($undefined_array['undefined_element_key']); 
}

if(isset($undefined_object)){
    unset($undefined_object->undefined_prop_name); 
}

Lý do chúng tôi chỉ kiểm tra biến ( cha ) đơn giản là vì chúng tôi không cần kiểm tra thuộc tính / phần tử và làm như vậy sẽ chậm hơn rất nhiều để viết và tính toán vì nó sẽ thêm một lần kiểm tra.

if(isset($array)){
...
}

if(isset($object)){
...
}

.vs

$object->prop_name = null;
$array['element_key'] = null;

// This way elements/properties with the value of `null` can still be unset.

if(isset($array) && array_key_exists('element_key', $array)){
...
}

if(isset($object) && property_exists($object, 'prop_name')){
...
}

// or 

// This way elements/properties with `null` values wont be unset.

if(isset($array) && $array['element_key'])){
...
}

if(isset($object) && $object->prop_name)){
...
}

Điều này không cần phải nói nhưng điều quan trọng là bạn phải biết typevề biến khi nhận, thiết lập và hủy thiết lập một phần tử hoặc thuộc tính; sử dụng sai cú pháp sẽ gây ra lỗi.

Tương tự khi cố gắng bỏ đặt giá trị của một mảng hoặc đối tượng nhiều chiều. Bạn phải đảm bảo rằng khóa / tên mẹ tồn tại.

if(isset($variable['undefined_key'])){
    unset($variable['undefined_key']['another_undefined_key']);
}

if(isset($variable->undefined_prop)){
    unset($variable->undefined_prop->another_undefined_prop);
}

Khi xử lý các đối tượng, có một điều khác phải nghĩ đến, đó là khả năng hiển thị.

Chỉ vì nó tồn tại không có nghĩa là bạn có quyền sửa đổi nó.


Cuối cùng, một câu trả lời thích hợp. Cảm ơn bạn.
wp78de

Một bản cập nhật nhỏ: Trong PHP 7.4 / 8.0, không có lỗi nào được đưa ra khi bạn unsetthuộc tính của đối tượng mẹ không tồn tại. Tuy nhiên, việc giải quyết khóa trong một mảng không tồn tại trong PHP8 không chỉ làm tăng thông báo mà còn là cảnh báo (có thể thay đổi).
wp78de

1

Kiểm tra liên kết này https://3v4l.org/hPAto

Công cụ trực tuyến hiển thị khả năng tương thích mã cho các phiên bản PHP khác nhau

Theo công cụ này, mã

unset($_SESSION['signup_errors']);

sẽ hoạt động cho PHP> = 5.4.0 mà không cung cấp cho bạn bất kỳ thông báo / cảnh báo / lỗi nào.

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.