Як перевірити, чи об’єкт порожній у PHP?


104

Як дізнатися, чи об’єкт порожній чи ні в PHP.

Далі йде код, у якому $objзберігаються XML-дані. Як я можу перевірити, чи порожній він чи ні?

Мій код:

$obj = simplexml_load_file($url);


Відповіді:


130

Ви можете надіслати масив і перевірити, чи він порожній чи ні

$arr = (array)$obj;
if (!$arr) {
    // do stuff
}

9
Класифікація не працює для мене, тому що я отримую помилку: помилка розбору PHP : помилка синтаксису, несподівана '(масив)' (масив) (T_ARRAY_CAST) в ... Я використовую PHP версії 5.4.28 і перший варіант з для мене працює два рядки коду.
Коанда

Якщо була така ж помилка при завантаженні плагіна WordPress, схоже, вони також використовують старішу версію PHP.
Асаф

4
empty насправді не перевіряє, чи масив порожній, що empty($var)еквівалентно (!isset($var) || !$var). Ви можете замінити empty($arr)з з !$arrмоментуarray() == FALSE
Тімоті Зорн

2
Причина empty((array) $obj)не працює в PHP 5.4+ і не має нічого спільного з набором тексту на одному рядку. Ви отримуєте помилку, оскільки empty()посилається на передані до неї змінні, і вона не може отримати посилання під час набору даних, якщо ви спочатку не збережете цю введену змінну в іншій змінній. Це робиться через те, що я описав у своєму попередньому коментарі. Це досить засмучує, що це прийнята відповідь, оскільки це може змусити людей повірити, що empty()перевіряє, чи масив "порожній", що не відповідає дійсності - це лише побічний ефект від того, що він насправді робить.
Тимофій Зорн

Чи буде вона працювати в php 7+, або це правильний спосіб її виправити.
канцверма

32

Редагувати : Я не розумів, що вони хочуть спеціально перевірити, чи об'єкт SimpleXMLElement порожній. Я залишив стару відповідь нижче

Оновлений відповідь (SimpleXMLElement) :

Для SimpleXMLElement:

Якщо під порожнім значенням у вас немає властивостей:

$obj = simplexml_load_file($url);
if ( !$obj->count() )
{
    // no properties
}

АБО

$obj = simplexml_load_file($url);
if ( !(array)$obj )
{
    // empty array
}

Якщо SimpleXMLElement є глибиною одного рівня, а під порожнім ви фактично маєте на увазі, що він має лише властивості, PHP вважає фальси (або відсутні властивості):

$obj = simplexml_load_file($url);
if ( !array_filter((array)$obj) )
{
    // all properties falsey or no properties at all
}

Якщо SimpleXMLElement глибший на один рівень, ви можете почати, перетворивши його в чистий масив:

$obj = simplexml_load_file($url);
// `json_decode(json_encode($obj), TRUE)` can be slow because
// you're converting to and from a JSON string.
// I don't know another simple way to do a deep conversion from object to array
$array = json_decode(json_encode($obj), TRUE);
if ( !array_filter($array) )
{
    // empty or all properties falsey
}


Стара відповідь (простий об’єкт) :

Якщо ви хочете перевірити, чи простий об’єкт (тип stdClass) повністю порожній (немає ключів / значень), ви можете зробити наступне:

// $obj is type stdClass and we want to check if it's empty
if ( $obj == new stdClass() )
{
    echo "Object is empty"; // JSON: {}
}
else
{
    echo "Object has properties";
}

Джерело: http://php.net/manual/en/language.oop5.object-comppare.php

Правка : доданий приклад

$one = new stdClass();
$two = (object)array();

var_dump($one == new stdClass()); // TRUE
var_dump($two == new stdClass()); // TRUE
var_dump($one == $two); // TRUE

$two->test = TRUE;
var_dump($two == new stdClass()); // FALSE
var_dump($one == $two); // FALSE

$two->test = FALSE;
var_dump($one == $two); // FALSE

$two->test = NULL;
var_dump($one == $two); // FALSE

$two->test = TRUE;
$one->test = TRUE;
var_dump($one == $two); // TRUE

unset($one->test, $two->test);
var_dump($one == $two); // TRUE

Не працює в PHP7.2:PHP Warning: Uncaught Error: Call to undefined method stdClass::count()
Juha Untinen

