Я хотел бы создать PHP-скрипт, который будет проверять SQL-запрос, но не выполняет его. Мало того, что он должен проверять синтаксис, но должен, если это возможно, сообщить вам, может ли запрос быть выполнен с учетом команды, которая находится в запросе. Вот Pseudocode того, что я хотел бы сделать:
<?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 ?>
Что-то вроде этого. Я хочу, чтобы он симулировал запрос без его выполнения. Это то, чего я хочу, и я ничего не могу найти по этому поводу.
Пример того, почему мы не хотим, чтобы запрос выполнялся, заключается в том, что запрос добавляет что-то в базу данных. Мы просто хотим, чтобы он имитировал его без изменения базы данных.
Любые ссылки или примеры были бы высоко оценены!
Вы можете попробовать эту библиотеку: http://code.google.com/p/php-sql-parser/ . Я еще не использовал его, поэтому я не могу этого гарантировать, но код выглядит так, что он сможет отличить действительный и недействительный SQL.
Другим вариантом может быть использование транзакций, если это позволяет вариант SQL. Сделка позволит вам выполнить SQL, а затем отменить его, после чего отменит любой ущерб, который был нанесен. Я думаю, что предпочел бы вариант 1.
Вы не можете просто анализировать и проверять SQL, потому что вам нужно проверить наличие таблиц, действительность JOIN и т. Д. Единственный способ сделать полный интегративный тест – фактически запустить запрос. Вы можете обернуть его в транзакцию, а затем откат. Однако плохо разработанный или вредоносный запрос может привести к тому, что ваш сервер встанет на колени или уничтожит данные.
Из MySQL 5.6.3 вы можете использовать EXPLAIN для большинства запросов
Я сделал это, и он прекрасно работает:
function checkMySqlSyntax($mysqli, $query) { if ( trim($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 ; } }
Он вернет False, если запрос в порядке (разрешено несколько разрешенных операторов) или сообщение об ошибке, указывающее на ошибку, если есть синтаксис или другой другой MySQL (например, несуществующая таблица или столбец).
ИЗВЕСТНЫЕ ОШИБКИ: