Как отлаживать запрос в extbase?

$query = $this->createQuery();

    return $query->matching($query->like('linker', "$linkerKey=$linkerValue"))
        ->setOrderings(array('crdate' => $ordering))
        ->execute();

Как я могу отлаживать такой сгенерированный запрос в extbase? При повторном создании того же запроса (но без execute()) и попытки отобразить его с помощью var_dump или внутреннего t3lib_div:: debug я просто получаю пустую страницу.

Ответ 1

$query = $this->createQuery();
$result = $query->matching($query->like('linker', "$linkerKey=$linkerValue"))
   ->setOrderings(array('crdate' => $ordering))
   ->execute();

$GLOBALS['TYPO3_DB']->debugOutput = true;

return $result;

Ответ 2

В версии 8.7 LTS необходимо выполнить другой путь:

 $queryParser = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class);
 \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($queryParser->convertQueryToDoctrineQueryBuilder($query)->getSQL());
 \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($queryParser->convertQueryToDoctrineQueryBuilder($query)->getParameters());

Ответ 3

Эта информация устарела и устарела в TYPO3 8.7. См. Ниже ответ @pgampe для более точного способа отладки запросов extbase.

В Extbase теперь есть QueryParser. В вашем методе репозитория, перед возвратом выполненного запроса, вставьте:

    $parser = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Storage\\Typo3DbQueryParser');  
    $queryParts = $parser->parseQuery($query); 
    \TYPO3\CMS\Core\Utility\DebugUtility::debug($queryParts, 'query');

Результатом является табличное представление частей запроса, разделенное по ключевым словам SQL, например:

table view of the query in question

Имейте в виду, что QueryResult, возвращаемый репозиторией, может по-прежнему отличаться от результата запроса SQL. Extbase использует PropertyMapper, чтобы попытаться преобразовать каждую строку результатов в объект ExtbaseObject. Если PropertyMapper неправильно сконфигурирован или строка содержит данные, которые не могут быть преобразованы в типы данных в соответствии с конфигурацией, эти объекты будут молча пропущены.

Ответ 4

Этот хак для extbase грязный, но полезный:

В typo3/sysext/extbase/Классы/Настойчивость/Хранение/Typo3DbBackend.php отредактируйте метод buildQuery (массив $sql) перед оператором return, добавьте:

t3lib_div::debug($statement, 'SQL Query Extbase');

Удалить после использования, и не забывайте, что это повлияет на все, что работает на extbase, поэтому используйте только в среде dev

Источник: http://sancer-media.net/2011/extbase-schneller-mysql-debug.html

Ответ 5

В v6.2x или более поздней версии вы можете отлаживать объект результата в extBase, например:

В репозитории:

return $query- > execute (true);// "true" вернет результат массива

Или вы можете отлаживать объект результата в контроллере:

$resultObject = $this- > yourRepository- > findAll();
\ TYPO3\CMS\Extbase\Utility\DebuggerUtility:: var_dump ($ resultObject);

Ответ 6

Это работает до тех пор, пока поддерживается $ GLOBALS ['TYPO3_DB']. Он покажет вам полный SQL-запрос на сборку.

/**
 * @param \TYPO3\CMS\Extbase\Persistence\QueryResultInterface $queryResult
 * @param bool $explainOutput
 * @return void
 */
public function debugQuery(
    \TYPO3\CMS\Extbase\Persistence\QueryResultInterface $queryResult,
    $explainOutput = false
) {
    $GLOBALS['TYPO3_DB']->debugOuput = 2;
    if ($explainOutput) {
        $GLOBALS['TYPO3_DB']->explainOutput = true;
    }
    $GLOBALS['TYPO3_DB']->store_lastBuiltQuery = true;
    $queryResult->toArray();
    \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump(
        $GLOBALS['TYPO3_DB']->debug_lastBuiltQuery
    );
    $GLOBALS['TYPO3_DB']->store_lastBuiltQuery = false;
    $GLOBALS['TYPO3_DB']->explainOutput = false;
    $GLOBALS['TYPO3_DB']->debugOuput = false;
}

Итак, с помощью этой функции вы можете сделать что-то вроде этого в вашем контроллере:

$all = $this->repository->findAll();
$this->repository->debugQuery($all);

Ответ 7

Легкий способ без изменения кода ядра Typo3 и не упоминаемый в каком-либо форуме до сих пор использует метод "serialize()" php:

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

В объекте результата вы найдете запрос SQL (найдите "statement;"...)

Ответ 8

Здесь я выкладываю метод, который вы можете ввести для отладки в любом классе, поэтому его черты наверняка будут возможны. Авторство и источник упоминаются в комментарии. Использование также:


    /**
    * Render the generated SQL of a query in TYPO3 8
    *
    * @author wp_bube https://www.typo3.net/forum/user-profil/benutzer/zeige/benutzer/wp-bube/
    * @src   https://www.typo3.net/forum/thematik/zeige/thema/125747/
    *
    * Usage: $this->debugQuery($query);
    *
    * @param \TYPO3\CMS\Extbase\Persistence\QueryInterface $query
    * @param bool $format
    * @param bool $exit
    */
    private function debugQuery($query, $format = true, $exit = true)
    {
        function getFormattedSQL($sql_raw)
        {
            if (empty($sql_raw) || !is_string($sql_raw)) {
                return false;
            }
            $sql_reserved_all = array( 'ACCESSIBLE', 'ACTION', 'ADD', 'AFTER', 'AGAINST', 'AGGREGATE', 'ALGORITHM', 'ALL', 'ALTER', 'ANALYSE', 'ANALYZE', 'AND', 'AS', 'ASC', 'AUTOCOMMIT', 'AUTO_INCREMENT', 'AVG_ROW_LENGTH', 'BACKUP', 'BEGIN', 'BETWEEN', 'BINLOG', 'BOTH', 'BY', 'CASCADE', 'CASE', 'CHANGE', 'CHANGED', 'CHARSET', 'CHECK', 'CHECKSUM', 'COLLATE', 'COLLATION', 'COLUMN', 'COLUMNS', 'COMMENT', 'COMMIT', 'COMMITTED', 'COMPRESSED', 'CONCURRENT', 'CONSTRAINT', 'CONTAINS', 'CONVERT', 'CREATE', 'CROSS', 'CURRENT_TIMESTAMP', 'DATABASE', 'DATABASES', 'DAY', 'DAY_HOUR', 'DAY_MINUTE', 'DAY_SECOND', 'DEFINER', 'DELAYED', 'DELAY_KEY_WRITE', 'DELETE', 'DESC', 'DESCRIBE', 'DETERMINISTIC', 'DISTINCT', 'DISTINCTROW', 'DIV', 'DO', 'DROP', 'DUMPFILE', 'DUPLICATE', 'DYNAMIC', 'ELSE', 'ENCLOSED', 'END', 'ENGINE', 'ENGINES', 'ESCAPE', 'ESCAPED', 'EVENTS', 'EXECUTE', 'EXISTS', 'EXPLAIN', 'EXTENDED', 'FAST', 'FIELDS', 'FILE', 'FIRST', 'FIXED', 'FLUSH', 'FOR', 'FORCE', 'FOREIGN', 'FROM', 'FULL', 'FULLTEXT', 'FUNCTION', 'GEMINI', 'GEMINI_SPIN_RETRIES', 'GLOBAL', 'GRANT', 'GRANTS', 'GROUP', 'HAVING', 'HEAP', 'HIGH_PRIORITY', 'HOSTS', 'HOUR', 'HOUR_MINUTE', 'HOUR_SECOND', 'IDENTIFIED', 'IF', 'IGNORE', 'IN', 'INDEX', 'INDEXES', 'INFILE', 'INNER', 'INSERT', 'INSERT_ID', 'INSERT_METHOD', 'INTERVAL', 'INTO', 'INVOKER', 'IS', 'ISOLATION', 'JOIN', 'KEY', 'KEYS', 'KILL', 'LAST_INSERT_ID', 'LEADING', 'LEFT', 'LEVEL', 'LIKE', 'LIMIT', 'LINEAR', 'LINES', 'LOAD', 'LOCAL', 'LOCK', 'LOCKS', 'LOGS', 'LOW_PRIORITY', 'MARIA', 'MASTER', 'MASTER_CONNECT_RETRY', 'MASTER_HOST', 'MASTER_LOG_FILE', 'MASTER_LOG_POS', 'MASTER_PASSWORD', 'MASTER_PORT', 'MASTER_USER', 'MATCH', 'MAX_CONNECTIONS_PER_HOUR', 'MAX_QUERIES_PER_HOUR', 'MAX_ROWS', 'MAX_UPDATES_PER_HOUR', 'MAX_USER_CONNECTIONS', 'MEDIUM', 'MERGE', 'MINUTE', 'MINUTE_SECOND', 'MIN_ROWS', 'MODE', 'MODIFY', 'MONTH', 'MRG_MYISAM', 'MYISAM', 'NAMES', 'NATURAL', 'NOT', 'NULL', 'OFFSET', 'ON', 'OPEN', 'OPTIMIZE', 'OPTION', 'OPTIONALLY', 'OR', 'ORDER', 'OUTER', 'OUTFILE', 'PACK_KEYS', 'PAGE', 'PARTIAL', 'PARTITION', 'PARTITIONS', 'PASSWORD', 'PRIMARY', 'PRIVILEGES', 'PROCEDURE', 'PROCESS', 'PROCESSLIST', 'PURGE', 'QUICK', 'RAID0', 'RAID_CHUNKS', 'RAID_CHUNKSIZE', 'RAID_TYPE', 'RANGE', 'READ', 'READ_ONLY', 'READ_WRITE', 'REFERENCES', 'REGEXP', 'RELOAD', 'RENAME', 'REPAIR', 'REPEATABLE', 'REPLACE', 'REPLICATION', 'RESET', 'RESTORE', 'RESTRICT', 'RETURN', 'RETURNS', 'REVOKE', 'RIGHT', 'RLIKE', 'ROLLBACK', 'ROW', 'ROWS', 'ROW_FORMAT', 'SECOND', 'SECURITY', 'SELECT', 'SEPARATOR', 'SERIALIZABLE', 'SESSION', 'SET', 'SHARE', 'SHOW', 'SHUTDOWN', 'SLAVE', 'SONAME', 'SOUNDS', 'SQL', 'SQL_AUTO_IS_NULL', 'SQL_BIG_RESULT', 'SQL_BIG_SELECTS', 'SQL_BIG_TABLES', 'SQL_BUFFER_RESULT', 'SQL_CACHE', 'SQL_CALC_FOUND_ROWS', 'SQL_LOG_BIN', 'SQL_LOG_OFF', 'SQL_LOG_UPDATE', 'SQL_LOW_PRIORITY_UPDATES', 'SQL_MAX_JOIN_SIZE', 'SQL_NO_CACHE', 'SQL_QUOTE_SHOW_CREATE', 'SQL_SAFE_UPDATES', 'SQL_SELECT_LIMIT', 'SQL_SLAVE_SKIP_COUNTER', 'SQL_SMALL_RESULT', 'SQL_WARNINGS', 'START', 'STARTING', 'STATUS', 'STOP', 'STORAGE', 'STRAIGHT_JOIN', 'STRING', 'STRIPED', 'SUPER', 'TABLE', 'TABLES', 'TEMPORARY', 'TERMINATED', 'THEN', 'TO', 'TRAILING', 'TRANSACTIONAL', 'TRUNCATE', 'TYPE', 'TYPES', 'UNCOMMITTED', 'UNION', 'UNIQUE', 'UNLOCK', 'UPDATE', 'USAGE', 'USE', 'USING', 'VALUES', 'VARIABLES', 'VIEW', 'WHEN', 'WHERE', 'WITH', 'WORK', 'WRITE', 'XOR', 'YEAR_MONTH' );

            $sql_skip_reserved_words = array('AS', 'ON', 'USING');
            $sql_special_reserved_words = array('(', ')');
            $sql_raw = str_replace("\n", " ", $sql_raw);
            $sql_formatted = "";
            $prev_word = "";
            $word = "";
            for ($i = 0, $j = strlen($sql_raw); $i < $j; $i++) {
                $word .= $sql_raw[$i];
                $word_trimmed = trim($word);
                if ($sql_raw[$i] == " " || in_array($sql_raw[$i], $sql_special_reserved_words)) {
                    $word_trimmed = trim($word);
                    $trimmed_special = false;
                    if (in_array($sql_raw[$i], $sql_special_reserved_words)) {
                        $word_trimmed = substr($word_trimmed, 0, -1);
                        $trimmed_special = true;
                    }
                    $word_trimmed = strtoupper($word_trimmed);
                    if (in_array($word_trimmed, $sql_reserved_all) && !in_array($word_trimmed, $sql_skip_reserved_words)) {
                        if (in_array($prev_word, $sql_reserved_all)) {
                            $sql_formatted .= '<b>' . strtoupper(trim($word)) . '</b>' . '&nbsp;';
                        } else {
                            $sql_formatted .= '<br/>&nbsp;';
                            $sql_formatted .= '<b>' . strtoupper(trim($word)) . '</b>' . '&nbsp;';
                        }
                        $prev_word = $word_trimmed;
                        $word = "";
                    } else {
                        $sql_formatted .= trim($word) . '&nbsp;';
                        $prev_word = $word_trimmed;
                        $word = "";
                    }
                }
            }
            $sql_formatted .= trim($word);
            return $sql_formatted;
        }

        $queryParser          = $this->objectManager->get(\TYPO3\CMS\Extbase\Persistence\Generic\Storage\Typo3DbQueryParser::class);
        $doctrineQueryBuilder = $queryParser->convertQueryToDoctrineQueryBuilder($query);
        $preparedStatement    = $doctrineQueryBuilder->getSQL();
        $parameters           = $doctrineQueryBuilder->getParameters();
        $stringParams = [];
        foreach ($parameters as $key => $parameter) {
            $stringParams[':' . $key] = $parameter;
        }
        $statement = strtr($preparedStatement, $stringParams);
        if ($format) {
            echo '<code>' . getFormattedSQL($statement) . '</code>';
        } else {
            echo $statement;
        }
        if ($exit) {
            exit;
        }
    }