Prestashop1.7中如何从Doctrine QueryBuilder获取表名及别名
PrestaShop 1.7 从Doctrine QueryBuilder获取表名与别名的实现方案
问题场景
在PrestaShop 1.7框架开发中,实现hookActionCustomerGridQueryBuilderModifier钩子方法时,需要提取查询构建器中涉及的所有表名与对应别名,直接调用getTables()方法无法得到预期结果,原有测试代码如下:
public function hookActionCustomerGridQueryBuilderModifier(array $params){ $searchQueryBuilder = $params['search_query_builder']; // tables names //$tablesList = $searchQueryBuilder->getTables(); // echo var_dump($tablesList); }
问题原因
PrestaShop 1.7后台Grid组件使用的是Doctrine DBAL QueryBuilder,而非ORM QueryBuilder。配套的DBAL 2.x版本中getTables()方法存在缺陷,仅能返回部分通过特定方式注册的表,无法覆盖所有join关联表,因此返回结果不符合预期。
可行实现方案
方案1:读取QueryBuilder查询片段(推荐,性能最优)
DBAL QueryBuilder会将所有主表、关联表信息存在内部查询片段中,无需生成SQL即可直接读取,覆盖所有Grid原生查询场景:
public function hookActionCustomerGridQueryBuilderModifier(array $params){ /** @var \Doctrine\DBAL\Query\QueryBuilder $searchQueryBuilder */ $searchQueryBuilder = $params['search_query_builder']; $tableAliasMap = []; // 提取主表(FROM片段) $fromParts = $searchQueryBuilder->getQueryPart('from'); foreach ($fromParts as $fromItem) { $tableAliasMap[$fromItem['alias']] = $fromItem['table']; } // 提取所有关联表(JOIN片段,按关联的主表分组存储) $joinParts = $searchQueryBuilder->getQueryPart('join'); foreach ($joinParts as $joinGroup) { foreach ($joinGroup as $joinItem) { $tableAliasMap[$joinItem['joinAlias']] = $joinItem['joinTable']; } } // $tableAliasMap 格式为 [表别名 => 真实表名] var_dump($tableAliasMap); }
该方法不需要执行SQL查询,性能开销为0,是PrestaShop Grid场景下的最优解
方案2:解析原生SQL(兜底方案)
如果遇到第三方模块直接修改原生SQL、绕过QueryBuilder标准方法添加表的极端场景,可以先生成最终SQL,通过正则提取表与别名映射:
public function hookActionCustomerGridQueryBuilderModifier(array $params){ $searchQueryBuilder = $params['search_query_builder']; $sql = $searchQueryBuilder->getSQL(); $tableAliasMap = []; // 正则匹配FROM、JOIN后的表名与别名 preg_match_all('/(FROM|JOIN)\s+`?([a-zA-Z0-9_]+)`?\s+(AS\s+)?`?([a-zA-Z0-9_]+)`?/i', $sql, $matches); if (!empty($matches[2])) { foreach ($matches[2] as $index => $tableName) { $tableAliasMap[$matches[4][$index]] = $tableName; } } var_dump($tableAliasMap); }
注意:正则解析方案仅作为兜底使用,如果SQL中存在子查询、特殊表名格式,需要根据实际业务调整正则规则。
内容的提问来源于stack exchange,提问作者Zied Dams
相关产品推荐
相关产品推荐

