13
votes

Comment déboguer une requête dans Extbase?

$query = $this->createQuery();

    return $query->matching($query->like('linker', "$linkerKey=$linkerValue"))
        ->setOrderings(array('crdate' => $ordering))
        ->execute();
How can i debug such a generated query in extbase? When creating the same query again (but without the execute() ) and trying to display it with var_dump or the internal t3lib_div::debug i just receive a blank page. 

0 commentaires

20 Réponses :


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

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

return $result;

4 commentaires

Cela ne fonctionne pas pour moi du tout. Qu'est-ce que $ globals ['typo3_db'] -> debugoutoutputt = vrai; censé faire? Je n'ai aucun résultat. J'utilise typo3 4.6.6 ici et je ne peux pas obtenir le SQL généré par ExtBase. Pourquoi est-ce aussi difficile?


@Martin: Voir API.TYPO3.ORG/TTTYPO3CMS/47/HTML/ ...


Pour prolonger: Vous pouvez également attribuer 1 (identique que true , pour affichage des requêtes avec des erreurs ) ou 2 ( Pour Afficher toutes les requêtes ).


$ Globals ['typo3_db'] -> debugoutputtput = 2; ne fonctionne pas ... Je ne comprends pas pourquoi il est un tel problème de simplement activer la production de requêtes SQL ...



5
votes

Ce hack à exttasse est sale, mais utile:

dans typo3 / systext / extbase / classes / persistance / stockage / typo3dbbackend.php Modifier la méthode BuildQuery (Array $ SQL) Avant la déclaration de retour, ajoutez: xxx

Supprimer après utilisation, et n'oubliez pas que cela affectera tout ce qui fonctionne sur ExtBase, utilisez donc dans l'environnement DEV uniquement

Source: http://sancer-media.net/2011/EXTBASE-SCHNE-MYSQL -debug.html


3 commentaires

Merci d'avoir posté votre réponse! Veuillez noter que vous devriez poster les parties essentielles de la réponse ici, sur ce site ou vos risques posts supprimés voir la FAQ où il mentionne les réponses que sont à peine plus qu'un lien ". , vous pouvez toujours inclure le lien si vous le souhaitez, mais seulement comme une" référence ". La réponse devrait se tenir seul sans avoir besoin du lien.


Remarque, dans TYPO3 6.1 Ceci est à TYPO3 / SYSTEXT / ExtBase / Classes / Persistence / Générique / Stockage / Typ o3dbbackend.php - mais le hack ne fonctionne plus


Voir la réponse de @ Biesior à Stackoverflow.com/Questions / 13084863 / ... pour 6.1 - Travaux



0
votes

Un moyen simple sans changer de code de base de TYPO3 et non mentionné dans aucun forum à ce jour utilise jusqu'à présent l'utilisation de la méthode PHP "Serialize ()": xxx

dans l'objet de résultat que vous trouvez le SQL Requête (rechercher "déclaration" ...)


0 commentaires

8
votes

Ces informations sont obsolètes et obsolètes dans TYPO3 8.7 et je n'ai laissé que la réponse pour référence. Reportez-vous à la réponse de @pgampe sur la manière dont les requêtes ExtBase de déboges dans des versions plus récentes de TPYO3.

extbase a maintenant un queryParser pour cela. Dans votre méthode de référentiel, juste avant de retourner la requête exécutée, insert: xxx

Le résultat est une vue de table des pièces de requête, divisée par des mots-clés SQL, par exemple:

vue table de la requête en question

garder à l'esprit que le queryResult que votre référentiel retourne peut toujours être différent du résultat de la requête SQL. ExtBase utilise la propertyMapper pour essayer de convertir chaque ligne de résultat en extculaseObject. Si la propriété est mal configurée ou que la ligne contient des données qui ne peuvent pas être converties en types de données en fonction de la configuration, ces objets seront ignorés.


3 commentaires

Sur la version 8.7, cela donne mon erreur: Appel à la méthode non définie Typo3 \ cms \ extbase \ persistence \ generic \ Storage \ Typo3DBQuerypa RSER :: Parerery ()


Comme @pgampe a souligné, cette méthode est obsolète. Voir sa réponse pour une mise à jour.


O.k désormais maintenant déboguer une requête générée dans l'un des fichiers principaux tels que ceci: $ this-> xyrepository-> ajouter ($ xyObject);



0
votes

en v6.2x ou plus tard, vous pouvez déboguer l'objet de résultat dans ExtBase comme:

