2010-09-27 42 views
65

Tôi cần kiểm tra xem giá trị có được định nghĩa là bất kỳ giá trị nào không, bao gồm cả giá trị rỗng. isset xử lý các giá trị null dưới dạng không xác định và trả về false. Hãy làm như sau: ví dụ:Kiểm tra nếu giá trị isset và null

$foo = null; 

if(isset($foo)) // returns false 
if(isset($bar)) // returns false 
if(isset($foo) || is_null($foo)) // returns true 
if(isset($bar) || is_null($bar)) // returns true, raises a notice 

Lưu ý rằng $bar không được xác định.

Tôi cần phải tìm một điều kiện thỏa mãn những điều sau đây:

if(something($bar)) // returns false; 
if(something($foo)) // returns true; 

ý tưởng Bất kỳ?

+14

if (isset ($ foo)) // trả về false, tôi bị rơi từ trên ghế, tất cả những năm ... – max4ever

Trả lời

63

IIRC, bạn có thể sử dụng get_defined_vars() cho việc này:

$foo = NULL; 
$vars = get_defined_vars(); 
if (array_key_exists('bar', $vars)) {}; // Should evaluate to FALSE 
if (array_key_exists('foo', $vars)) {}; // Should evaluate to TRUE 
+0

+1 Tôi sẽ đề xuất cùng chức năng, 'get_defined_vars' vui vẻ đối phó với phạm vi. – salathe

+1

Dường như được làm việc, nhưng tôi đã hy vọng cho một cái gì đó đơn giản hơn. Oh well. Hãy xem liệu có ai có thể tìm ra một cái lót không. –

+4

tốt, bạn không cần vars, do đó, trong lý thuyết của nó một dòng "if (array_key_exists ('foo', get_defined_vars())) {}" – Hannes

0

Bạn có thể sử dụng is_nullempty thay vì isset(). Empty không in thông báo lỗi nếu biến không tồn tại.

+0

tôi đang sử dụng is_null. Kết quả là giống nhau bất kể 'isset'. –

+0

Tôi đã phạm sai lầm khi đăng câu trả lời đầu tiên của mình: bạn đã thử với empty() chưa? – Raveline

+0

Điều này sẽ không hoạt động đối với các giá trị không rỗng và không phải NULL như FALSE, 0, array() hoặc "". – C9HDN

12

Xem Best way to test for a variable's existence in PHP; isset() is clearly broken

if(array_key_exists('foo', $GLOBALS) && is_null($foo)) // true & true => true 
if(array_key_exists('bar', $GLOBALS) && is_null($bar)) // false & => false 
+3

Mã bạn trích dẫn chỉ hoạt động nếu biến nằm trong phạm vi toàn cục. – Raveline

+0

Thật vậy nhưng nó không phải là trường hợp thường xuyên nhất? Trong một hàm, bạn sẽ có các biến ở phạm vi toàn cục và các đối số (luôn được xác định). Bạn cũng có thể có các thuộc tính đối tượng nhưng sau đó bạn có thể sử dụng 'property_exists'. –

+0

Sử dụng $ GLOBALS có vẻ hơi dễ bay hơi, tôi phải tự mình thử nghiệm trước khi tôi có thể tuyên bố điều này là đang hoạt động. –

-2

is_null($bar) trả về true, vì nó không có giá trị gì cả. Ngoài ra, bạn có thể sử dụng:

if(isset($bar) && is_null($bar)) // returns false 

để kiểm tra xem $bar được xác định và sẽ chỉ trả lại đúng nếu:

$bar = null; 
if(isset($bar) && is_null($bar)) // returns true 
+0

Không, anh ta nói rằng 'if (isset ($ bar))' cho sai khi '$ bar = null'. –

+0

xấu của tôi. sẽ cập nhật câu trả lời của tôi. – Ruel

+2

Điều này sẽ không vượt qua bất kỳ biến nào khác ngoài null (ví dụ: nếu '$ bar =" test "'). –

0

Dưới đây một số cách giải quyết ngớ ngẩn sử dụng Xdebug. ;-)

