【问题标题】:Property exists but property_exists() return false;属性存在但 property_exists() 返回 false;
【发布时间】:2017-08-18 01:57:52
【问题描述】:

嗯,我真的很困惑。 当我检查属性是否存在时,它返回 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']]);
}

【问题讨论】:

  • $pais 的上下文是什么?它是标准对象还是静态对象?
  • @RobertDeBoer iv 更新了更多信息。

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


【解决方案1】:

我看到你在使用 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)

【讨论】:

  • 是这样的吗,根据PHP文档,那就不行了。 property_exists 不适用于由魔术函数创建的属性。
  • 没错。这就是 $pais->id 返回 1 而 property_exists 返回 false 的原因。
  • 是的,我正在使用 laravel.. 但如果我覆盖它的 __get,雄辩的将停止工作并搞乱所有关系..
  • thanx... 似乎是一个不错的选择。但它有点奇怪。我在其他情况下使用了这段代码......并且工作正常......
  • 因为 ORM 模型很奇怪 :-)
【解决方案2】:

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

例子:

$pais = Pais::find(1);

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

注意在模型上使用toArray

【讨论】:

    【解决方案3】:

    无需经历这一切,然后如果您勤奋并想检查 getAttributestoArray Laravel 函数返回什么以及发生了什么,我们可以使用 issetis_null PHP 核心的组合职能。我在这里专注于 Laravel 和相应的关系,这是一个更复杂的示例,但所有其他变体都可以从下面的代码中提取。享受,我希望它会节省时间。 让我尝试用完整的 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
    
    

    【讨论】:

      【解决方案4】:

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

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

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

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-17
        • 1970-01-01
        相关资源
        最近更新 更多