【问题标题】:Symfony 2 / PHP compare the difference of objects in arrays?Symfony 2 / PHP比较数组中对象的差异?
【发布时间】:2016-08-18 17:35:17
【问题描述】:

我正在使用 Symfony 2.7 我已经构建了一个带有实体的表单,当提交时返回一个对象数组。我需要能够将这个对象数组与我在该表中的内容进行比较?

这就是我设置表单的方式

$builder
   .......
       ->add('my_options',   'entity',  [
                    'label'         => 'Options:',
                    'class'         => 'xxxxBundle:Details',
                    'choice_label'  => 'Title',
                    'multiple'      => true,
                    'expanded'      => true,
                    'required'      => false,
                    'mapped'        => false,
                    'data'          => $data,
                    'attr'          => ['class' => 'AdminList'],
                    'query_builder' =>  function(EntityRepository $er) {
                             return $er->createQueryBuilder('de')
                                        ->where('de.active = ?1')
                                        ->setParameter(1, 1);                                                                             }
       ]);

然后,我对选项表中已有的内容进行基本查找,

$EditPanels = $this->getDoctrine()
               ->getRepository('xxxBundle:Options')
               ->findBy(['AccountID' => $AcID]);

这给了我两个数组,一个是用户刚刚选择的(他们现在需要的这个帐户的选项),另一个是数据库表中已有的。

如何通过删除不需要的内容并添加新选项来比较这些表以使用新选项更新行?

谢谢。

【问题讨论】:

    标签: php arrays symfony


    【解决方案1】:
        $newIds = array_map($formData, function (Details $d) {
            return $d->id;
        });
    
        $oldIds = array_map($EditPanels, function (Details $d) {
            return $d->id;
        });
    
        $shouldBeRemoved = array_diff($oldIds, $newIds);
        $shouldBeAdded   = array_diff($newIds, $oldIds);
    

    现在您有了所有需要更改的选项的 ID。希望这会有所帮助。

    【讨论】:

    • 您想使用array_map 而不是array_reduce
    • @moonwave99:你说得对,谢谢。我已经改变了答案。
    【解决方案2】:

    我认为您甚至不应该查询现有记录。相反,您可以:

    保留所有新记录并更新现有记录:

    foreach ($new as $object) {
        if ($object->getId() === null) {
            $em->persist($object);
        }
    }
    $em->flush();
    

    从数据库中删除所有其他记录:

    $qb = $em->getRepository('xxxxBundle:Details')->createQueryBuilder();
    $qb->delete()->where($qb->expr()->notIn('id', array_column('id', $new)));
    

    附:不确定语法,但你明白了。

    【讨论】:

    • 嗨,不知道这将如何工作,我喜欢这个想法,但 $object 仍然需要绑定到实体?这是来自另一个表单实体吗?我确信这是一个更好的方法,但看不到如何使用它。
    • 哦,对不起,现在我看到选项和详细信息有两个不同的实体 :) 简单地清除表并将所有新数据作为新记录插入怎么样?它应该不会对性能产生太大影响,但会简化应用程序的逻辑。
    • 现在这是一个想法...我专注于更新表格。但是删除所有 X = X 的地方,然后添加新的。我试一试。我将只是让我这样做一个可行的解决方案(我不会发布的东西)非常糟糕:(
    • 这行得通,不是性能方面的最佳解决方案,但它是唯一需要更改这些选项的管理员,而且它们不太可能会改变(如果有的话)。非常感谢。 - 如果您将其发布为答案,我将其标记为真实! - 非常感谢伙伴!
    • 感谢您接受当前答案,我懒得修改它:)
    猜你喜欢
    • 2016-10-19
    • 2023-03-27
    • 1970-01-01
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    • 1970-01-01
    • 2020-02-15
    • 1970-01-01
    相关资源
    最近更新 更多