2009-09-07 32 views
19

Tôi đang đọc dữ liệu JSON bằng PHP và dữ liệu đó chứa các đối tượng trống (như {}). Vì vậy, vấn đề là, tôi phải xử lý các trường hợp khi đối tượng là trống theo cách khác nhau nhưng tôi không thể tìm thấy cách đủ tốt để làm kiểm tra. empty(get_object_vars(object)) trông quá đáng sợ và rất kém hiệu quả. Có cách nào tốt để thực hiện kiểm tra không?Cách kiểm tra xem đối tượng JSON có trống trong PHP không?

+0

liên quan: https://stackoverflow.com/q/9412126/3995261 – YakovL

Trả lời

22

Có bao nhiêu đối tượng Trừ khi empty(get_object_vars($object)) hoặc truyền đến mảng chứng tỏ là một sự chậm lại lớn/nút cổ chai, tôi sẽ không lo lắng về nó - giải pháp của Greg là tốt.

tôi muốn đề nghị sử dụng các $associative cờ khi giải mã dữ liệu JSON, mặc dù:

json_decode($data, true) 

này giải mã đối tượng JSON như đồng bằng mảng PHP cũ thay vì như stdClass đối tượng. Sau đó, bạn có thể kiểm tra các đối tượng trống bằng cách sử dụng empty() và tạo đối tượng của lớp do người dùng xác định thay vì sử dụng stdClass, đây có thể là một ý tưởng hay về lâu dài.

24

Bạn có thể bỏ nó vào một mảng (tiếc là bạn không thể làm điều này trong một cuộc gọi đến empty():

$x = (array)$obj; 
if (empty($x)) 
    ... 

Hoặc đúc để một mảng và count():

if (count((array)$obj)) 
    ... 
+0

Nó không giống với get_object_vars? I E. không thực sự hiệu quả? :) – vava

+2

Tôi chưa thử nghiệm nó nhưng trừ khi bạn đang gặp vấn đề về hiệu suất và đã xác định điều này là nút cổ chai, tôi không nghĩ rằng đáng để bạn lo lắng về nó. – Greg

+1

Nó không phải dễ dàng để ngừng lo lắng về biến đổi mảng không cần thiết nếu bạn là một lập trình viên C++ hầu hết cuộc sống của bạn :) Nó có nghĩa là phân bổ bộ nhớ và sao chép nội dung cho một cái gì đó mà chỉ cần kiểm tra nhanh nếu một bit được thiết lập. – vava

0

Tôi phải nói một đối tượng trống hay không, nhưng tôi cũng phải bỏ qua các thuộc tính riêng tư và được bảo vệ, vì vậy tôi đã thực hiện chức năng nhỏ này mà bạn có thể thực hiện việc này.

function empty_obj(&$object, $ignore_private = true, $ignore_protected = true) { 
    $obj_name = get_class($object); 
    $obj = (array)$object; 

    foreach(array_keys($obj) as $prop) { 
    $is_private = $is_protected = false; 

    $prop = preg_replace("/[^\w*]/", '', $prop); 
    $prop_name = str_replace(array($obj_name, '*'), '', $prop); 

    if(preg_match("~^$obj_name$prop_name$~", $prop)) 
     $is_private = true; 
    if(preg_match("~^\*$prop_name$~", $prop)) 
     $is_protected = true; 

    if(!$is_private || !$is_protected || ($is_private && !$ignore_private) || ($is_protected && !$ignore_protected)) 
     return; 
    } 
    return true; 
} 
0

Tôi không chắc liệu điều này có hiệu quả nhiều hay ít hơn khi truyền sang mảng nhưng tôi đoán nhiều hơn. Bạn chỉ có thể bắt đầu lặp lại đối tượng và ngay sau khi bạn tìm thấy một cái gì đó bạn có một câu trả lời và dừng vòng lặp.

function is_obj_empty($obj){ 
    if(is_null($obj)){ 
     return true; 
    } 
    foreach($obj as $key => $val){ 
     return false; 
    } 
    return true; 
} 
3

Cố gắng mà không sử dụng empty() đó là:

get_object_vars($obj) ? TRUE : FALSE; 

On PHP docs chúng ta có thể đọc lưu ý:

Khi sử dụng empty() trên thuộc tính đối tượng không thể tiếp cận, các __isset() phương pháp quá tải sẽ được gọi là , nếu được khai báo.

Có nghĩa là khi sử dụng empty() trên một đối tượng có phương pháp __get(), nó sẽ luôn trả về True.

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