【问题标题】:Eloquent using foreach inside each function在每个函数中使用 foreach 雄辩
【发布时间】:2018-11-29 14:22:11
【问题描述】:

我想交换图像顺序(从 angularjs/ui-sortable 检索到的数据,因此 $newImgOrder 数组表示新顺序。)

(array) $newImgOrder = ['test.jpeg', 'another.jpeg'];

Images::select('url')->where('project_id', '=', $args['id'])->get()
   ->each(function($img) use (&$newImgOrder) {
       foreach ($newImgOrder as $item) {
           $img->url = $item;
           $img->save(); 
       }
   });

* 已更新 = 执行此操作的正确方法 *

感谢@Devon

删除了 foreach + select()

(array) $newImgOrder = ['test.jpeg', 'another.jpeg'];

Images::where('project_id', '=', $args['id'])->get()
   ->each(function($img) use (&$newImgOrder) {
           $img->url = array_shift($item);
           $img->save(); 
       }
   });

这是我想要做的快速演示:

动作前的表格状态

+---------+-------------+--------------+
| id      | project_id  | url          |  
+---------+-------------+--------------+
| 1       | 15          | another.jpeg |
+---------+-------------+--------------+
| 2       | 15          | test.jpeg    |
+---------+-------------+--------------+

预期结果 =

+---------+-------------+--------------+
| id      | project_id  | url          |  
+---------+-------------+--------------+
| 1       | 15          | test.jpeg    |
+---------+-------------+--------------+
| 2       | 15          | another.jpeg |
+---------+-------------+--------------+

实际结果=

+---------+-------------+--------------+
| id      | project_id  | url          |  
+---------+-------------+--------------+
| 1       | 15          | another.jpeg |
+---------+-------------+--------------+
| 2       | 15          | another.jpeg |
+---------+-------------+--------------+

那个迭代有什么问题。我尝试了双 foreach 但我得到了相同的结果......我错过了什么吗?任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 想想这里的逻辑。对于每张图片,你都在循环 $newImageOrder 并保存该图片的 url。因此,您为每张图像执行两次保存。
  • 嗨@Devon,是的,我同意你的观点,但我只想覆盖现有值。抱歉,我是 eloquent 的新手 :D 对于真正的逻辑,你更喜欢什么?
  • 逻辑与雄辩无关。你在不应该的时候循环。我添加了一个答案。

标签: php laravel eloquent slim


【解决方案1】:

对于每张图片,您的代码会循环访问 $newImageOrder 并保存该图片的网址。因此,您为每张图像执行两次保存,这显然不是您想要的。

内部 foreach 循环没有理由。如果您确定 $newImageOrder 中的元素数将与查询中的行数相匹配,并且由于您将 $newImageOrder 作为对闭包的引用,您可以使用 shift:

each(function($img) use (&$newImgOrder) {
   $img->url = array_shift($newImgOrder);
   $img->save();
});

这会将第一个元素从数组中移出并返回,这意味着您将在每次迭代中删除并使用 $newImgOrder 的第一个元素。

请记住,这是一个可变的更改。 $newImgOrder 被闭包改变。如果这不是您想要的,您可能希望使用运行计数来代替偏移量。

【讨论】:

  • 非常感谢您的逻辑。 :) 我还删除了选择标签以使我的代码正常工作。
  • @bgul 是的,这是一个很好的观点。如果不选择主键,Eloquent 将不知道如何更新行。
  • 再次感谢您分享您的知识@Devon。我更新了我的问题:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-24
  • 2017-06-26
  • 2013-09-06
  • 2014-01-03
  • 1970-01-01
  • 1970-01-01
  • 2017-04-01
相关资源
最近更新 更多