2
@ juha-untinen Рішення ->count()спеціально для примірників, SimpleXMLElementа не для примірників stdClass. Я вважаю, що все це все ще працює в PHP7.2.
Тимофій Зорн


12

Уявіть собі, якщо об’єкт не порожній і в досить-таки великому розмірі, навіщо ви витрачаєте ресурси, щоб передати його на масив чи серіалізацію ...

Це дуже просте рішення, яке я використовую в JavaScript. На відміну від згаданого рішення, яке кидає об'єкт для масиву та перевірки, чи він порожній, або для кодування його в JSON, ця проста функція є дуже ефективною щодо використаних ресурсів для виконання простого завдання.

function emptyObj( $obj ) {
    foreach ( $obj AS $prop ) {
        return FALSE;
    }

    return TRUE;
}

Рішення працює дуже просто: Він взагалі не вводить цикл foreach, якщо об’єкт порожній і він повернеться true. Якщо він не порожній, він увійде в foreachцикл і повернеться falseвідразу, не проходячи через весь набір.


8

Використання empty()не буде працювати, як зазвичай, при використанні його на об’єкті, оскільки __isset()замість цього буде викликаний метод перевантаження, якщо оголошено.

Тому ви можете використовувати count()(якщо об'єкт є лічильним ).

Або використовуючи get_object_vars(), наприклад,

get_object_vars($obj) ? TRUE : FALSE;

7

Ще одне можливе рішення, яке не потребує кастингу для array:

// test setup
class X { private $p = 1; } // private fields only => empty
$obj = new X;
// $obj->x = 1;


// test wrapped into a function
function object_empty( $obj ){
  foreach( $obj as $x ) return false;
  return true;
}


// inline test
$object_empty = true;
foreach( $obj as $object_empty ){ // value ignored ... 
  $object_empty = false; // ... because we set it false
  break;
}


// test    
var_dump( $object_empty, object_empty( $obj ) );

2

не існує єдиного безпечного способу перевірити, чи об’єкт порожній

php count () спочатку кидає масив, але кастинг може створити порожній масив, залежить від способу реалізації об'єкта (об'єкти розширень часто впливають на ці проблеми)

у вашому випадку вам доведеться використовувати $ obj-> count ();

http://it.php.net/manual/en/simplexmlelement.count.php

(це не число PHP http://www.php.net/count )


1

Якщо ви киньте що-небудь у PHP як (bool), воно відразу скаже вам, чи є об'єктом, примітивним типом або null. Використовуйте наступний код:

$obj = simplexml_load_file($url);

if (!(bool)$obj) {
    print "This variable is null, 0 or empty";
} else {
    print "Variable is an object or a primitive type!";
}

1
неправильно. $ x = новий \ stdClass (); var_dump ((bool) $ x); друкує «справжній»; У вашому випадку simpleXml може повернути помилку в деяких випадках
Quamis

Правильно. новий stdClass () - дійсний об'єкт, тому це правда. Посібник PHP каже simplexml_load_file (), "Повертає об'єкт класу SimpleXMLElement з властивостями, що містять дані, що містяться в документі XML, або FALSE при відмові". Отже, якщо ви кинете (bool) simplexml_load_file (), це буде правдою (тому що функція повертає об'єкт), але неправдивою (тому що функція повертається помилковою).
рузвельт

0

Якщо об’єкт "порожній" чи ні, це питання визначення, і оскільки це залежить від природи об'єкта, який представляє клас, це визначає клас.

Сам PHP вважає кожен примірник класу не порожнім.

class Test { }
$t = new Test();
var_dump(empty($t));

// results in bool(false)

Не може бути загального визначення для "порожнього" об'єкта. Ви можете стверджувати, що у наведеному вище прикладі результат empty()повинен бути true, тому що об'єкт не представляє ніякого вмісту. Але як знати PHP? Деякі об'єкти ніколи не мають на меті представляти вміст (наприклад, фабрики думок), інші завжди представляють значущу цінність (думають new DateTime()).

Коротше кажучи, вам доведеться придумати власні критерії для конкретного об'єкта та перевірити їх відповідно або поза об'єктом, або з самостійно написаного isEmpty()методу в об'єкті.



-1

Я використовував json_decode рядка в запиті на пост. Ніщо з вищезгаданого не працювало для мене, врешті-решт я використав це:

$post_vals = json_decode($_POST['stuff']);

if(json_encode($post_vals->object) != '{}')
{
    // its not empty
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.