PHP kiểm tra xem thuộc tính tồn tại trong đối tượng hay lớp


159

Tôi hiểu PHP không có biến đối tượng thuần túy, nhưng tôi muốn kiểm tra xem một thuộc tính có nằm trong đối tượng hoặc lớp đã cho không.

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

hoặc là

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

Trong JS, tôi có thể viết điều này để kiểm tra xem biến acó tồn tại trong một đối tượng không:

if ('a' in ob)

Trong PHP, có thể làm bất cứ điều gì như thế này không?

Cảm ơn bạn rất nhiều vì lời khuyên của bạn.


2
Chỉ cần đề cập đến ... khi chúng ta thực hiện OOP, chúng ta nói thuộc tính không biến, như chúng ta nói phương thức, không phải chức năng.
Christopher Bonitz

Câu trả lời:


254

property_exists (hỗn hợp $ class, chuỗi $ property)

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

isset (hỗn hợp $ var [, hỗn hợp $ ...])

if (isset($ob->a))

isset () sẽ trả về false nếu thuộc tính là null

Ví dụ 1:

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

Ví dụ 2:

class Foo
{
   public $bar = null;
}

$foo = new Foo();

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

12
Không nhất thiết, nếu thuộc tính tồn tại, nhưng không được xác định ngay lập tức () sẽ trả về false. us3.php.net/manual/en/types.comparisons.php
Mitchell

Ngay lập tức () có thể được kết hợp với khoảng trống () để kiểm tra cả thuộc tính giá trị.

4
Trong khi isset () là câu trả lời sai, nếu bạn nhận thức được cảnh báo thì nó nhanh hơn đáng kể so với property_exists ()
Nico Westerdale 6/218

Đây có phải là một tình huống mà empty()một giải pháp tốt hơn? !empty($var)?
b_dubb

1
@b_dubb không, mảng trống, 0, false, null, '' tất cả trả về true bằng `blank () '
Peter

61

Để kiểm tra xem thuộc tính có tồn tại không và nếu nó cũng không, bạn có thể sử dụng hàm property_exists().

Tài liệu: http://php.net/manual/en/feft.property-exists.php

Trái ngược với isset (), property_exists () trả về TRUE ngay cả khi thuộc tính có giá trị NULL.

bool property_exists (hỗn hợp $ class, chuỗi $ property)

Thí dụ:

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

7
Điều này nên được đánh dấu là câu trả lời được chấp nhận vì nó trả lời câu trả lời rõ ràng rất chính xác. isset không hữu ích để kiểm tra sự tồn tại của một thuộc tính trong một đối tượng.
Christopher Bonitz

11

Không phảietet hay property_exists làm việc cho tôi.

  • Ngay lập tức trả về false nếu thuộc tính tồn tại nhưng là NULL.
  • property_exists trả về true nếu thuộc tính là một phần của định nghĩa lớp của đối tượng, ngay cả khi nó chưa được đặt.

Tôi đã kết thúc với:

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

Thí dụ:

    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 property có thể gây ra hành vi lỗi. Đây dường như là phương pháp an toàn nhất
Thanh Trung

mảng_key_exists () không được dùng trong php 7.4
Ali_Hr

Từ khóa trong "Sử dụng mảng_key_exists () trên các đối tượng không được dùng nữa" là các đối tượng. get_object_vars () trả về một mảng, vì vậy chúng tôi vẫn tốt.
smariot

7

Giải pháp

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

Để cho thấy điều này sẽ trông như thế nào trong một câu lệnh if cho rõ ràng hơn về cách thức hoạt động của nó.

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

Giải trình

Cách PHP truyền thống để kiểm tra sự tồn tại của một cái gì đó là làm:

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

HOẶC cho một cách cụ thể hơn lớp:

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

Cả hai đều ổn trong các câu lệnh dài nhưng trong các câu lệnh ternary chúng trở nên cồng kềnh không cần thiết như vậy:

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

Bạn cũng có thể đạt được điều này chỉ với toán tử ternary như vậy:

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

Nhưng ... nếu giá trị không tồn tại (không được đặt), nó sẽ tăng E_NOTICEvà không phải là cách thực hành tốt nhất. Nếu giá trị là nullnó sẽ không tăng ngoại lệ.

Do đó, nhà điều hành ternary để giải cứu làm cho câu trả lời nhỏ gọn này:

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


Giải thích tuyệt vời!
DasBen

4

Nếu bạn muốn biết nếu một thuộc tính tồn tại trong một thể hiện của một lớp mà bạn đã xác định, chỉ cần kết hợp property_exists()với isset().

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

1
Gọi điện property_exists($this, $property)là loại dư thừa ở đây, vì mã của bạn sẽ luôn có kết quả giống như isset($this->$property)một mình.
MarthyM

Đây là một kiểm tra đầy đủ hơn về các sự kiện vì isset()không thể cho bạn biết nếu một tài sản là một thành viên thực sự của định nghĩa lớp. Tôi sẽ tìm kiếm lại sau để đảm bảo.
Anthony Rutledge

Đó là sự thật, đầu ra sẽ giống nhau cho các thuộc tính lớp thực tế. Nếu bạn có các thuộc tính ảo với __get()và quan trọng hơn là __isset()các phương thức ma thuật, đầu ra sẽ khác trong một số trường hợp.
MarthyM

1

Để kiểm tra xem có cái gì thoát ra không, bạn có thể sử dụng hàm PHPetet () xem php.net . Hàm này sẽ kiểm tra nếu biến được đặt và không phải là NULL.

Thí dụ:

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

Nếu bạn cần kiểm tra xem một thuộc tính có tồn tại trong một lớp hay không, thì bạn có thể sử dụng hàm xây dựng trong hàm property_exists ()

Thí dụ:

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

1

Sử dụng mảng_key_exists () trên các đối tượng không được dùng trong php 7.4

Thay vào đó, nên sử dụng ngay lập tức () hoặc property_exists ()

tham khảo: php.net


0

Chỉ cần đặt 2 xu của tôi ở đây.

Cho lớp sau:

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

Điều sau đây sẽ xảy ra:

$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

Hy vọng điều này sẽ giúp được bất cứ ai

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.