php - 有没有办法让 PHP 在不执行 SQL 语法的情况下验证它?

标签 php mysql sql

我想构建一个 PHP 脚本来验证 SQL 查询,但不执行它。它不仅应该验证语法,而且如果可能的话,还应该让您知道查询是否可以在给定查询中的命令的情况下执行。这是我希望它执行的操作的伪代码:

<?php
//connect user
//connect to database
//v_query = $_GET['usrinput'];
if(validate v_query == true){
echo "This query can be executed";
}
else{
echo "This query can't be executed because the table does not exist.";
}

//disconnect 
?>

是这样的。我希望它在不执行查询的情况下模拟查询。这就是我想要的,但我在这上面找不到任何东西。

我们不希望执行查询的一个例子是,如果查询向数据库添加了一些东西。我们只是希望它在不修改数据库的情况下模拟它。

任何链接或示例将不胜感激!

最佳答案

从 MySQL 5.6.3 开始,您可以对大多数查询使用 EXPLAIN

我做了这个,效果很好:

function checkMySqlSyntax($mysqli, $query) {
   if ( trim($query) ) {
      // Replace characters within string literals that may *** up the process
      $query = replaceCharacterWithinQuotes($query, '#', '%') ;
      $query = replaceCharacterWithinQuotes($query, ';', ':') ;
      // Prepare the query to make a valid EXPLAIN query
      // Remove comments # comment ; or  # comment newline
      // Remove SET @var=val;
      // Remove empty statements
      // Remove last ;
      // Put EXPLAIN in front of every MySQL statement (separated by ;) 
      $query = "EXPLAIN " .
               preg_replace(Array("/#[^\n\r;]*([\n\r;]|$)/",
                              "/[Ss][Ee][Tt]\s+\@[A-Za-z0-9_]+\s*:?=\s*[^;]+(;|$)/",
                              "/;\s*;/",
                              "/;\s*$/",
                              "/;/"),
                        Array("","", ";","", "; EXPLAIN "), $query) ;

      foreach(explode(';', $query) as $q) {
         $result = $mysqli->query($q) ;
         $err = !$result ? $mysqli->error : false ;
         if ( ! is_object($result) && ! $err ) $err = "Unknown SQL error";
         if ( $err) return $err ;
      }
      return false ;
  }
}

function replaceCharacterWithinQuotes($str, $char, $repl) {
    if ( strpos( $str, $char ) === false ) return $str ;

    $placeholder = chr(7) ;
    $inSingleQuote = false ;
    $inDoubleQuotes = false ;
    $inBackQuotes = false ;
    for ( $p = 0 ; $p < strlen($str) ; $p++ ) {
        switch ( $str[$p] ) {
            case "'": if ( ! $inDoubleQuotes && ! $inBackquotes ) $inSingleQuote = ! $inSingleQuote ; break ;
            case '"': if ( ! $inSingleQuote && ! $inBackquotes ) $inDoubleQuotes = ! $inDoubleQuotes ; break ;
            case '`': if ( ! $inSingleQuote && ! $inDoubleQuotes ) $inBackquotes  = ! $inBackquotes ; break ;
            case '\\': $p++ ; break ;
            case $char: if ( $inSingleQuote || $inDoubleQuotes || $inBackQuotes) $str[$p] = $placeholder ; break ;
        }
    }
    return str_replace($placeholder, $repl, $str) ;
 }

如果查询正常(允许多个;允许分隔语句),它将返回 False,如果存在语法或其他 MySQL 其他(如不存在的表或列),则返回错误消息说明错误。

PHP Fiddle

已知错误:

  • 带有行号的 MySQL 错误:行号大多不匹配。
  • 不适用于 SELECT、UPDATE、REPLACE、INSERT、DELETE 以外的 MySQL 语句

关于php - 有没有办法让 PHP 在不执行 SQL 语法的情况下验证它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8045536/

相关文章:

mysql - 如何显示来自 3 个连接的单个项目的记录或数据

MySQL CASE WHEN where 子句导致失败

sql - 如何将具有相同字段的两个表的结果合并到一个字段中?

php - 如何使用 PHPUnit 的 --filter 选项按 "ends with"进行过滤?

php - 从 MySQL 中删除行

php - Gallery Pro 表进入 WordPress 的 mysql

php - 来自mysql结果的多维数组

mysql - 使用其他 2 个表的计算更新表

sql - 当进一步使用 CROSS APPLY 时,我可以在第一个 SELECT 中使用 GROUP BY 吗?

php - 在 Codeigniter 中在哪里设置 session ?