Доброго времени суток, я понимаю тема избитая и скорее всего есть массу ответов на мой вопрос, но у меня не получается, прошу помочь разобраться. У меня есть скрипт которые принимает значения из глобального массива (для простоты сделал из $GET, у меня скрипт намного больше выполняет функционала, я просто оставил все что касается моего вопроса, остальное убрал) для записи в базу. PHP: <?php $db = mysqli_connect('localhost','root', 'motorola', 'yz'); if (!$db) { die("Connection failed: " . mysqli_connect_error()); } //обрезаем пробелы в начале и в конце значений массива $_GET $_GET = array_map(function($items) { if (is_array($items)) foreach ($items as $key => $value) $items[$key] = trim($value); else $items = trim($items); return $items; }, $_GET); if (!empty($_GET)){ $query1 = "INSERT INTO `baza` SET "; foreach ($_GET as $key => $value) { //для каждого элемента массива GET if(empty($value)){ //если пустой то NULL $value = NULL; } //если не массив if (!is_array($value) && $value!=null) { //добавим к строке запроса 1 $query1 .= " $key = '$value' ,"; } } $query1 = rtrim($query1, ','); echo 'Запрос 1 '.$query1.'<hr/>';//это получившаяся строка запроса ее нужно проверить. $rec = mysqli_query($db,$query1);//если строка устраивает тогда выполнить запрос //закрываем соединение с базой mysqli_close($db); if ($rec != TRUE){ echo 'Запись в базу не произведена'; } else { echo 'Запись в базу произведена'; } } ?> и если в адресной строке пропишем например: Код (Text): http://uz/ecran.php?adres=Vladimir&shema=LLL то все хорошо, запись в базу производится и получаем вывод скрипта Код (Text): Запрос 1 INSERT INTO `baza` SET adres = 'Vladimir' , shema = 'LLL' Запись в базу произведена Но естественно в значениях массива может закрасться спецсимвол, например одинарная кавычка '. Код (Text): http://uz/ecran.php?adres=Vla'dimir&shema=LLL Тогда получаю естественно ошибку: Код (Text): Запрос 1 INSERT INTO `baza` SET adres = 'Vla'dimir' , shema = 'LLL' Fatal error: Uncaught mysqli_sql_exception: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'dimir' , shema = 'LLL'' at line 1 in F:\server\OpenServer\domains\uz\ecran.php:31 Stack trace: #0 F:\server\OpenServer\domains\uz\ecran.php(31): mysqli_query() #1 {main} thrown in F:\server\OpenServer\domains\uz\ecran.php on line 31 Для этих целей вроде как существует специальная функция mysqli_real_escape_string. Я пробую ее применить так: PHP: <?php $db = mysqli_connect('localhost','root', 'motorola', 'yz'); if (!$db) { die("Connection failed: " . mysqli_connect_error()); } //обрезаем пробелы в начале и в конце значений массива $_GET $_GET = array_map(function($items) { if (is_array($items)) foreach ($items as $key => $value) $items[$key] = trim($value); else $items = trim($items); return $items; }, $_GET); if (!empty($_GET)){ $query1 = "INSERT INTO `baza` SET "; foreach ($_GET as $key => $value) { //для каждого элемента массива GET if(empty($value)){ //если пустой то NULL $value = NULL; } //если не массив if (!is_array($value) && $value!=null) { //добавим к строке запроса 1 $query1 .= " $key = '$value' ,"; } } $query1 = rtrim(mysqli_real_escape_string($db, $query1), ','); echo 'Запрос 1 '.$query1.'<hr/>';//это получившаяся строка запроса ее нужно проверить. $rec = mysqli_query($db,$query1);//если строка устраивает тогда выполнить запрос //закрываем соединение с базой mysqli_close($db); if ($rec != TRUE){ echo 'Запись в базу не произведена'; } else { echo 'Запись в базу произведена'; } } ?> При этом вижу что заикранировалась не только одинарная кавычка в слове Vla'dimir, но и все одинарные кавычки в запросе, это вызывает ошибку. Код (Text): Запрос 1 INSERT INTO `baza` SET adres = \'Vla\'dimir\' , shema = \'LLL\' Fatal error: Uncaught mysqli_sql_exception: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\'Vla\'dimir\' , shema = \'LLL\'' at line 1 in F:\server\OpenServer\domains\uz\ecran.php:31 Stack trace: #0 F:\server\OpenServer\domains\uz\ecran.php(31): mysqli_query() #1 {main} thrown in F:\server\OpenServer\domains\uz\ecran.php on line 31 Что я делаю не так?
Спасибо, я сам разобрался, нужно было просто не все экранировать. Но может есть способ более элегантный? PHP: <?php $db = mysqli_connect('localhost','root', 'motorola', 'yz'); if (!$db) { die("Connection failed: " . mysqli_connect_error()); } //обрезаем пробелы в начале и в конце значений массива $_GET $_GET = array_map(function($items) { if (is_array($items)) foreach ($items as $key => $value) $items[$key] = trim($value); else $items = trim($items); return $items; }, $_GET); if (!empty($_GET)){ $query1 = "INSERT INTO `baza` SET "; foreach ($_GET as $key => $value) { //для каждого элемента массива GET if(empty($value)){ //если пустой то NULL $value = NULL; } //если не массив if (!is_array($value) && $value!=null) { //добавим к строке запроса 1 $value = mysqli_real_escape_string($db, $value); $query1 .= " $key = '$value' ,"; } } $query1 = rtrim($query1, ','); echo 'Запрос 1 '.$query1.'<hr/>';//это получившаяся строка запроса ее нужно проверить. $rec = mysqli_query($db,$query1);//если строка устраивает тогда выполнить запрос //закрываем соединение с базой mysqli_close($db); if ($rec != TRUE){ echo 'Запись в базу не произведена'; } else { echo 'Запись в базу произведена'; } } ?>
Делаешь вот такой класс PHP: class job_db { private $db; public function __construct(){ try { $this->db = new PDO('mysql:host=localhost;charset=UTF8;dbname=name', 'name', 'pas'); } catch (PDOException $e) { print "Error!: " . $e->getMessage(); die(); } } public function query($sql, $params = []){ $stmt = $this->db->prepare($sql); if(!empty($params)){ foreach ($params as $key =>$val){ $stmt->bindValue(':'.$key, $val); } } $stmt->execute(); return $stmt; } public function fetchAll($sql, $params = []){ $result = $this->query($sql, $params); return $result->fetchAll(PDO::FETCH_ASSOC); } public function update($sql, $params = []){ $result = $this->query($sql, $params); return $result->rowCount(); } } Функции можешь дописывать любые. Затем на любой другой странице пишешь в начале страницы или в функции PHP: require 'config.php'; $job_db = new job_db(); А что бы обратиться к базе пишешь так PHP: $params = [ 'name'=> $name, 'id'=> $id, ]; $result = $job_db->update("UPDATE `aaa` SET `name`= :name WHERE `id`=:id", $params); И Всё защищено и всё работает