PHP перевірити, чи існує властивість в об'єкті чи класі


159

Я розумію, що в PHP немає чистої змінної об'єкта, але я хочу перевірити, чи є властивість у даному об'єкті чи класі.

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

або

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

У JS я можу написати це, щоб перевірити, чи aіснує змінна в об'єкті:

if ('a' in ob)

У PHP можна зробити щось подібне?

Дуже дякую за пораду.


2
Згадуючи лише ... коли ми робимо OOP, ми говоримо, що властивість не є змінною, як, наприклад, метод, а не функція.
Крістофер Боніц

Відповіді:


254

property_exists (змішаний $ клас, рядок $ властивості)

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

isset (змішаний $ var [, змішаний $ ...])

if (isset($ob->a))

isset () поверне помилкове значення, якщо властивість недійсна

Приклад 1:

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

Приклад 2:

class Foo
{
   public $bar = null;
}

$foo = new Foo();

var_dump(property_exists($foo, 'bar')); // true
var_dump(isset($foo->bar)); // false

12
Не обов'язково, якщо властивість існує, але вона не визначена, isset () поверне помилкове значення. us3.php.net/manual/en/types.comparisons.php
Мітчелл

isset () може поєднуватися з порожнім (), щоб перевірити як властивість, так і значення.

4
Хоча isset () - неправильна відповідь, якщо ви знаєте про застереження, це значно швидше, ніж property_exists ()
Ніко Вестердейл

це ситуація, коли empty()краще рішення? !empty($var)?
b_dubb

1
@b_dubb ні, порожній масив, 0, false, null, "" все повертається істиною через `empty () '
Петро

61

Щоб перевірити, чи існує властивість, і чи він також недійсний, ви можете скористатися функцією property_exists().

Документи: http://php.net/manual/en/function.property-exists.php

На відміну від isset (), property_exists () повертає TRUE, навіть якщо властивість має значення NULL.

bool property_exists (змішаний $ клас, рядок $ властивість)

Приклад:

if (property_exists($testObject, $property)) {
    //do something
}

7
Це слід позначити як прийняту відповідь, оскільки вона відповідає чітко. isset не корисний для перевірки існування властивості в об'єкті.
Крістофер Боніц

11

Ні isset, ні property_exists не працюють для мене.

  • isset повертає false, якщо властивість існує, але NULL.
  • property_exists повертає true, якщо властивість є частиною визначення класу об'єкта, навіть якщо воно було встановлено.

Я закінчив:

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

Приклад:

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

property_exist + unset властивість може спричинити помилку поведінки. Це здається найбезпечнішим методом
Thanh Trung

array_key_exists () застаріло в php 7.4
Ali_Hr

Ключове слово в "Використання array_key_exists () для об'єктів застаріле" - це об'єкти. get_object_vars () повертає масив, тому ми все ще хороші.
smariot

7

Рішення

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

Щоб показати, як це виглядатиме в операторі if, щоб отримати більш чітку інформацію про те, як це працює.

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

Пояснення

Традиційний спосіб PHP перевірити наявність чогось - це зробити:

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

АБО для більш конкретного класу:

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

Вони є обома чудовими у висловлюваннях тривалої форми, але у потрійних висловлюваннях вони стають надмірно громіздкими так:

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

Ви також можете досягти цього лише за допомогою трійкового оператора:

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

Але ... якщо значення не існує (не встановлено), воно підвищить E_NOTICEі не є найкращою практикою. Якщо це значення, nullце не призведе до винятку.

Тому потрійний оператор на допомогу робить це акуратною маленькою відповіддю:

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


Чудове пояснення!
DasBen

4

Якщо ви хочете знати , якщо властивість існує в разі класу , який ви визначили, просто об'єднати property_exists()з isset().

public function hasProperty($property)
{
    return property_exists($this, $property) && isset($this->$property);
}

1
Дзвінки тут property_exists($this, $property)є надлишковими, оскільки ваш код завжди матиме такий же результат, як і isset($this->$property)один.
MarthyM

Це більш повне вивчення фактів, оскільки isset()не може сказати, чи властивість є справжнім членом визначення класу. Пізніше я загляну вгору, щоб переконатися.
Ентоні Ратлідж

Це правда, вихід буде однаковий для фактичних властивостей класу. Якщо у вас є віртуальні властивості з, __get()і що ще важливіше, __isset()магічні методи, вихід у деяких випадках буде різним.
MarthyM

1

Щоб перевірити, чи щось не відбувається, ви можете скористатися функцією PHP isset (), див. Php.net . Ця функція перевірить, чи встановлена ​​змінна та не NULL.

Приклад:

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

Якщо вам потрібно перевірити, чи існує властивість у класі, ви можете використовувати функцію вбудованого властивості property_exists ()

Приклад:

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

1

Використання array_key_exists () для об'єктів застаріло в php 7.4

Натомість слід використовувати або isset (), або property_exists ()

довідка: php.net


0

Просто кладу мої 2 центи тут.

Дано наступний клас:

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

станеться наступне:

$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

Сподіваюся, що це допоможе комусь

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.