【问题标题】:Modifying object in array is changing the session value修改数组中的对象正在更改会话值
【发布时间】:2021-04-02 09:00:52
【问题描述】:

我在 PHP Laravel 中有以下一段代码,其中包含对象数组。每个对象有 2 个属性。身份证和姓名。这整个对象被保存在会话中。然后保存后,我从数组中的每个对象中删除 id。这也是在修改会话。

我做错了吗?

$array = [];

$obj = new \stdClass();
$obj->id = "1";
$obj->name = "Test";

array_push($array, $obj);

$request->session()->put('val', $array);

foreach($array as $key => $val) {
    unset($array[$key]->id);
}

echo "<pre>";
print_r($request->session()->get('val'));
echo "</pre>";

在这里,我注意到 id 属性从会话中消失了。

【问题讨论】:

  • 是的,因为您正在编辑数组的同一个副本。
  • @nice_dev - 你能更正代码吗?
  • 未设置有什么意义?您想在会话中保留该数组的单独副本以及通常的数组吗?
  • @nice_dev:我将新数组作为对前端的响应发送。前端不需要id属性,
  • 在 2 个不同的框架上拥有前端和后端时,会话是否有用?

标签: php laravel laravel-7 laravel-8


【解决方案1】:

出现问题是因为正在操作对象的同一副本。要解决这个问题,您需要 clone 对象,然后取消设置并发送响应,保持会话中的数据完好无损。

$cloned_data = [];
foreach($array as $key => $val) {
    $new_obj = clone $val;
    unset($new_obj->id);
    $cloned_data[] = $new_obj;
}

print_r($cloned_data);

【讨论】:

    【解决方案2】:

    对于仅将名称发送到前端,您可以使用 collection pluck 来获取一个新的名称数组

    $dataForFrontend = collect($array)->pluck('name')->all();
    

    这改变了要发送到前端的数据的视图。 [0] => '测试'

    如果您需要按名称键入它 - 例如[0]['name'] =&gt; 'Test'

    $dataForFrontend = collect($data)->map(
        fn($item) => ['name' => $item->name]
    )->all();
    

    如果需要将数组元素保留为原始类型的对象,与@nice_dev 的解决方案基本相同

    $dataForFrontend = collect($array)->map(function($item) {
        $clone = clone $item;
        unset($clone->id);
    
        return $clone;
    })->all();
    

    将数组元素保留为对象 - 不是原始类型,而是作为 std 类的对象

    $dataForFrontend = collect($data)->map(
        fn($item) => (object)['name' => $item->name]
    )->all();
    

    【讨论】:

    • 这改变了要发送到前端的数据视图。 [0] =&gt; 'Test'
    猜你喜欢
    • 2015-05-05
    • 1970-01-01
    • 2021-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多