PHP verifica si la propiedad existe en el objeto o la clase

159

Entiendo que PHP no tiene una variable de objeto puro, pero quiero verificar si una propiedad está en el objeto o clase dada.

$ob = (object) array('a' => 1, 'b' => 12); 

o

$ob = new stdClass;
$ob->a = 1;
$ob->b = 2;

En JS, puedo escribir esto para verificar si aexiste una variable en un objeto:

if ('a' in ob)

En PHP, ¿se puede hacer algo así?

Muchas gracias por tu consejo.

Micah
fuente
2
Solo mencionando ... cuando hacemos OOP, decimos propiedad no variable, como decimos método, no función.
Christopher Bonitz

Respuestas:

254

property_exists (clase mixta $, cadena $ propiedad)

if (property_exists($ob, 'a')) 

isset (mixed $ var [, mixed $ ...])

if (isset($ob->a))

isset () devolverá falso si la propiedad es nula

Ejemplo 1:

$ob->a = null
var_dump(isset($ob->a)); // false

Ejemplo 2

class Foo
{
   public $bar = null;
}

$foo = new Foo();

var_dump(property_exists($foo, 'bar')); // true
var_dump(isset($foo->bar)); // false
Peter
fuente
12
No necesariamente, si la propiedad existe, pero no está definida, isset () devolverá falso. us3.php.net/manual/en/types.comparisons.php
Mitchell
isset () se puede combinar con empty () para verificar tanto la propiedad como el valor.
44
Si bien isset () es la respuesta incorrecta, si conoce la advertencia, es considerablemente más rápido que property_exists ()
Nico Westerdale
¿Es esta una situación en la que empty()hay una mejor solución? !empty($var)?
b_dubb
1
@b_dubb no, matriz vacía, 0, falso, nulo '', todos devuelven verdadero por `empty () '
Peter
61

Para verificar si la propiedad existe y si también es nula, puede usar la función property_exists().

Documentos: http://php.net/manual/en/function.property-exists.php

A diferencia de isset (), property_exists () devuelve TRUE incluso si la propiedad tiene el valor NULL.

bool property_exists (clase mixta $, cadena $ propiedad)

Ejemplo:

if (property_exists($testObject, $property)) {
    //do something
}
Chiara Perino
fuente
77
Esto debe marcarse como la respuesta aceptada, ya que responde la respuesta explícita muy precisa. isset no es útil para probar la existencia de una propiedad en un objeto.
Christopher Bonitz
11

Ni isset ni property_exists funcionan para mí.

  • isset devuelve falso si la propiedad existe pero es NULL.
  • property_exists devuelve verdadero si la propiedad es parte de la definición de clase del objeto, incluso si se ha desarmado.

Terminé yendo con:

    $exists = array_key_exists($property, get_object_vars($obj));

Ejemplo:

    class Foo {
        public $bar;

        function __construct() {
            $property = 'bar';

            isset($this->$property); // FALSE
            property_exists($this, $property); // TRUE
            array_key_exists($property, get_object_vars($this)); // TRUE

            unset($this->$property);

            isset($this->$property); // FALSE
            property_exists($this, $property); // TRUE
            array_key_exists($property, get_object_vars($this)); // FALSE

            $this->$property = 'baz';

            isset($this->$property); // TRUE
            property_exists($this, $property); // TRUE
            array_key_exists($property, get_object_vars($this));  // TRUE
        }
    }
smariot
fuente
property_exist + unset property puede causar un comportamiento defectuoso. Este parece ser el método más seguro
Thanh Trung
array_key_exists () está en
desuso
La palabra clave en "El uso de array_key_exists () en objetos está en desuso" es objetos. get_object_vars () devuelve una matriz, por lo que seguimos siendo buenos.
smariot
7

Solución

echo $person->middleName ?? 'Person does not have a middle name';

Para mostrar cómo se vería esto en una declaración if para obtener más claridad sobre cómo funciona esto.

if($person->middleName ?? false) {
    echo $person->middleName;
} else {
    echo 'Person does not have a middle name';
}

Explicación

La forma tradicional de PHP para verificar la existencia de algo es hacer:

if(isset($person->middleName)) {
    echo $person->middleName;
} else {
    echo 'Person does not have a middle name';
}

O para una forma más específica de clase:

if(property_exists($person, 'middleName')) {
    echo $person->middleName;
} else {
    echo 'Person does not have a middle name';
}

Ambos están bien en declaraciones de forma larga, pero en declaraciones ternarias se vuelven innecesariamente engorrosas de esta manera:

isset($person->middleName) ? echo $person->middleName : echo 'Person does not have a middle name';

También puede lograr esto solo con el operador ternario así:

echo $person->middleName ?: 'Person does not have a middle name';

Pero ... si el valor no existe (no está establecido), aumentará E_NOTICEy no es la mejor práctica. Si el valor es, nullno generará la excepción.

Por lo tanto, el operador ternario al rescate hace que esta sea una pequeña y clara respuesta:

echo $person->middleName ?? 'Person does not have a middle name';

Robar
fuente
¡Gran explicación!
DasBen
4

Si desea saber si existe una propiedad en una instancia de una clase que ha definido, simplemente combínela property_exists()con isset().

public function hasProperty($property)
{
    return property_exists($this, $property) && isset($this->$property);
}
Anthony Rutledge
fuente
1
Las llamadas property_exists($this, $property)son algo redundantes aquí, ya que su código siempre tendrá el mismo resultado que isset($this->$property)solo.
MarthyM
Este es un examen más completo de los hechos porque isset()no puede decirle si una propiedad es un miembro verdadero de la definición de clase. Buscaré nuevamente más tarde para asegurarme.
Anthony Rutledge
Eso es cierto, la salida será la misma para las propiedades de clase reales. Si tiene propiedades virtuales __get()y, lo que es más importante __isset(), métodos mágicos, el resultado será diferente en algunos casos.
MarthyM
1

Para verificar si algo existe, puede usar la función PHP isset (), consulte php.net . Esta función verificará si la variable está establecida y no es NULL.

Ejemplo:

if(isset($obj->a))
{ 
  //do something
}

Si necesita verificar si existe una propiedad en una clase, puede usar la función de compilación property_exists ()

Ejemplo:

if (property_exists('class', $property)) {
    //do something
}
Tjoene
fuente
1

El uso de array_key_exists () en objetos está en desuso en php 7.4

En su lugar, se debe usar isset () o property_exists ()

referencia: php.net

Ali_Hr
fuente
0

Solo pongo mis 2 centavos aquí.

Dada la siguiente clase:

class Foo
{
  private $data;

  public function __construct(array $data)
  {
    $this->data = $data;
  }

  public function __get($name)
  {
    return $data[$name];
  }

  public function __isset($name)
  {
    return array_key_exists($name, $this->data);
  }
}

ocurrirá lo siguiente:

$foo = new Foo(['key' => 'value', 'bar' => null]);

var_dump(property_exists($foo, 'key'));  // false
var_dump(isset($foo->key));  // true
var_dump(property_exists($foo, 'bar'));  // false
var_dump(isset($foo->bar));  // true, although $data['bar'] == null

Espero que esto ayude a cualquiera

Víctor
fuente