Php Symfony形式子对象上的递归循环

Php Symfony形式子对象上的递归循环,php,recursion,symfony,symfony-forms,Php,Recursion,Symfony,Symfony Forms,我试图构建一种方法,将Symfony表单错误转换为可以序列化的多维数组 目前,我只有表单中的表单(字段集类型)。我创建了一个新系统,用于在表单中嵌入N个表单。我需要能够遍历所有有错误的子项来填充$errors数组 我需要记录我穿越的深度或距离 例如,表单中的表单将是$errors[depth1][depth2][message']。包含多个嵌入表单(最多5个)的表单将是$errors[depth1][depth2][depth3][depth4][depth5][message']$errors

我试图构建一种方法,将Symfony表单错误转换为可以序列化的多维数组

目前,我只有表单中的表单(字段集类型)。我创建了一个新系统,用于在表单中嵌入N个表单。我需要能够遍历所有有错误的子项来填充
$errors
数组

我需要记录我穿越的深度或距离

例如,表单中的表单将是
$errors[depth1][depth2][message']
。包含多个嵌入表单(最多5个)的表单将是
$errors[depth1][depth2][depth3][depth4][depth5][message']
$errors[depth1][depth2]
e.t.c

NB:
[depth(N)]
将替换为当前表单名称

最干净的方法是什么

这是我当前获取字段集的函数,但我希望它能够在不考虑深度的情况下获取任何错误并保持位置(键)完整

它可能看起来像:

private static function getFieldErrorsRecursively(Form $form, &$errors, $position = [])
    {
        foreach ($form as $child) {
            $fieldsArray = $child->getConfig()->getOptions()['fields'] ?? [];
            if (count($fieldsArray) === 0) {
                if (!$child->isValid()) {
                    foreach ($child->getErrors() as $error) {
                        $errors[$child->getName()]['message'] = $error->getMessage();
                        $errors[$child->getName()]['messageTemplate'] = $error->getMessageTemplate();
                        $errors[$child->getName()]['messagePluralization'] = $error->getMessagePluralization();
                        $errors[$child->getName()]['messageParameters'] = $error->getMessageParameters();
                        $errors[$child->getName()]['cause'] = $errors[$child->getName()];
                        if ($errorCause = $error->getCause()) {
                            $errors[$child->getName()]['cause']['plural'] = $errorCause->getPlural();
                            $errors[$child->getName()]['cause']['propertyPath'] = $errorCause->getPropertyPath();
                            $errors[$child->getName()]['cause']['invalidValue'] = $errorCause->getInvalidValue();
                            $errors[$child->getName()]['cause']['constraint'] = serialize($errorCause->getConstraint());
                            $errors[$child->getName()]['cause']['code'] = $errorCause->getCode();
                            $errors[$child->getName()]['cause']['cause'] = $errorCause->getCause();
                        }
                    }

                    return true;
                }
            } elseif (count($fieldsArray) > 0) {
                self::getFieldErrorsRecursively($child, $errors, $child->getName());

                if (count($errors) > 0) {
                    return true;
                }

                return true;
            }
        }

        return false;
    }
任何帮助都将不胜感激:)


不要(跟踪)。构建一个递归函数,该函数使用数组调用,并使用嵌套数组调用自身。如果通过引用传递,则始终可以使用
$errors['cause']..
我想我必须跟踪位置,但是当我再次应用它们时,我需要知道当将错误应用到它的原始字段时,表单的深度。如果我只搜索与原始原因字段匹配的字段,也许我不需要跟踪它们。这很好,它可以整理代码当然尽管我认为我仍然需要编写一些递归的东西,因为您无法序列化该函数的输出,因为它包含闭包。
private static function getFieldErrorsRecursively(Form $form, &$errors, $position = [])
    {
        foreach ($form as $child) {
            $fieldsArray = $child->getConfig()->getOptions()['fields'] ?? [];
            if (count($fieldsArray) === 0) {
                if (!$child->isValid()) {
                    foreach ($child->getErrors() as $error) {
                        $errors[$child->getName()]['message'] = $error->getMessage();
                        $errors[$child->getName()]['messageTemplate'] = $error->getMessageTemplate();
                        $errors[$child->getName()]['messagePluralization'] = $error->getMessagePluralization();
                        $errors[$child->getName()]['messageParameters'] = $error->getMessageParameters();
                        $errors[$child->getName()]['cause'] = $errors[$child->getName()];
                        if ($errorCause = $error->getCause()) {
                            $errors[$child->getName()]['cause']['plural'] = $errorCause->getPlural();
                            $errors[$child->getName()]['cause']['propertyPath'] = $errorCause->getPropertyPath();
                            $errors[$child->getName()]['cause']['invalidValue'] = $errorCause->getInvalidValue();
                            $errors[$child->getName()]['cause']['constraint'] = serialize($errorCause->getConstraint());
                            $errors[$child->getName()]['cause']['code'] = $errorCause->getCode();
                            $errors[$child->getName()]['cause']['cause'] = $errorCause->getCause();
                        }
                    }

                    return true;
                }
            } elseif (count($fieldsArray) > 0) {
                self::getFieldErrorsRecursively($child, $errors, $child->getName());

                if (count($errors) > 0) {
                    return true;
                }

                return true;
            }
        }

        return false;
    }
// a FormErrorIterator instance representing the form tree structure
$errors = $form->getErrors(true, false);