属性存在但property_exists()返回false;

时间:2017-03-25 00:32:22

标签: php laravel laravel-5 php-7 laravel-5.4

我真的很困惑。 当我检查属性是否存在时,它返回false。

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

4 个答案:

答案 0 :(得分:8)

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

因此,每次您请求某个属性时,他们都会检查是否存在任何列或关系,而不是拥有真正的属性,而是返回该属性。

您可以使用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)

答案 1 :(得分:2)

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

示例:

$pais = Pais::find(1);

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

请注意在模型上使用toArray

答案 2 :(得分:0)

无需全部检查,然后如果您很努力并想查看Laravel函数返回了什么getAttributestoArray,我们可以使用isset的组合和is_null PHP核心功能。我在这里专注于Laravel和对应的Relationip,这是一个更复杂的示例,但是所有其他变体都可以从下面的代码中提取。享受,我希望它将节省时间。 让我尝试详细说明Laravel实例和Artisan Tinker。

请忍受我。

谢谢 PHP Artisan Tinker!

/**
 * @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

答案 3 :(得分:0)

我正在使用Laravel并遇到相同的问题。

$this->getAttributes()property_exists()结合使用不起作用,因为property_exists()仅适用于对象和类,因此您需要isset()array_key_exists()

isset()的问题在于,如果键存在但值是null,则返回false,因此它与property_exists()不同。 array_key_exists()的行为与property_exists()类似,但是自PHP 7.4起已弃用。

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

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