首页 文章

Extbase - 从查询中获取创建的sql

提问于
浏览
9

我想从我的typo3扩展中获取一些数据库表 . 扩展基于extbase .

查询始终只返回数据,但数据存在

我试过这个:

$query = $this->createQuery();
$query->statement('SELECT * FROM `my_table`
    WHERE field = ? ORDER BY date DESC LIMIT 1',
    array($condition));

$results = $query->execute();

还有这个:

$query = $this->createQuery();

$query->matching($query->equals('field', $condition));
$query->setOrderings(array('date' => Tx_Extbase_Persistence_QueryInterface::ORDER_DESCENDING));
$query->setLimit(1);

$results = $query->execute();

两者都返回null作为结果 .

是否有可能获得该类创建的sql来查找bug的位置?

我查看了一些extbase持久化类,但没有找到线索

编辑:对于那些感兴趣的人..我找到了一个“解决方案” .

如果使用statement()方法创建查询,则可以使用此函数打印查询

echo $query->getStatement()->getStatement();

它不会替换占位符 . 但是你可以用这种方法得到变量

var_dump($query->getStatement()->getBoundVariables());

这是我发现的最佳解决方案,无需编辑extbase扩展

8 回答

  • 1

    我只是用$ _GET条件扩展了上面的代码片段 . 为了调试,只需将“?dbg_table = tx_some_of_my_tables”附加到您的地址,然后您就可以开始了;-)

    if (in_array($_GET['dbg_table'], $sql['tables'])) {
            echo('<div style="background: #ebebeb; border: 1px solid #999; margin-bottom: 20px; padding: 10px;"><pre style="white-space: normal">'.$statement.'</pre></div>');
        }
    
  • 5

    检查this snippet,虽然使用起来不太舒服但它有很大帮助:

    一般来说,你需要在 buildQuery(array $sql) 方法(*)末尾的代码 - 就在 return $statement; 之前

    if (in_array("your_table_name", $sql['tables'])) {
        var_dump($statement);
        print_r($statement);
    }
    

    (*)类文件:

    • TYPO3版本:4.x: typo3/sysext/extbase/Classes/Persistence/Storage/Typo3DbBackend.php

    • TYPO3版本:6.x: typo3/sysext/extbase/Classes/Persistence/Generic/Storage/Typo3DbBackend.php


    在6.2.x中......

    您可以在 \TYPO3\CMS\Core\Database\DatabaseConnection::exec_SELECTquery 方法内尝试,只需在获取$查询后添加条件,如(trim很重要!):

    public function exec_SELECTquery($select_fields, $from_table, $where_clause, $groupBy = '', $orderBy = '', $limit = '') {
        $query = $this->SELECTquery($select_fields, $from_table, $where_clause, $groupBy, $orderBy, $limit);
    
        if (trim($from_table) == 'fe_users') {
            DebuggerUtility::var_dump($query);
        }
    
    // rest of method
    
  • 6

    在TYPO3 6.2中,您可以使用Extbase DebuggerUtility来调试查询 .

    在$ query-> execute()之前添加此代码:

    /** @var Typo3DbQueryParser $queryParser */
    $queryParser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Storage\\Typo3DbQueryParser');
    \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($queryParser->parseQuery($query));
    
  • 0

    一个简单的方法,不改变任何Typo3核心代码,到目前为止在任何论坛中都没有提到使用php“serialize()”方法:

    $result = $query->execute();
    echo (serialize($result));
    

    在结果对象中,您可以找到SQL查询(“statement;”...)

  • 0

    对biesiors的改进回答:

    由于Extbase在调用buildQuery()之后替换了一些占位符,您可能更喜欢将调试输出放在 getObjectDataByQuery() 中,就在$ this-> replacePlaceholders($ sql,$ parameters,$ tableName)之后;

    if (strpos($sql, "your_table_name.")) {
        debug($sql, 'my debug output');
    };
    

    另外,最好使用debug()而不是var_dump() .
    [档案: typo3\sysext\extbase\Classes\Persistence\Generic\Storage\Typo3DbBackend.php . 版本6.1中的第339行]:

  • 2
    $query = $this->createQuery();
    $query->getQuerySettings()->setReturnRawQueryResult(TRUE);
    $getHotelInfo = 'SELECT * FROM `my_table` WHERE field = ? ORDER BY date DESC LIMIT 1';
    return $query->statement($getHotelInfo)->execute();
    

    要执行查询,您必须在存储库中编写“setReturnQueryResult”

  • 0

    使用TYPO3 6.1时,更简洁的方法来调试语句是使用query parser Typo3DbBackend .

    $parser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Storage\\Typo3DbBackend');
    $params = array();
    $queryParts = $parser->parseQuery($query, $params);
    
    \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('query', 'my_extension', 1, array('query' => $queryParts, 'params' => $params));
    

    解析器返回一个包含生成的SQL语句的不同部分的数组 .

    使用TYPO3 6.2时, parseQuery 方法已移至Typo3DbQueryParser并丢失其第二个参数 .

  • 3

    我建议在'SYS'数组下的typo3conf / LocalConfiguration.php文件中设置它

    'SYS' => array(
    ......
    'displayErrors' => 1,
    'sqlDebug' => 1
    .......
    )
    

    然后故意在查询中写错字段名,然后执行代码 . 这将显示上一个查询执行错误 .

相关问题