Как защитить форму от ошибок и sql инъекции?

Вот обработка данных как происходит

<?php
include_once 'db.php';

if (isset($_POST['add'])) {

// преобразуем специальные символы в текст

$name = htmlspecialchars($_POST['name']);
$text = htmlspecialchars($_POST['text']);
$message = htmlspecialchars($_POST['message']);
$rating = htmlspecialchars($_POST['rating']);

// заносим данные из формы в переменные и проверяем на ошибки

$name = strip_tags(trim($_POST['name']));
$text = strip_tags(trim($_POST['text']));
$message = strip_tags(trim($_POST['message']));
$rating = strip_tags(trim($_POST['rating']));
$date = $_POST['date'];

// заносим дату и время отзыва
$date = date('Y-m-d H:i');

// проверка введенных данных

if($name != '' AND $text != '' AND $message != '')

// отправка данных в бд

mysqli_query($link, " INSERT INTO Otzivy2 (name, text, message, date, rating) VALUES ('$name', '$text', '$message', '$date', '$rating')");
$to      = 'почта';
$subject = 'review';
$message = "Текст отзыва: " . $_POST['message'] . "\nОт: " . $_POST['text'] . " " . $_POST['email'] . "\nВремя: " . date("d.m.Y - H:i");
$headers = array(
    'From' => 'почта',
    'Reply-To' => 'почта',
    'X-Mailer' => 'PHP/' . phpversion()
);

mail($to, $subject, $message, $headers);
}




// закрываем сеанс


include_once 'clear.php';
include_once 'form.php';

?> 

Ответы (1 шт):

Автор решения: Ипатьев

Для того чтобы навсегда избежать любых проблем с передаваемыми в запрос данными, будь то ошибки или взлом сайта, любые данные надо всегда передавать в базу данных отдельно от запроса. Это делается с помощью подготовленных, или, как их ещё называют, параметризованных запросов.

В mysqli, чтобы выполнить параметризованный запрос, необходимо выполнить 4 действия:

  • Заменить все переменные в запросе на специальные маркеры, которые называются плейсхолдеры или параметры, а по сути - просто знаки вопроса
  • Подготовить запрос к исполнению с помощью функции prepare(). Эта функция принимает строку запроса и возвращает экземпляр специального класса mysqli_stmt, с которым в дальнейшем и производятся все манипуляции
  • Привязать переменные к запросу с помощью bind_param(). Это очень интересная функция. Она принимает в качестве параметров все переменные, которые должны попасть в запрос, в том же самом порядке, в котором стоят плейсхолдеры в запросе. Но кроме того, сначала в этой функции должны быть указаны типы для всех переменных, в виде строки, где тип переменной обозначается одной буквой. То есть букв в этой строке должно быть ровно столько, сколько дальше будет переменных. К счастью, можно особо не париться с типами и для всех переменных указывать тип "s".
  • Выполнить запрос с помощью с помощью execute(). Эта функция выполняется без параметров

На словах это звучит длинно, но на практике получается не так сложно:

$sql = "INSERT INTO Otzivy2 (name, text, message, date, rating) VALUES (?,?,?,?,?)";
$stmt = $link->prepare($sql);
$stmt->bind_param("sssss", $name, $text, $message, $date, $rating);
$stmt->execute();

То же самое касается и запросов SELECT. Только для получения результата запроса надо выполнить еще одну команду - get_result().

Например

$sql = "SELECT * FROM Otzivy2 LIMIT ?,?";
$stmt = $db->prepare($sql);
$stmt->bind_param("ss", $start, $num);
$stmt->execute();
$result = $stmt->get_result(); // получаем result

а дальше как обычно fetch или while

→ Ссылка