¿Cómo comprobar que un objeto está vacío en PHP?

Respuestas:

130

Puede convertir a una matriz y luego verificar si está vacía o no

$arr = (array)$obj;
if (!$arr) {
    // do stuff
}
Peter Kelly
fuente
9
El encasillado no me funciona, porque me sale el error: Error de PHP Parse: error de sintaxis, inesperado '(matriz)' (matriz) (T_ARRAY_CAST) en ... Yo uso PHP versión 5.4.28 y la primera opción con dos líneas de código funcionan para mí.
Coanda
Tuvo el mismo error al subir un plugin de WordPress, parece que también usan una versión anterior de PHP.
Asaf
4
vacío en realidad no comprueba si una matriz está vacía, empty($var)equivalente a (!isset($var) || !$var). Puede reemplazar su empty($arr)s con !$arrdesdearray() == FALSE
Timothy Zorn
2
La razón por la empty((array) $obj)que no funciona en PHP 5.4+ no tiene nada que ver con el encasillado en una línea. Obtiene el error porque empty()toma una referencia a las variables que se le pasan, y no puede obtener una referencia al encasillar a menos que primero almacene esa variable en otra variable. Hace esto debido a lo que describí en mi comentario anterior. Es bastante frustrante que esta sea la respuesta aceptada, ya que puede llevar a las personas a creer que empty()comprueba si una matriz está "vacía", lo cual no es cierto; eso es solo un efecto secundario de lo que realmente hace.
Timothy Zorn
¿Funcionará en php 7+, o es la forma correcta de solucionarlo?
kantsverma
32

Editar : No me di cuenta de que querían verificar específicamente si un objeto SimpleXMLElement está vacío. Dejé la vieja respuesta a continuación

Respuesta actualizada (SimpleXMLElement) :

Para SimpleXMLElement:

Si por vacío quiere decir que no tiene propiedades:

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

O

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

Si SimpleXMLElement tiene un nivel de profundidad, y por vacío, en realidad quiere decir que solo tiene propiedades que PHP considera falsey (o ninguna propiedad):

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

Si SimpleXMLElement tiene más de un nivel de profundidad, puede comenzar convirtiéndolo en una matriz pura:

$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
}


Respuesta anterior (objeto simple) :

Si desea verificar si un objeto simple (tipo stdClass) está completamente vacío (sin claves / valores), puede hacer lo siguiente:

// $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";
}

Fuente: http://php.net/manual/en/language.oop5.object-comparison.php

Editar : ejemplo agregado

$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
Timothy Zorn
fuente
No funciona en PHP7.2:PHP Warning: Uncaught Error: Call to undefined method stdClass::count()
Juha Untinen
2
@ juha-untinen La solución con ->count()es específicamente para instancias de SimpleXMLElementy no para instancias de stdClass. Creo que todo esto todavía funciona en PHP7.2.
Timothy Zorn
21

Puede convertir su objeto en una matriz y probar su recuento de esta manera:

if(count((array)$obj)) {
   // doStuff
}
Mohamed23gharbi
fuente
12

Imagínese si el objeto no está vacío y de alguna manera es bastante grande, ¿por qué desperdiciaría los recursos para convertirlo en una matriz o serializarlo ...

Esta es una solución muy fácil que uso en JavaScript. A diferencia de la solución mencionada que lanza un objeto a una matriz y verifica si está vacío, o para codificarlo en JSON, esta función simple es muy eficiente con respecto a los recursos utilizados para realizar una tarea simple.

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

    return TRUE;
}

La solución funciona de una manera muy simple: no entrará en ningún bucle foreach si el objeto está vacío y volverá true. Si no está vacío, ingresará al foreachbucle y regresará de falseinmediato, sin pasar por todo el conjunto.

stamat
fuente
8

El uso empty()no funcionará como de costumbre cuando se usa en un objeto, porque en su __isset()lugar se llamará al método de sobrecarga, si se declara.

Por lo tanto, puede usar count()(si el objeto es contable ).

O usando get_object_vars(), por ejemplo

get_object_vars($obj) ? TRUE : FALSE;
Kenorb
fuente
7

Otra posible solución que no necesita fundición para 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 ) );
biziclop
fuente
2

no existe una forma segura única de comprobar si un objeto está vacío

count () de php se lanza primero a la matriz, pero la conversión puede producir una matriz vacía, depende de cómo se implemente el objeto (los objetos de las extensiones a menudo se ven afectados por esos problemas)

en su caso, debe usar $ obj-> count ();

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

(ese no es el recuento de php http://www.php.net/count )


fuente
1

Si lanza algo en PHP como (bool), le dirá de inmediato si el elemento es un objeto, tipo primitivo o nulo. Utilice el siguiente código:

$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!";
}
Roosevelt
fuente
1
incorrecto. $ x = nuevo \ stdClass (); var_dump ((bool) $ x); imprime 'verdadero'; En su caso, simpleXml puede devolver falso en algunos casos
Quamis
Correcto. new stdClass () es un objeto válido, por eso es cierto. El manual de PHP dice, simplexml_load_file (), "Devuelve un objeto de clase SimpleXMLElement con propiedades que contienen los datos contenidos en el documento XML, o FALSE en caso de falla". Entonces, si lanza (bool) simplexml_load_file (), será verdadero (porque la función devolvió un objeto) pero falso (porque la función devolvió falso).
Roosevelt
0

Si un objeto está "vacío" o no es una cuestión de definición, y debido a que depende de la naturaleza del objeto que representa la clase, le corresponde a la clase definirlo.

PHP mismo considera que cada instancia de una clase no está vacía.

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

// results in bool(false)

No puede haber una definición genérica para un objeto "vacío". En el ejemplo anterior, podría argumentar que el resultado de empty()debería ser true, porque el objeto no representa ningún contenido. Pero, ¿cómo saber PHP? Algunos objetos nunca están destinados a representar contenido (piense en las fábricas, por ejemplo), otros siempre representan un valor significativo (piense new DateTime()).

En resumen, tendrá que crear sus propios criterios para un objeto específico y probarlos en consecuencia, ya sea desde fuera del objeto o desde un isEmpty()método autoescrito en el objeto.

nem75
fuente
0
$array = array_filter($array);
if(!empty($array)) {
    echo "not empty";
}

o

if(count($array) > 0) {
    echo 'Error';
} else {
    echo 'No Error';
}
Muhammad Tahir
fuente
Si bien esto puede responder a la pregunta, siempre es una buena idea incluir algo de texto en su respuesta para explicar lo que está haciendo. Lea cómo escribir una buena respuesta .
Jørgen R
-1

Estaba usando un json_decode de una cadena en la solicitud de publicación. Nada de lo anterior funcionó para mí, al final usé esto:

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

if(json_encode($post_vals->object) != '{}')
{
    // its not empty
}
Frank Conry
fuente