【问题标题】:php laravel strict object castingphp laravel 严格的对象转换
【发布时间】:2021-07-09 12:50:15
【问题描述】:

我意识到当我使用这样的对象转换列时,laravel/eloquent 不会保存我的模型:

$original = '{"test": null}';
$new = '{"test": false}';

原因是转换为对象的属性在 HasAttributes.php::R1577 中是这样评估的(以找出记录是否脏):

 } elseif ($this->hasCast($key, ['object', 'collection'])) {
            return $this->castAttribute($key, $attribute) ==
                $this->castAttribute($key, $original);

即它使用 == 来比较两个对象。所以问题可以像这样重现:

        $original = '{"test": null}';
        $new = '{"test": false}';

        $originalObject = json_decode($original, true);
        $newObject = json_decode($new, true);

        $original == $new; // false
        $originalObject == $newObject; // true <-- this is what laravel does and therefore thinks there was no change
        $originalObject === $newObject; // false <-- this is what I want (unless there is a reason not to do it)

是否有理由使用 == 而不是 === 进行比较?有没有办法强制它使用严格比较?

【问题讨论】:

    标签: php laravel eloquent casting


    【解决方案1】:

    总结

    object 转换将返回一个对象实例。对象的严格比较实际上并不比较任何值,只比较实例引用。要获得所需的比较,您需要切换到 jsonarray 演员表。

    当然,这意味着您的变量现在将是一个关联数组而不是一个对象,并且您的代码需要相应地更新。

    详情

    objectcollection 强制转换将返回一个实际对象(不是数组)的实例。 Laravel 不使用严格比较这些强制转换,因为严格比较对对象和数组的工作方式不同:

    • 对于数组,如果两个数组具有相同的键/值且顺序和类型相同,则严格比较将返回 true。
    • 对于对象,严格比较不比较任何值,只会返回true,两个对象实际上是同一个类的同一个实例。

    由于对象的严格比较会与实例进行比较,因此您显示的 Laravel 代码将始终返回 false,因为您始终在比较两个不同的对象实例(即使它们具有完全相同的数据)。

    为了获得您正在寻找的比较功能,您需要切换到使用jsonarray 演员表,这会将您的属性转换为关联数组而不是对象。 Laravel 将对关联数组使用严格比较,这将比较实际的数组数据。

    示例

    如上所述,您的示例并不完全等同于 Laravel 正在做的事情。在您的示例代码中,您将 true 作为第二个参数传递给 json_decode()(这是 Laravel 对 jsonarray 强制转换所做的事情),这将返回关联数组而不是对象。如果你传入了 false(这是 Laravel 对 object 演员所做的),你会看到你的严格比较失败。

    简单示例:

    [] === []; // true
    (object)[] === (object)[]; // false
    
    // or
    json_decode('{}', true) === json_decode('{}', true); // true
    json_decode('{}', false) === json_decode('{}', false); // false
    

    【讨论】:

      猜你喜欢
      • 2019-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-21
      • 1970-01-01
      • 1970-01-01
      • 2012-12-22
      相关资源
      最近更新 更多