dans le référentiel:

retour $ $ Query-> exécuter (vrai); // "vrai" retournera le résultat de la matrice

ou aussi vous pouvez déboguer l'objet de résultat dans le contrôleur:

$ résultantObject = ceci-> YourRepository-> résultats ();
\ Typo3 \ cms \ extbase \ utilitaire \ déboggerutilité :: var_dump ($ résultant);


0 commentaires

38
votes

dans la version 8,7 lts forte>, une autre façon doit être prise:

$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());


5 commentaires

Excellent!, Qui aide effectivement à trouver ce qui se passe en arrière.


Pourquoi cela n'est-il pas directement intégré dans la débogueur ?!


Merci. Ces lignes seront sobres pour moi.


Je pense que l'instruction SQL exécutable est nécessaire. $ QueryParser = $ this-> ObjectManager-> Obtenez (\ TYPO3 \ CMS \ ExtBase \ persistence \ Gen \ Storage \ Typo3DB QueryParser :: Classe); $ sql = $ QueryParser-> ConvertQuéryTodOctrineQueryBuilder ($ requis) -> GE TSQL (); $ paramters = $ QueryParser-> ConvertQuéryTodoctrineQueryBuilder ($ requis) -> GE TPARAMETTERS (); $ Search = Array (); $ remplaçable = tableau (); foreach ($ paramters comme $ k => $ v) {$ Search [] = ':'. $ k; $ Remplacer [] = '\' '. $ v. '\' '; } $ sql = str_replace ($ recherche, $ Remplacer, $ SQL); \ Typo3 \ cms \ extbase \ utilitaire \ déboggerutilité :: var_dump ($ SQL);


pgampe, @franzholzinger, basing sur vos réponses J'ai créé un référentiel abstrait comme indiqué dans une autre réponse , je suis intéressé par votre opinion et peut-être corriger et tester dans les précédentes versions TYPO3.



1
votes

Cela fonctionne aussi longtemps que $ globals ['typo3_db'] est pris en charge. Il vous montrera la requête complète de la construction SQL. XXX PRE>

Ainsi, avec cette fonction, vous pouvez faire quelque chose comme celui-ci dans votre contrôleur: p>

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


0 commentaires

0
votes

Ici, je pose une méthode que vous pouvez entrer pour le débogage de n'importe quelle classe, ce qui en fait un trait serait sûrement possible. La paternité et la source sont mentionnées dans le commentaire, l'utilisation également:

    /**
    * 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;
        }
    }


0 commentaires

1
votes

Selon @pgampe de la réponse et @franzholzinger S: J'ai créé abstractonrepository dans mon ext Wit Certaines méthodes extraites, pouvant être étendues dans votre propre référentiel Pour amener la possibilité de débogage un peu plus confortable.

note strong> c'est testé et fonctionne pour TYPO3 VER 10.x code>, la plupart fonctionnera probablement depuis 8.7 + Code> également, nécessite des tests. P>

<?php

namespace VENDOR\Extkey\Domain\Repository;


use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;


class FooRepository extends \VENDOR\Extkey\Domain\Repository\AbstractRepository
{

    public function findByName($name)
    {
        $query = $this->createQuery();
        $query->matching(
            $query->equals('name', $name)
        );
        $this->debugQuery($query, 'Debug SQL in repository with QueryInterface');
        return $query->execute();
    }

    public function queryByName($name)
    {
        /** @var ConnectionPool $pool */
        $pool = GeneralUtility::makeInstance(ConnectionPool::class);
        $connection = $pool->getConnectionForTable('tx_extkey_domain_model_yourmodel');
        $queryBuilder = $connection->createQueryBuilder();
        $query = $queryBuilder
            ->select('*')
            ->from('tx_extkey_domain_model_yourmodel')
            ->where("name like :name")
            ->setParameter('name', "%{$name}%");

        $this->debugQuery($query, 'Debug SQL in my repository with QueryBuilder');
        return $query->execute()->fetchAll();
    }


2 commentaires

Le seul inconvénient est que toutes les classes de référentiel sont obligées de dériver de l'abstractroptère. Il serait préférable d'avoir une classe d'API externe à la place.


Dans rendudebug () Les deux tableaux doivent être inversés. Sinon, un ": dcvalue12" remplacera en partie en recherchant et en remplaçant ': dcvalue1'. Dans l'ordre inverse, vous pouvez éviter cela.



0
votes

