У меня есть 2 страницы на веб-сайте, одна из них – index.php и индексная страница список всех сообщений, которые существуют в базе данных, а другая страница – post.php и post page display single post при нажатии на определенное сообщение на индексной странице.
Теперь код, который я использовал для перечисления всех сообщений в index.php:
$postslist = mysqli_query($db, "SELECT * FROM posts"); while ($post = mysqli_fetch_array($postlist)) { echo '<a href="' .SITEURL.'/post.php?p='.$post['postid'].'>'.$post['title'].'</a>'; }
И это работает, и у меня есть все сообщения, отображаемые на моей странице index.php и ссылки для публикации на post.php странице.
И на странице post.php я использовал такой код:
if(!isset($_GET['p'])){ echo 'Dont load this page directly'; } else { $id = $_GET['p']; $querypost = mysqli_query($conn, "SELECT * FROM posts WHERE postid='$id'"); $data = mysqli_fetch_array($querypost); echo '<h3>' . $data['title'] . '</h3>'; }
И это отлично работает и возвращает сообщение с этим идентификатором, но я читаю некоторые учебные пособия и сообщения здесь, в stackoverflow, и это может быть немного неуверенно, и было предложено использовать такой код, чтобы убедиться, что он безопасен для использования базы данных
if(!isset($_GET['p'])){ echo 'Dont load this page directly'; } else { $id = $_GET['p']; $id = mysqli_real_escape_string($id); $querypost = mysqli_query($conn, "SELECT * FROM posts WHERE postid='$id'"); $data = mysqli_fetch_array($querypost); echo '<h3>' . $data['title'] . '</h3>'; }
Но это порождает ошибку, поэтому достаточно ли она достаточно защищена от базы данных, если существует postid, и как я могу сделать ее защищенной, если это недостаточно безопасно?
Редактирование: Ну, я взял на себя поиск методов, опубликованных у вас, ребята, и через несколько часов я включил его в mysqli_prepare, но его использование в post.php довольно просто, поскольку оно только подключается к таблице сообщений и вытаскивает все данные из одной таблицы по сообщению id.
Но когда я пробовал такой же метод на другой странице, это стало довольно большим решением.
На второй странице мне приходится извлекать данные из 5 разных таблиц, которые объединяются с использованием LEFT JOIN во все соответствия определенного идентификатора из определенного столбца в таблице, и это то, что вышло только с использованием 3 таблиц.
$stmt = mysqli_prepare($conn, "SELECT * FROM giveaways INNER JOIN members ON giveaways.creator = members.steamID INNER JOIN sc_steamgames ON giveaways.gameid = sc_steamgames.appid WHERE giveawayID=?"); mysqli_stmt_bind_param($stmt, "i", $id); mysqli_stmt_execute($stmt); mysqli_stmt_bind_result($stmt, $id, $creator, $comment, $tcreated, $tstarting, $tfinish, $provider, $type, $gameid, $memberid, $steamid, $username, $profileurl, $avatar, $avatarmed, $avatarbig, $steamgames, $regdate, $verified, $coins, $gold, $points, $appid, $title, $storeprice, $valuedprice, $pointsworth); mysqli_stmt_fetch($stmt); echo $creator .' - '. $comment . ' - '. $gameid . ' - ' .$title.' - '.($storeprice /100) ; mysqli_stmt_close($stmt);
И это прекрасно работает, но вы можете видеть, насколько массивным это стало с 3 таблицами, и мне нужно вывести информацию из еще двух таблиц, поэтому мне было интересно, действительно ли это решение, которое вы бы использовали?
И еще один вопрос, если пользователь должен просматривать страницу со статическим значением, например
index.php?go=upcoming
Нужно ли мне также использовать некоторую дополнительную безопасность или использовать ее, как сейчас
if(isset($_GET['go']) && $_GET['go'] == 'upcoming')
достаточно безопасна? Поскольку существует известная ценность go и чего ожидать.
Это mysqli_real_escape_string
ошибку, потому что mysqli_real_escape_string
ожидает два аргумента, первым из которых является соединение $conn
.
Если вы это сделаете, он должен быть достаточно безопасным , но лучше использовать параметризованный запрос. Например:
$stmt = mysqli_prepare($conn, "SELECT cols FROM posts WHERE postid = ?"); mysqli_stmt_bind_param($stmt, 'i', $id);
Проверка того, что id
существует в базе данных, вовсе не защищен от инъекций, поскольку вам необходимо использовать потенциально вредоносный id
в запросе, чтобы выполнить проверку в первую очередь.
Если ваш столбец id
является целым числом, используйте следующее:
$id = (int) $_GET['p'];
Это будет безопасно, потому что принуждение типа (int) уничтожает любые незаконные символы.
Обеспечение безопасности SQL также может быть простым: всегда используйте параметры для динамических значений. Это работает для целых значений, строк и дат. Тогда вам не нужно беспокоиться о цитировании или выходе или фильтрации. @ExplosionPills показывает пример.