属性 存在但 property_exists() return 错误;

Property exists but property_exists() return false;

好吧,我真的很困惑。 当我检查 属性 是否存在时,它 returns 为假。

if (property_exists($pais, 'id'))
// false

但是当我调试时它显示它在那里。

print_r($pais->id);
// 1
print_r(property_exists($pais, 'id'));
// false

我是疯了还是我的神经元炸了?

pais 的创建由

完成
if (key_exists('country', $data))
    $pais = Pais::adicionarPais($data);

(...) 

public static function adicionarPais(array $data)
{
    return Pais::firstOrCreate(['nome' => $data['country']]);
}

我看到您使用的是 Laravel,所以我猜这是 Eloquent 型号。他们可能正在使用魔术方法从您的数据库列创建动态属性和方法。看这里:http://php.net/manual/en/language.oop5.overloading.php

因此,每次您请求 属性 时,他们将检查是否有任何列或关系,而不是拥有真正的属性,而 return 则相反。

您可以使用 getAttributes() 方法获取您的模型属性 (https://github.com/illuminate/database/blob/master/Eloquent/Concerns/HasAttributes.php#L851)

class Pais
{
    public function __get($name) {
        if ($name == 'id') {
            return 1;
        }
    }
}
$pais = new Pais();
var_dump($pais->id); // int(1)
var_dump(property_exists($pais, 'id')); // bool(false)

您可以将模型转换为数组,然后使用array_key_exists。 Eloquent 对象属性是通过魔术方法设置的,因此 property_exists 将不起作用,特别是如果 属性 实际上确实存在但设置为 null.

示例:

$pais = Pais::find(1);

if (array_key_exists('country', $pais->toArray())) {
    // do stuff
}

注意模型上toArray的使用。

无需通读所有内容,如果您勤奋并想检查 getAttributestoArray Laravel 的功能 return 以及发生了什么,我们可以结合使用 issetis_null PHP 核心功能。我在这里专注于 Laravel 和相应的关系,这是一个更复杂的例子,但所有其他变体都可以从下面的代码中提取。享受,我希望它能节省时间。 让我尝试用完整的证明 Laravel 示例和 Artisan Tinker 来详细说明。

请多多包涵。

谢谢PHPArtisan修补匠!

/**
 * @return \Illuminate\Database\Eloquent\Model|HasMany|object|null
 */
public function profile(): HasMany
{
    return $this->hasMany(User_profile::class, 'user_id', 'user_id')
        ->orderBy('created_at', 'desc');
}
php artisan tinker

>>> $u = (new App\Models\User())->find(11549)
=> App\Models\User {#3481
     user_id: 11549,
     created_at: "2019-10-31 09:26:14",
     updated_at: "2019-10-31 09:26:14",
     first_name: "Pippy",
     middle_name: null,
     last_name: "Longstocking",
     phone: null,
     email: "11544@example.com",
     pincode: null,
     flag_is_active: 0,
     flag_is_email_subscribed: 1,
     flag_is_mobile_subscribed: 1,
     flag_terms_agreed: 1,
     flag_is_blocked: 0,
     flag_delete: 0,
     where_from: 1,
     employee_status: 0,
     remember_token: null,
     user_reference: "11544",
     alternate_user_reference: "11544",
     user_transaction_reference: null,
     user_channel: null,
     campaign_id: 0,
     ip_address: "172.31.10.23",
   }

>>> $u->profile()
=> Illuminate\Database\Eloquent\Relations\HasMany {#3483}

>>> $userProfile=$u->profile()->first();
=> null

>>> $userProfile->flag_ifisa
PHP Notice:  Trying to get property 'flag_ifisa' of non-object in Psy Shell code on line 1

>>> $userProfile->toArray()
PHP Error:  Call to a member function toArray() on null in Psy Shell code on line 1

>>> $userProfile->getAttributes()
PHP Error:  Call to a member function getAttributes() on null in Psy Shell code on line 1

>>> is_null($userProfile)
=> true

>>> isset($userProfile->flag_ifisa)
=> false

我正在使用 Laravel 并且遇到了同样的问题。

$this->getAttributes()property_exists()组合不起作用,因为property_exists()只对对象有效,而类,所以你需要isset()array_key_exists().

isset() 的问题在于,如果键存在但值为 null,则它 returns 为假,因此它与 property_exists() 不同。 array_key_exists() 的行为类似于 property_exists() 但自 PHP 7.4.

以来已弃用

解决方案:将数组转换为对象,并使用 property_exists():

property_exists((object)$this->getAttributes(), $key)