PHP sprawdza, czy właściwość istnieje w obiekcie lub klasie

159

Rozumiem, że PHP nie ma czystej zmiennej obiektu, ale chcę sprawdzić, czy właściwość znajduje się w danym obiekcie lub klasie.

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

lub

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

W JS mogę napisać to, aby sprawdzić, czy zmienna aistnieje w obiekcie:

if ('a' in ob)

Czy w PHP można zrobić coś takiego?

Bardzo dziękuję za twoją poradę.

Micheasza
źródło
2
Wspomnę tylko ... kiedy robimy OOP, mówimy właściwość, a nie zmienna, jak mówimy metoda, a nie funkcja.
Christopher Bonitz,

Odpowiedzi:

254

property_exists (mieszana klasa $, ciąg $ właściwość)

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

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

if (isset($ob->a))

isset () zwróci false, jeśli właściwość ma wartość null

Przykład 1:

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

Przykład 2:

class Foo
{
   public $bar = null;
}

$foo = new Foo();

var_dump(property_exists($foo, 'bar')); // true
var_dump(isset($foo->bar)); // false
Piotr
źródło
12
Niekoniecznie, jeśli właściwość istnieje, ale nie jest zdefiniowana, funkcja isset () zwróci wartość false. us3.php.net/manual/en/types.comparisons.php
Mitchell
isset () można łączyć z funkcją empty (), aby sprawdzić zarówno właściwość, jak i wartość.
4
Chociaż isset () jest błędną odpowiedzią, jeśli wiesz o zastrzeżeniu, jest ono znacznie szybsze niż property_exists ()
Nico Westerdale,
czy to sytuacja, w której empty()jest lepsze rozwiązanie? !empty($var)?
b_dubb,
1
@b_dubb no, empty array, 0, false, null, '' all return true by `empty () '
Piotr
61

Aby sprawdzić, czy właściwość istnieje i czy też jest pusta, możesz użyć funkcji property_exists().

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

W przeciwieństwie do isset (), property_exists () zwraca TRUE, nawet jeśli właściwość ma wartość NULL.

bool property_exists (mieszana klasa $, ciąg $ właściwość)

Przykład:

if (property_exists($testObject, $property)) {
    //do something
}
Chiara Perino
źródło
7
Należy to oznaczyć jako zaakceptowaną odpowiedź, ponieważ odpowiada ona na wyraźną odpowiedź bardzo precyzyjnie. isset nie jest przydatne do testowania istnienia właściwości w obiekcie.
Christopher Bonitz,
11

Ani isset, ani property_exists nie działają dla mnie.

  • isset zwraca false, jeśli właściwość istnieje, ale ma wartość NULL.
  • property_exists zwraca wartość true, jeśli właściwość jest częścią definicji klasy obiektu, nawet jeśli nie została ustawiona.

Skończyło się na:

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

Przykład:

    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
źródło
property_exist + unset property może powodować błędne zachowanie. To wydaje się być najbezpieczniejszą metodą
Thanh Trung
array_key_exists () jest
przestarzała
Słowo kluczowe w "Używanie array_key_exists () na obiektach jest przestarzałe" to obiekty. get_object_vars () zwraca tablicę, więc nadal jesteśmy dobrzy.
smariot
7

Rozwiązanie

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

Aby pokazać, jak to wyglądałoby w oświadczeniu if, aby uzyskać większą jasność, jak to działa.

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

Wyjaśnienie

Tradycyjny sposób PHP na sprawdzenie, czy coś istnieje, to:

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

LUB w sposób bardziej specyficzny dla klasy:

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

Oba są dobre w długich oświadczeniach, ale w potrójnych oświadczeniach stają się niepotrzebnie uciążliwe, jak na przykład:

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

Możesz to również osiągnąć za pomocą tylko operatora trójskładnikowego, takiego jak ten:

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

Ale ... jeśli wartość nie istnieje (nie jest ustawiona), podniesie wartość E_NOTICEi nie jest najlepszą praktyką. Jeśli wartość jest równa null, nie zgłosi wyjątku.

Dlatego trójskładnikowy operator na ratunek czyni tę zgrabną małą odpowiedź:

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

Obrabować
źródło
Świetne wyjaśnienie!
DasBen
4

Jeśli chcesz wiedzieć, czy właściwość istnieje w instancji klasy, którą zdefiniowałeś, po prostu połącz ją property_exists()z isset().

public function hasProperty($property)
{
    return property_exists($this, $property) && isset($this->$property);
}
Anthony Rutledge
źródło
1
Wywołanie property_exists($this, $property)jest tutaj trochę zbędne, ponieważ twój kod zawsze będzie miał taki sam wynik jak isset($this->$property)sam.
MarthyM
Jest to pełniejsza analiza faktów, ponieważ isset()nie można stwierdzić, czy właściwość jest prawdziwym członkiem definicji klasy. Później spojrzę w górę, aby się upewnić.
Anthony Rutledge
To prawda, dane wyjściowe będą takie same dla rzeczywistych właściwości klasy. Jeśli masz właściwości wirtualne z metodami magicznymi __get()i co ważniejsze __isset(), dane wyjściowe będą w niektórych przypadkach inne.
MarthyM
1

Aby sprawdzić, czy coś się kończy, możesz użyć funkcji PHP isset (), patrz php.net . Ta funkcja sprawdzi, czy zmienna jest ustawiona i czy nie ma wartości NULL.

Przykład:

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

Jeśli chcesz sprawdzić, czy właściwość istnieje w klasie, możesz użyć wbudowanej funkcji property_exists ()

Przykład:

if (property_exists('class', $property)) {
    //do something
}
Tjoene
źródło
1

Używanie array_key_exists () na obiektach jest przestarzałe w php 7.4

Zamiast tego należy użyć isset () lub property_exists ()

odniesienie: php.net

Ali_Hr
źródło
0

Umieszczam tutaj moje 2 centy.

Biorąc pod uwagę następującą klasę:

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

wydarzy się co następuje:

$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

Mam nadzieję, że to pomoże każdemu

Zwycięzca
źródło