使用 Symfony+Doctrine 获得 table 个名字,不包括 table 个由关系制成的名字

Get table names with Symfony+Doctrine excluding tables made from relations

我想使用 Doctrine 从我的 PSQL 数据库中获取所有 table 名称,但我不想要关系 tables,例如:

表格:

我目前正在使用

获取它们
$em->getConnection()->getSchemaManager()->listTables();

有什么方法可以在不使用 strpos() 排除数组结果的情况下做到这一点?

我编写了一个目前适用于我的代码,但尚未完成。如果您来到这里是为了找到我遇到的同一个问题的答案,请随时分析代码。 但请记住,我不是专业人士(远非专业人士)。

我在 ReportController 中有这个:

// Returns an array with my entities
$entities = $em->getMetadataFactory()->getAllMetadata();

//Generate my table names, according to Franz's answer
$tableNames = [
    function(ClassMetadata $meta) {
        return $meta->getTableName();
    },
    $entities
];
    foreach ($tableNames[1] as $tableKey=>$tableName) {
        $table[$tableKey] = $tableName->getTableName();
    }

// Generate an array of columns from $table
// Code from generateColumnNames() below
$column[] = $this->getDoctrine()
    ->getRepository(Chamados::class)
    ->generateColumnNames($table);

//Since I'm displaying some Entity names in PT-BR, I need to treat them.
//I wish I had a better way to do this without having to treat them one by one
foreach ($entities as $entity) {
    $e = explode('\',$entity->getName());

    if ($e[2] === "User") {
        $e[2] = "Usuários";
    }
    else if ($e[2] === "Tramite") {
        $e[2] = "Trâmites";
    }
    else if ($e[2] === "Clients") {
        $e[2] = "Clientes";
    }
    $entKey[] = $e[2];
}
//Insert each name into each array value to display them in my form
$entities = array_combine($entKey, $entities);

//Generate the form
$form = $this->createFormBuilder(['aaa'])
    ->add('entity', ChoiceType::class, [
        'required' => true,
        'placeholder' => '',
        'attr' => [
            'style' => 'text-transform:capitalize',
            'class' => 'entity-class general-control'
        ],
        'choices' => $entities
    ])
    ->add('type', ChoiceType::class, [
        'label' => 'Tipo de relatório',
        'required' => true,
        'placeholder' => '',
        'attr' => [
            'style' => 'display: none',
            'class' => 'type-class general-control'
        ],
        'choices' => [
            'Campo' => 0,
            'Quantidade' => 1,
            'Tudo' => 2,
        ]
    ])
    ->add('select', ChoiceType::class, [
        'label' => 'Campos',
        'required' => false,
        'multiple' => true,
        'attr' => [
            'style' => 'text-transform:capitalize; display: none',
            'class' => 'select-class general-control'
        ],
        'choices' => $column
    ])
    ->add('where', ChoiceType::class, [
        'label' => 'Onde',
        'placeholder' => '',
        'attr' => [
            'style' => 'text-transform:capitalize; display: none',
            'class' => 'where-class general-control'
        ],
        'choices' => $column
    ])
    ->add('operator', ChoiceType::class, [
        'label' => false,
        'attr' => [
            'style' => 'display: none',
            'class' => 'operator-class general-control'
        ],
        'choices' => [
            'Igual a' => '=',
            'Diferente de' => '!=',
            'Contém' => 'LIKE',
            'Entre' => 'BETWEEN',
            'Maior ou igual a' => '>=',
            'Menor ou igual a' => '<=',
        ]
    ])
    ->add('parameter', TextType::class, [
        'label' => false,
        'attr' => [
            'style' => 'display: none',
            'placeholder' => 'Parâmetro',
            'readonly' => 'true',
            'class' => 'parameter-class general-control'
        ]
    ])
    ->add('submit', SubmitType::class, [
        'label' => 'Gerar relatório',
        'attr' => [
            'class' => 'button-blue submit-class general-control',
            'style' => 'display: none'
        ]
    ])
    ->getForm();

$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid()) {
    //Get each form value to use it on generateReport() (code below)
    $entity = $form->get('entity')->getData();
    $type = $form->get('type')->getData();
    $select = $form->get('select')->getData();
    $where = $form->get('where')->getData();
    $operator = $form->get('operator')->getData();
    $parameter = $form->get('parameter')->getData();

    //Generate the report, returning an array
    $result = $this->getDoctrine()
        ->getRepository(Chamados::class)
        ->generateReport($entity, $type, $select, $where, $operator, $parameter);

    return $this->redirectToRoute('generalResult', [
        'result' => $result,
        'entity' => $entity->getTableName()
    ]);
}

return [
    'form' => $form->createView()
];

generateColumnNames()(在存储库内):

public function generateColumnNames($table){
        $em = $this->getEntityManager();
        foreach($table as $t) {
            foreach ($em->getConnection()->getSchemaManager()->listTableColumns($t) as $v) {

            $column[$t][$v->getName()] = $v->getName();
            }
        }

        return $column;
    }

generateReport()(在同一个存储库中):

public function generateReport($entity, int $type, array $selectField, string $whereField, string $operator, string $parameter): array
    {

        //0 = Fields / 1 = Count / * = Everything

        if ($type === 0) {
            foreach($selectField as $key=>$value) {
                $select[$key] = "c." . $value;
            }
            $select = implode(", ", $select);
        }
        else if ($type === 1){    
            $select = "count('id')";
        }
        else {
            $select = "c";
        };    

        $query = $this->_em->createQueryBuilder()
            ->select($select)
            ->from($entity->getName(), 'c');

        if ($operator === "LIKE") {
            $parameter = "%" . $parameter . "%";
            $query->andWhere("LOWER (c." . $whereField . ") " . $operator . " :" . $whereField);
        }
        else {
            $query->andWhere("c." . $whereField . " " . $operator . " :" . $whereField);
        }
        $query->setParameter(":" . $whereField, $parameter);

        $result = $query->getQuery()->getArrayResult();
        return $result;
    }

以下代码应该有效:

public class MyController {
    public function listTables(EntityManagerInterface $em) {
        $allMetadata = $em->getMetadataFactory()->getAllMetadata();
        $tableNames = array_map(
            function(ClassMetadata $meta) {
                return $meta->getTableName();
            },
            $allMetadata);

        // do something with the table names
    }
}

学说文档:ClassMetadata#getTableName()

这是我的做法...

public function getTables(): bool|array {
    // get connection any way you do
    $connection = BasePDO::getInstance()->getEntityManager()->getConnection();
    $query = "SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'";
    $statement = $connection->prepare($query);
    // First column is the table name
    return $statement->executeQuery()->fetchFirstColumn();
}