Maison > Article > développement back-end > Utilisation de sql-parser pour l'analyse de la syntaxe SQL dans PHPMyAdmin
L'écriture de SQL est une chose courante pour PHP, alors comment analyser les instructions SQL pour optimiser SQL ? sql-parser fournit une telle fonction, jetons-y un coup d'œil.
phpMyAdmin est un outil de gestion de bases de données open source qui fonctionne sur le Web et prend en charge la gestion des bases de données MySQL et MariaDB. Le programme de phpMyAdmin est principalement développé en utilisant PHP et JavaScript. Son installation et son utilisation sont relativement simples et il existe de nombreuses introductions connexes. Je ne les répéterai pas. Aujourd'hui, je vais présenter l'un des composants principaux du code source, sql-parser.
Introduction à sql-parser
L'objectif principal du composant sql-parser est d'effectuer une analyse lexicale et une analyse syntaxique des instructions SQL, puis de déconstruire, traiter, remplacer et réassembler SQL instructions, etc., et vous pouvez également effectuer un traitement de surbrillance sur SQL. sql-parser est implémenté en langage PHP pur. C'est également l'un des rares modules de l'ensemble du code source de phpMyAdmin à avoir une structure de code relativement claire et à être conforme aux spécifications standard PSR actuelles de l'industrie PHP.
Installation du composant SQL-parser
Vous devez installer php, le client git et l'outil de gestion des packages php composer à l'avance
margin@margin-MB1:~/tmp$ sudo git clone https://github.com/phpmyadmin/sql-parser.git margin@margin-MB1:~/tmp$ cd sql-parser && sudo composer install
Le composant est installé spécifique. les détails sont présentés ci-dessous. Appelez
pour analyser les instructions ordinaires
require_once '../sql-parser/vendor/autoload.php'; use SqlParser\Parser; $query = 'SELECT * FROM t1 LEFT JOIN (t2, t3, t4) ' . 'ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)'; $parser = new Parser($query); $stmt = $parser->statements[0]; echo json_encode($stmt);
La variable $parser dans le résultat en cours d'exécution est un objet volumineux, qui stocke les résultats de l'analyse lexicale de l'instruction $query. $query->list, analyse syntaxique Résultats $query-statements et messages d'erreur, etc.
La structure des instructions $query est la suivante :
{"expr": [{"database":null,"table":null,"column":null,"expr":"*","alias":null,"function":n ull,"subquery":null}],"from": [{"database":null,"table":"t1","column":null,"expr":"t1","alias":null,"function": null,"subquery":null}],"partition":null,"where":null,"group":null,"having":null," order":null,"limit":null,"procedure":null,"into":null,"join": [{"type":"LEFT","expr":{"database":null,"table":null,"column":null,"expr":"(t2, t3, t4)","alias":null,"function":null,"subquery":null},"on":[{"identifiers": ["t2","a","t1"],"isOperator":false,"expr":"(t2.a=t1.a"},{"identifiers": [],"isOperator":true,"expr":"AND"},{"identifiers": ["t3","b","t1"],"isOperator":false,"expr":"t3.b=t1.b"},{"identifiers": [],"isOperator":true,"expr":"AND"},{"identifiers": ["t4","c","t1"],"isOperator":false,"expr":"t4.c=t1.c)"}],"using":null}],"union": [],"options":{"options":[]},"first":0,"last":50}
Parse transaction
require_once '../sql-parser/vendor/autoload.php'; use SqlParser\Parser; $query = 'START TRANSACTION;' . 'SELECT @A:=SUM(salary) FROM table1 WHERE type=1;' . 'UPDATE table2 SET summary=@A WHERE type=1;' . 'COMMIT;'; $parser = new Parser($query); $stmt = $parser->statements[0]; echo json_encode($stmt);
Résultat de sortie :
{"type":1,"statements":[{"expr": [{"database":null,"table":null,"column":null,"expr":"@A:=SUM(salary)","alias":nul l,"function":"SUM","subquery":null}],"from": [{"database":null,"table":"table1","column":null,"expr":"table1","alias":null,"fu nction":null,"subquery":null}],"partition":null,"where":[{"identifiers": ["type"],"isOperator":false,"expr":"type=1"}],"group":null,"having":null,"order": null,"limit":null,"procedure":null,"into":null,"join":null,"union":[],"options": {"options":[]},"first":1,"last":19},{"tables": [{"database":null,"table":"table2","column":null,"expr":"table2","alias":null,"fu nction":null,"subquery":null}],"set":[{"column":"summary","value":"@A"}],"where": [{"identifiers": ["type"],"isOperator":false,"expr":"type=1"}],"order":null,"limit":null,"options" :{"options":[]},"first":20,"last":35}],"end": {"type":2,"statements":null,"end":null,"options":{"options": {"1":"COMMIT"}},"first":36,"last":37},"options":{"options":{"1":"START TRANSACTION"}},"first":0,"last":0}
En plus des deux instructions ci-dessus, sql-parser prend également en charge l'analyse des procédures stockées et presque toute la syntaxe MySQL. Je ne donnerai pas d'exemples un par un. Ce qui suit est un exemple d'utilisation de son constructeur SQL.
Instruction Assembler SQL
Instruction Assembler select :
require_once '../sql-parser/vendor/autoload.php'; use SqlParser\Components\OptionsArray; use SqlParser\Components\Expression; use SqlParser\Components\Condition; use SqlParser\Components\Limit; use SqlParser\Statements\SelectStatement; $stmt = new SelectStatement(); $stmt->options = new OptionsArray(array('DISTINCT')); $stmt->expr[] = new Expression('sakila', 'film', 'film_id', 'fid'); $stmt->expr[] = new Expression('COUNT(film_id)'); $stmt->from[] = new Expression('', 'film', ''); $stmt->from[] = new Expression('', 'actor', ''); $stmt->where[] = new Condition('film_id > 10'); $stmt->where[] = new Condition('OR'); $stmt->where[] = new Condition('actor.age > 25'); $stmt->limit = new Limit(1, 10); var_dump($stmt->build());
Résultat de sortie :
margin@margin-MB1:~/code/parserTest$ php build.php string(137) "SELECT DISTINCT `sakila`.`film`.`film_id` AS `fid`, COUNT(film_id) FROM `film`, `actor` WHERE film_id > 10 OR actor.age > 25 LIMIT 10, 1 "
Instruction de déclenchement Assembler :
require_once '../sql-parser/vendor/autoload.php'; use SqlParser\Components\Expression; use SqlParser\Components\OptionsArray; use SqlParser\Statements\CreateStatement; $stmt = new CreateStatement(); $stmt->options = new OptionsArray(array('TRIGGER')); $stmt->name = new Expression('ins_sum'); $stmt->entityOptions = new OptionsArray(array('BEFORE', 'INSERT')); $stmt->table = new Expression('account'); $stmt->body = 'SET @sum = @sum + NEW.amount'; var_dump($stmt->build());
Résultat de sortie :
margin@margin-MB1:~/code/parserTest$ php build.php string(89) "CREATE TRIGGER ins_sum BEFORE INSERT ON account FOR EACH ROW SET @sum = @sum + NEW.amount"
Retraitement SQL
Plusieurs instructions traitées ensemble :
require_once '../sql-parser/vendor/autoload.php'; use SqlParser\Parser; use SqlParser\Components\Expression; $query = <<<str id="3" from="" change="" $statement_0="$parser-" 处理第一条语句="" parser($query);="" $parser="new" str;="" where="" tbl3="" *="" select="" null;="" not="" unsigned="" )="" 10="" int(="" `field_2`="" `field_1`="" `tbl`="" table="" alter="" auto_increment;="" null="" `uid`="">statements[0]; $statement_0->table = new Expression( 'db2', 'tb2', '' ); var_dump($statement_0->build()); //处理第二条语句 $statement_1 = $parser->statements[1]; $statement_1->table = new Expression( 'db3', 'tb3', '' ); var_dump($statement_1->build());</str>
Résultats de sortie :
margin@margin-MB1:~/code/parserTest$ php build.php string(85) "ALTER TABLE `db2`.`tb2` CHANGE `uid` `uid` INT( 10 ) UNSIGNED NOT NULL AUTO_INCREMENT" string(78) "ALTER TABLE `db3`.`tb3` CHANGE `field_1` `field_2` INT( 10 ) UNSIGNED NOT NULL"
Ci-dessus sont quelques exemples d'utilisation de base du composant sql-parser. Le composant sql-parser de phpMyAdmin a des fonctions relativement riches et complètes. Cet article ne peut pas être exhaustif en raison des limitations d'espace. Code source pour en savoir plus sur une utilisation plus avancée.
Recommandations associées :
Quelques opérations sur l'optimisation MySQL
Optimisation MySQL (3) index clusterisé et index non clusterisé
Introduction détaillée au code graphique des techniques d'optimisation MySql SQL
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!