Je construit une fonction statique d'une classe utilitie pour l'utilisation dans TYPO3 9.5. Cela devrait fonctionner dans TYPO3 10.4. et typo3 11 xxx

Utilisation dans le référentiel xxx


0 commentaires

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

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

return $result;

4 commentaires

Cela ne fonctionne pas pour moi du tout. Qu'est-ce que $ globals ['typo3_db'] -> debugoutoutputt = vrai; censé faire? Je n'ai aucun résultat. J'utilise typo3 4.6.6 ici et je ne peux pas obtenir le SQL généré par ExtBase. Pourquoi est-ce aussi difficile?


@Martin: Voir API.TYPO3.ORG/TTTYPO3CMS/47/HTML/ ...


Pour prolonger: Vous pouvez également attribuer 1 (identique que true , pour affichage des requêtes avec des erreurs ) ou 2 ( Pour Afficher toutes les requêtes ).


$ Globals ['typo3_db'] -> debugoutputtput = 2; ne fonctionne pas ... Je ne comprends pas pourquoi il est un tel problème de simplement activer la production de requêtes SQL ...



5
votes

Ce hack à exttasse est sale, mais utile:

dans typo3 / systext / extbase / classes / persistance / stockage / typo3dbbackend.php Modifier la méthode BuildQuery (Array $ SQL) Avant la déclaration de retour, ajoutez: xxx

Supprimer après utilisation, et n'oubliez pas que cela affectera tout ce qui fonctionne sur ExtBase, utilisez donc dans l'environnement DEV uniquement

Source: http://sancer-media.net/2011/EXTBASE-SCHNE-MYSQL -debug.html


3 commentaires

Merci d'avoir posté votre réponse! Veuillez noter que vous devriez poster les parties essentielles de la réponse ici, sur ce site ou vos risques posts supprimés voir la FAQ où il mentionne les réponses que sont à peine plus qu'un lien ". , vous pouvez toujours inclure le lien si vous le souhaitez, mais seulement comme une" référence ". La réponse devrait se tenir seul sans avoir besoin du lien.


Remarque, dans TYPO3 6.1 Ceci est à TYPO3 / SYSTEXT / ExtBase / Classes / Persistence / Générique / Stockage / Typ o3dbbackend.php - mais le hack ne fonctionne plus


Voir la réponse de @ Biesior à Stackoverflow.com/Questions / 13084863 / ... pour 6.1 - Travaux



0
votes

Un moyen simple sans changer de code de base de TYPO3 et non mentionné dans aucun forum à ce jour utilise jusqu'à présent l'utilisation de la méthode PHP "Serialize ()": xxx

dans l'objet de résultat que vous trouvez le SQL Requête (rechercher "déclaration" ...)


0 commentaires

8
votes

Ces informations sont obsolètes et obsolètes dans TYPO3 8.7 et je n'ai laissé que la réponse pour référence. Reportez-vous à la réponse de @pgampe sur la manière dont les requêtes ExtBase de déboges dans des versions plus récentes de TPYO3.

extbase a maintenant un queryParser pour cela. Dans votre méthode de référentiel, juste avant de retourner la requête exécutée, insert: xxx

Le résultat est une vue de table des pièces de requête, divisée par des mots-clés SQL, par exemple:

vue table de la requête en question

garder à l'esprit que le queryResult que votre référentiel retourne peut toujours être différent du résultat de la requête SQL. ExtBase utilise la propertyMapper pour essayer de convertir chaque ligne de résultat en extculaseObject. Si la propriété est mal configurée ou que la ligne contient des données qui ne peuvent pas être converties en types de données en fonction de la configuration, ces objets seront ignorés.


3 commentaires

Sur la version 8.7, cela donne mon erreur: Appel à la méthode non définie Typo3 \ cms \ extbase \ persistence \ generic \ Storage \ Typo3DBQuerypa RSER :: Parerery ()


Comme @pgampe a souligné, cette méthode est obsolète. Voir sa réponse pour une mise à jour.


O.k désormais maintenant déboguer une requête générée dans l'un des fichiers principaux tels que ceci: $ this-> xyrepository-> ajouter ($ xyObject);



0
votes

en v6.2x ou plus tard, vous pouvez déboguer l'objet de résultat dans ExtBase comme:

dans le référentiel:

retour $ $ Query-> exécuter (vrai); // "vrai" retournera le résultat de la matrice

ou aussi vous pouvez déboguer l'objet de résultat dans le contrôleur:

$ résultantObject = ceci-> YourRepository-> résultats ();
\ Typo3 \ cms \ extbase \ utilitaire \ déboggerutilité :: var_dump ($ résultant);


0 commentaires

38
votes

dans la version 8,7 lts forte>, une autre façon doit être prise:

$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());


5 commentaires

Excellent!, Qui aide effectivement à trouver ce qui se passe en arrière.


Pourquoi cela n'est-il pas directement intégré dans la débogueur ?!


Merci. Ces lignes seront sobres pour moi.


Je pense que l'instruction SQL exécutable est nécessaire. $ QueryParser = $ this-> ObjectManager-> Obtenez (\ TYPO3 \ CMS \ ExtBase \ persistence \ Gen \ Storage \ Typo3DB QueryParser :: Classe); $ sql = $ QueryParser-> ConvertQuéryTodOctrineQueryBuilder ($ requis) -> GE TSQL (); $ paramters = $ QueryParser-> ConvertQuéryTodoctrineQueryBuilder ($ requis) -> GE TPARAMETTERS (); $ Search = Array (); $ remplaçable = tableau (); foreach ($ paramters comme $ k => $ v) {$ Search [] = ':'. $ k; $ Remplacer [] = '\' '. $ v. '\' '; } $ sql = str_replace ($ recherche, $ Remplacer, $ SQL); \ Typo3 \ cms \ extbase \ utilitaire \ déboggerutilité :: var_dump ($ SQL);


pgampe, @franzholzinger, basing sur vos réponses J'ai créé un référentiel abstrait comme indiqué dans une autre réponse , je suis intéressé par votre opinion et peut-être corriger et tester dans les précédentes versions TYPO3.



1
votes

Cela fonctionne aussi longtemps que $ globals ['typo3_db'] est pris en charge. Il vous montrera la requête complète de la construction SQL. XXX PRE>

Ainsi, avec cette fonction, vous pouvez faire quelque chose comme celui-ci dans votre contrôleur: p>

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


0 commentaires

0
votes

Ici, je pose une méthode que vous pouvez entrer pour le débogage de n'importe quelle classe, ce qui en fait un trait serait sûrement possible. La paternité et la source sont mentionnées dans le commentaire, l'utilisation également:

    /**
    * 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;
        }
    }


0 commentaires

1
votes

Selon @pgampe de la réponse et @franzholzinger S: J'ai créé abstractonrepository dans mon ext Wit Certaines méthodes extraites, pouvant être étendues dans votre propre référentiel Pour amener la possibilité de débogage un peu plus confortable.

note strong> c'est testé et fonctionne pour TYPO3 VER 10.x code>, la plupart fonctionnera probablement depuis 8.7 + Code> également, nécessite des tests. P>

<?php

namespace VENDOR\Extkey\Domain\Repository;


use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;


class FooRepository extends \VENDOR\Extkey\Domain\Repository\AbstractRepository
{

    public function findByName($name)
    {
        $query = $this->createQuery();
        $query->matching(
            $query->equals('name', $name)
        );
        $this->debugQuery($query, 'Debug SQL in repository with QueryInterface');
        return $query->execute();
    }

    public function queryByName($name)
    {
        /** @var ConnectionPool $pool */
        $pool = GeneralUtility::makeInstance(ConnectionPool::class);
        $connection = $pool->getConnectionForTable('tx_extkey_domain_model_yourmodel');
        $queryBuilder = $connection->createQueryBuilder();
        $query = $queryBuilder
            ->select('*')
            ->from('tx_extkey_domain_model_yourmodel')
            ->where("name like :name")
            ->setParameter('name', "%{$name}%");

        $this->debugQuery($query, 'Debug SQL in my repository with QueryBuilder');
        return $query->execute()->fetchAll();
    }


2 commentaires

Le seul inconvénient est que toutes les classes de référentiel sont obligées de dériver de l'abstractroptère. Il serait préférable d'avoir une classe d'API externe à la place.


Dans rendudebug () Les deux tableaux doivent être inversés. Sinon, un ": dcvalue12" remplacera en partie en recherchant et en remplaçant ': dcvalue1'. Dans l'ordre inverse, vous pouvez éviter cela.



0
votes

Je construit une fonction statique d'une classe utilitie pour l'utilisation dans TYPO3 9.5. Cela devrait fonctionner dans TYPO3 10.4. et typo3 11 xxx

Utilisation dans le référentiel xxx


0 commentaires