PHP vérifie si la propriété existe dans l'objet ou la classe

159

Je comprends que PHP n'a pas de variable objet pur, mais je veux vérifier si une propriété est dans l'objet ou la classe donné.

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

ou

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

Dans JS, je peux écrire ceci pour vérifier si une variable aexiste dans un objet:

if ('a' in ob)

En PHP, peut - on faire quelque chose comme ça?

Merci beaucoup pour votre conseil.

Michée
la source
2
En mentionnant simplement ... quand nous faisons la POO, nous disons propriété non variable, comme nous disons méthode, pas fonction.
Christopher Bonitz

Réponses:

254

property_exists (mixte $ class, chaîne $ property)

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

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

if (isset($ob->a))

isset () retournera false si la propriété est nulle

Exemple 1:

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

Exemple 2:

class Foo
{
   public $bar = null;
}

$foo = new Foo();

var_dump(property_exists($foo, 'bar')); // true
var_dump(isset($foo->bar)); // false
Peter
la source
12
Pas nécessairement, si la propriété existe mais n'est pas définie, isset () retournera false. us3.php.net/manual/en/types.comparisons.php
Mitchell
isset () peut être combiné avec empty () pour vérifier à la fois la propriété et la valeur.
4
Bien que isset () soit la mauvaise réponse, si vous êtes conscient de la mise en garde, elle est considérablement plus rapide que property_exists ()
Nico Westerdale
est-ce une situation où empty()existe une meilleure solution? !empty($var)?
b_dubb
1
@b_dubb no, empty array, 0, false, null, '' all return true by `empty () '
Peter
61

Pour vérifier si la propriété existe et si elle est également nulle, vous pouvez utiliser la fonction property_exists().

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

Contrairement à isset (), property_exists () renvoie TRUE même si la propriété a la valeur NULL.

booléen property_exists (mixed $ class, string $ property)

Exemple:

if (property_exists($testObject, $property)) {
    //do something
}
Chiara Perino
la source
7
Cela devrait être marqué comme la réponse acceptée car elle répond à la réponse explicite très précise. isset n'est pas utile pour tester l'existence d'une propriété dans un objet.
Christopher Bonitz
11

Ni isset ni property_exists ne fonctionnent pour moi.

  • isset renvoie false si la propriété existe mais est NULL.
  • property_exists renvoie true si la propriété fait partie de la définition de classe de l'objet, même si elle n'a pas été définie.

J'ai fini par y aller avec:

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

Exemple:

    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
la source
property_exist + propriété unset peut provoquer un comportement bogué. Cela semble être la méthode la plus sûre
Thanh Trung
array_key_exists () est obsolète en php 7.4
Ali_Hr
Le mot clé dans "L'utilisation de array_key_exists () sur des objets est obsolète" est des objets. get_object_vars () renvoie un tableau, donc nous sommes toujours bons.
smariot
7

Solution

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

Pour montrer à quoi cela ressemblerait dans une instruction if pour plus de clarté sur la façon dont cela fonctionne.

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

Explication

La manière traditionnelle PHP de vérifier l'existence de quelque chose est de faire:

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

OU pour une manière plus spécifique à la classe:

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

Ce sont tous les deux très bien dans les déclarations de forme longue, mais dans les déclarations ternaires, ils deviennent inutilement encombrants comme ceci:

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

Vous pouvez également y parvenir avec juste l'opérateur ternaire comme ceci:

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

Mais ... si la valeur n'existe pas (n'est pas définie), elle lèvera un E_NOTICEet ce n'est pas la meilleure pratique. Si la valeur est, nullelle ne lèvera pas l'exception.

Par conséquent, l'opérateur ternaire à la rescousse, ce qui en fait une petite réponse intéressante:

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

Rob
la source
Excellente explication!
DasBen
4

Si vous voulez savoir si une propriété existe dans une instance d'une classe que vous avez définie, combinez simplement property_exists()avec isset().

public function hasProperty($property)
{
    return property_exists($this, $property) && isset($this->$property);
}
Anthony Rutledge
la source
1
L'appel property_exists($this, $property)est un peu redondant ici, car votre code aura toujours le même résultat que isset($this->$property)seul.
MarthyM
Il s'agit d'un examen plus complet des faits car isset()il ne peut pas vous dire si une propriété est un vrai membre de la définition de classe. Je chercherai à nouveau plus tard pour m'en assurer.
Anthony Rutledge
C'est vrai, la sortie sera la même pour les propriétés de classe réelles. Si vous avez des propriétés virtuelles avec __get()et surtout __isset()des méthodes magiques, la sortie sera différente dans certains cas.
MarthyM
1

Pour vérifier si quelque chose se termine, vous pouvez utiliser la fonction PHP isset () voir php.net . Cette fonction vérifie si la variable est définie et n'est pas NULL.

Exemple:

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

Si vous avez besoin de vérifier si une propriété existe dans une classe, vous pouvez utiliser la fonction intégrée property_exists ()

Exemple:

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

L'utilisation de array_key_exists () sur des objets est obsolète dans php 7.4

Au lieu de cela, isset () ou property_exists () doivent être utilisés

référence: php.net

Ali_Hr
la source
0

Je mets juste mes 2 cents ici.

Compte tenu de la classe suivante:

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);
  }
}

ce qui suit se produira:

$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

J'espère que cela aidera n'importe qui

Victor
la source