You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 03:21:44