Я знаю этот вопрос, если плаваю повсюду, но я не могу применить его к своей проблеме.
Я использую не параметризованные запросы, что делает мой проект чрезвычайно уязвимым для SQL-инъекций
Участок:
У меня есть форма, где вы вводите дату.
PHP получит дату и использует ее в запросе для получения нескольких строк информации.
Как я могу параметризовать мои запросы MySQL и распечатать несколько строк? Это то, что я до сих пор:
HTML
<form action="#" class="form-horizontal" method="post">
<label for="fromDate" class="control-label">Date from:</label>
<input type="date" id="fromDate" class="datepicker" name="searchDate" value="<?php echo $searchDate; ?>">
<button type="submit" class="btn">Go</button>
<input type="hidden" name="formIdentifier" value="mainSearch" />
</form>
PHP
if($_POST['formIdentifier'] == "mainSearch"){
//get date from form
$searchDate = $_POST['searchDate'];
$todayDateFrom = $searchDate." 00:00:00";
$todayDateTo = $searchDate." 23:59:59";
$stmt = $conn->prepare("SELECT G.* FROM Groups AS G, Customers AS C
WHERE C.travel_Date >= '?'
AND C.travel_Date <= '?'
AND C.customer_ID = G.leader_ID");
$stmt->bind_param("si", todayDateFrom , todayDateTo );
$stmt->execute();
/* bind variables to prepared statement */
$stmt->bind_result($col1, $col2);
}
PHP цикл
while ($stmt->fetch()) {
//Display copious amounts of data.
}
Я основал свой код из руководства по PHP и в итоге оказался перегружен. Я даже не уверен, что нахожусь на правильном пути в подготовке своих запросов, не говоря уже о попытках отобразить данные. Любая помощь будет оценена!
примечание — если бы кто-то мог объяснить $stmt->bind_param("si", todayDateFrom , todayDateTo );
особенно «си», это было бы фантастически. Я просто не понимаю, какова его цель.
—РЕШЕНИЕ—
Благодаря всем ответам я смог заставить работать свой первый параметризованный запрос.
Как и предполагалось, я удалил «», который окружал «?» В моем запросе.
Затем я изменил bind_param
«si» — «ss», потому что я связывал 2 строки, а не строку и целое число.
Затем я связал результаты (в этом примере у меня есть 3 столбца в таблице)
$stmt->bind_result($group_ID, $leader_ID, $gDate);
Поскольку у меня в настоящее время не установлен драйвер стороннего производителя, мне пришлось отображать результаты примерно так:
while ($stmt->fetch()) {
echo "group_ID: ".$group_ID."<br />";
echo "leader_ID: ".$leader_ID."<br />";
echo "group_Date: ".$group_Date."<br />";
}
Ваш существующий код работает просто отлично, за исключением одной маленькой ошибки из руководства Руководство по PHP MySQLi bind_param
я соответствующая переменная имеет тип integer
d соответствующая переменная имеет тип double
s соответствующая переменная имеет тип string
Итак, сверху мы видим, что «i» используется, если вы хотите сказать MySQLi, что ваш параметр на самом деле является целочисленным, и «s» используется, если вы хотите сообщить MySQLi, что ваш параметр является на самом деле строкой.
Поэтому, пожалуйста, замените
$stmt->bind_param("si", todayDateFrom , todayDateTo );
с
$stmt->bind_param("ss", todayDateFrom , todayDateTo );
и удалить
‘
из заполнителей параметров (т. е. ‘?’ следует заменить на?)
И ваш код отправки параметризованного оператора будет работать нормально
Получение результатов
Из руководства PHP MySQLi выборки что делает fetch:
Извлечь результаты из подготовленного оператора в связанные переменные
То, что вы ищете, это get_result. Из руководства это:
Получает набор результатов из подготовленного оператора
Таким образом, вы можете получить данные, используя следующий код:
$result = $stmt->get_result();
while ($row = $result->fetch_array(MYSQLI_NUM))
{
foreach ($row as $r)
{
print "$r ";
}
print "\n";
}
Вот документация для fetch_array
Вам нужно изменить следующую строку:
$stmt->bind_param("si", todayDateFrom , todayDateTo );
Для того, чтобы:
$stmt->bind_param("ss", todayDateFrom , todayDateTo );
Причина: Если вы посмотрите на следующее изображение, вы можете увидеть, что i
для Integer
а также s
для String
,
Параметр даты должен быть представлен как String
, следовательно, использовать s
,
Ссылка: PHP mysqli_stmt :: bind_param Документации.
Также вам необходимо обновить ваш оператор SQL:
$stmt = $conn->prepare("SELECT G.* FROM Groups AS G, Customers AS C
WHERE C.travel_Date >= '?'
AND C.travel_Date <= '?'
AND C.customer_ID = G.leader_ID");
Для того, чтобы:
$stmt = $conn->prepare("SELECT G.* FROM Groups AS G, Customers AS C
WHERE C.travel_Date >= ?
AND C.travel_Date <= ?
AND C.customer_ID = G.leader_ID");
Причина: Метка параметра не должна быть окружена '
,
$stmt->bind_param("si", todayDateFrom , todayDateTo );
Во время связывания параметров вы упоминаете, что первая переменная — строка, а вторая — целое число, но согласно вашему коду это должно быть
$stmt->bind_param("ss", $todayDateFrom , $todayDateTo );
Пожалуйста, удалите одинарные кавычки из вашего запроса, и должно быть что-то вроде этого
$stmt = $conn->prepare("SELECT G.* FROM Groups AS G, Customers AS C
WHERE C.travel_Date >= ?
AND C.travel_Date <= ?
AND C.customer_ID = G.leader_ID");