function is_declared($name) { 
    ob_start(); 
    xdebug_debug_zval($name); 
    $content = ob_get_clean(); 

    return !empty($content); 
} 

$foo = null; 
var_dump(is_declared('foo')); // -> true 

$bla = 'bla'; 
var_dump(is_declared('bla')); // -> true 

var_dump(is_declared('bar')); // -> false 
+1

Không trông rất cầm tay .. :) –

+1

Thật vậy. Và hiệu suất cũng có thể giảm. ;-) –

1

Các mã sau đây được viết là phần mở rộng PHP là tương đương với array_key_exists ($ name, get_defined_vars()) (nhờ Henrik và Hannes)

// get_defined_vars() 
// https://github.com/php/php-src/blob/master/Zend/zend_builtin_functions.c#L1777 
// array_key_exists 
// https://github.com/php/php-src/blob/master/ext/standard/array.c#L4393 

PHP_FUNCTION(is_defined_var) 
{ 

    char *name; 
    int name_len; 

    if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) == FAILURE) { 
     return; 
    } 

    if (!EG(active_symbol_table)) { 
     zend_rebuild_symbol_table(TSRMLS_C); 
    } 

    if (zend_symtable_exists(EG(active_symbol_table), name, name_len + 1)) { 
     RETURN_TRUE; 
    } 

} 
21

Nếu bạn đang đối phó với các thuộc tính đối tượng whcih có thể có một giá trị NULL bạn có thể sử dụng: property_exists() thay vì isset()

<?php 

class myClass { 
    public $mine; 
    private $xpto; 
    static protected $test; 

    function test() { 
     var_dump(property_exists($this, 'xpto')); //true 
    } 
} 

var_dump(property_exists('myClass', 'mine')); //true 
var_dump(property_exists(new myClass, 'mine')); //true 
var_dump(property_exists('myClass', 'xpto')); //true, as of PHP 5.3.0 
var_dump(property_exists('myClass', 'bar')); //false 
var_dump(property_exists('myClass', 'test')); //true, as of PHP 5.3.0 
myClass::test(); 

?> 

Trái ngược với isset(), property_exists() trả về TRUE ngay cả khi thuộc tính có giá trị NULL.

+7

Bạn có thể làm tương tự cho các mảng với array_key_exists(); – C9HDN

2

Tôi đã phát hiện ra rằng compact là một chức năng mà bỏ qua các biến unset nhưng không hành động dựa trên những thiết lập để null, vì vậy khi bạn có một bảng lớn biểu tượng địa phương tôi sẽ tưởng tượng bạn có thể có được một giải pháp hiệu quả hơn so với kiểm tra array_key_exists('foo', get_defined_vars()) bởi sử dụng array_key_exists('foo', compact('foo')):

$foo = null; 
echo isset($foo) ? 'true' : 'false'; // false 
echo array_key_exists('foo', compact('foo')) ? 'true' : 'false'; // true 
echo isset($bar) ? 'true' : 'false'; // false 
echo array_key_exists('bar', compact('bar')) ? 'true' : 'false'; // false 
+0

Thay thế thú vị. Nhưng lưu ý rằng có thể là * chậm hơn * so với việc gọi array_key_exists trên một mảng hiện có, chẳng hạn như $ GLOBALS - vì tìm kiếm trong bảng băm không nhận được chậm hơn, khi bảng lớn, và bạn đã thêm công việc phụ của 'compact'. Tuy nhiên, tôi đã bình chọn nó vì nó hữu ích trong một tình huống: nếu bạn muốn biết liệu 'foo' tồn tại * trong ngữ cảnh hiện tại *, bất kể nó đến từ đâu - nếu bạn không quan tâm là địa phương hay toàn cục, muốn biết liệu nó có tồn tại hay không. – ToolmakerSteve

+0

@ToolmakerSteve - Tôi đã thực sự đề cập đến chi phí đáng kể có thể gọi là 'get_defined_vars'. Xem [tại đây] (http://stackoverflow.com/questions/27808704/what-is-the-performance-impact-off-get-defined-vars). – nzn

Các vấn đề liên quan