PHP / Laravel - 更新 JSON 对象的值

Posted

技术标签:

【中文标题】PHP / Laravel - 更新 JSON 对象的值【英文标题】:PHP / Laravel - update values of JSON object 【发布时间】:2019-02-11 16:28:43 【问题描述】:

在 Laravel php 中,我有一个需要更新一些参数的对象。对象已更新,我可以返回或 dd() 正确的值。但是当我 ->save() 时,就好像值没有改变。 ->save 方法工作正常,但我更新对象值的方式显然是错误的......

因此,我使用以下代码循环遍历参数数组来更新并创建更新的对象(简化示例):

      $account = Account::find('account_id');
      // ^returns something like (object)['user'=>['name'=>'jeff','age'=>'20']];

      $to_update = ['user.name':'john', 'user.age':'50'];

      // the following function converts exploded arrays of key names to php objects
      // ie user.name:"John" becomes user->name = john
      function get($path, $object, $value) 
        $temp = &$object;
        foreach($path as $var) 
            $temp =& $temp->$var;
        
        $temp = $value;
      

      foreach($to_update as $keys => $value)

        $key = explode(".", $keys);
        get($key, $account, $value);
      

      // $account->save();

      return $account;

这会返回一个不错的更新对象,例如:

+"user": +"name":"john" +"age":"50"

但是,如果我保存该对象,它不会保存更新的值,只会保存旧值。所以改变最后两行:

      $account->save();

      return $account;

结果

+"user": +"name":"jeff" +"age":"20" // these are the old values

所以我的问题是 - 为什么return $account 给出正确的更新对象,但$account->save(); return $account 恢复为原始值?

仅供参考:以下代码有效(但对我来说太简单了):

  $account = Account::find('account_id');
  // ^returns something like (object)['user'=>['name'=>'jeff','age'=>'20']];

  $account->user->name = "jim";
  $account->user->age = "100";

  $account->save();

  return $account;

+"user": +"name":"jim" +"age":"100"

保存前 $account 的完整 dd 输出如下所示(包括我更新的值):

        Account #642
            +"id": "1234567890"
            +"object": "account"
            +"business_name": "my-business"
            +"business_primary_color": "#c2185b"
            +"business_url": "http://url.com"
            +"charges_enabled": true
            +"country": "GB"
            +"created": 1534491122
            +"debit_negative_balances": false
            +"decline_charge_on": StripeObject #644
                +"avs_failure": false
                +"cvc_failure": false
            
            +"default_currency": "gbp"
            +"details_submitted": false
            +"display_name": "display_name"
            +"email": "my_email@email.com"
            +"external_accounts": Collection #643
                +"object": "list"
                +"data": []
                +"has_more": false
                +"total_count": 0
                +"url": "external_accounts_url"
            
            +"legal_entity": StripeObject #649
                +"additional_owners": []
                +"address": StripeObject #655
                +"city": null
                +"country": "GB"
                +"line1": null
                +"line2": null
                +"postal_code": null
                +"state": null
                
                +"business_name": null
                +"business_tax_id_provided": false
                +"dob": StripeObject #656
                +"day": "01"
                +"month": "01"
                +"year": null
                
                +"first_name": "john"
                +"last_name": "doe"
                +"personal_address": StripeObject #659
                +"city": null
                +"country": "GB"
                +"line1": null
                +"line2": null
                +"postal_code": null
                +"state": null
                
                +"type": "company"
                +"verification": StripeObject #662
                +"details": null
                +"details_code": null
                +"document": null
                +"document_back": null
                +"status": "unverified"
                
            
            +"metadata": StripeObject #652
            +"payout_schedule": StripeObject #665
                +"delay_days": 7
                +"interval": "daily"
            
            +"payout_statement_descriptor": null
            +"payouts_enabled": false
            +"product_description": null
            +"statement_descriptor": "MY BUSINESS"
            +"support_email": null
            +"support_phone": null
            +"timezone": "Etc/UTC"
            +"tos_acceptance": StripeObject #670
                +"date": 1535741539
                +"ip": "255.255.255.255"
                +"user_agent": null
            
            +"type": "custom"
            +"verification": StripeObject #673
                +"disabled_reason": null
                +"due_by": null
                +"fields_needed": array:6 [
                0 => "external_account"
                1 => "legal_entity.additional_owners"
                2 => "legal_entity.dob.day"
                3 => "legal_entity.dob.month"
                4 => "legal_entity.dob.year"
                5 => "legal_entity.last_name"
                ]
            
            

【问题讨论】:

您可以在保存前发布您的 $account 的完整 dd 吗?可能你操纵了错误的属性。不过,我不完全确定您为什么选择如此复杂的方式来更新帐户用户。由于该帐户似乎只有 1 个用户,您可以在第一个实例中简单地查询该用户,然后直接从请求参数中更新它,例如 $user->update($request->only(['name', 'age']) 检查此字段是否可用于模型 Account::create([$account]);如果您没有保护模型中的所有字段,可能会起作用? 这不是一个 eloquent 模型实例的完整 dd。一个 dd 将输出模型的所有字段+方法(例如laraveldaily.com/echoing-dd-vs-var_dump-vs-print_r) 哦,好吧-我刚刚意识到:即使您正在对用户进行更改,您也正在保存帐户。您可能需要使用 push 而不是 save - 请参阅***.com/questions/17035682/… 【参考方案1】:

当您更新内部实体但在外部实体上调用 save 时,它​​只会更新外部实体,然后重新加载尚未更新的当前关系。

因此请改用$account->push() 或仅使用$account->user->save() 以保存正确的。

Eloquent push() and save() difference

【讨论】:

听起来不错!但是我不能直接使用 push() [调用未定义的方法 push()]。有没有办法“应用”我的更改然后保存,我想知道......? $account->user->save();也会导致[调用未定义的方法 save()] 如果 $accoun->user->save() 导致未定义的方法,那么用户不会返回一个雄辩的模型 - dd($account->user) 的结果是什么 这是一个 StripeObject (JSON) : StripeObject #649 +"address": StripeObject #655 +"city": null +"country": "GB" 等等... 你在使用 laravel 收银员吗?我不知道我们正在讨论条带集成,您实际上想在条带端更新信息【参考方案2】:

您调用了帐户对象的保存方法而不是帐户中的用户对象来使用它 $account->user->save(); 要么 如果您的目的是更新相同的用户详细信息,请使用它 $account->user->update(['name'=>'jim','age'=>'100']);

【讨论】:

以上是关于PHP / Laravel - 更新 JSON 对象的值的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.1 Php artisan 命令在作曲家更新后不起作用

更新到 Laravel 7 php artisan 后无法正常工作

如何优化使用 PHP 或 Mysql 或 Laravel 将 12K 的 JSON 插入数据库

作曲家和 laravel 7 不适用于 php 8.1 [关闭]

如何使用 PHP/Laravel 返回 Json 数据数组?

PHP,Laravel:从 JSON 中消除特定的复杂数组