Я всегда делал простую связь mysql_connect
, mysql_pconnect
:
$db = mysql_pconnect('*host*', '*user*', '*pass*');
if (!$db) {
echo("<strong>Error:</strong> Could not connect to the database!");
exit;
}
mysql_select_db('*database*');
При использовании этого я всегда использовал простой метод для удаления любых данных перед выполнением запроса, будь то INSERT
, SELECT
, UPDATE
или DELETE
с помощью mysql_real_escape_string
$name = $_POST['name'];
$name = mysql_real_escape_string($name);
$sql = mysql_query("SELECT * FROM `users` WHERE (`name` = '$name')") or die(mysql_error());
Теперь я понимаю, что это безопасно, в какой-то степени!
Он избегает опасных символов; тем не менее, он по-прежнему уязвим для других атак, которые могут содержать безопасные символы, но могут быть вредны для отображения данных или в некоторых случаях, изменения или удаления данных злонамеренно.
Итак, я немного искал и узнал о PDO, MySQLi и подготовленных операциях. Да, я могу опаздывать на игру, но я читал много, много учебников (tizag, W3C, блоги, поисковые запросы Google), и ни один из них не упомянул об этом. Похоже, очень странно, почему, так как просто избежать пользовательского ввода действительно небезопасно, а не хорошая практика, если не сказать больше. Да, я знаю, что вы можете использовать Regex, чтобы справиться с этим, но все же, я уверен, что этого недостаточно?
Насколько я понимаю, использование PDO/подготовленных операторов - гораздо более безопасный способ хранения и извлечения данных из базы данных, когда переменные задаются пользователем. Единственная проблема заключается в том, что переход (особенно после того, как я сильно застрял в моих привычках/привычках предыдущего кодирования) немного сложнее.
Сейчас я понимаю, что для подключения к моей базе данных с использованием PDO я бы использовал
$hostname = '*host*';
$username = '*user*';
$password = '*pass*';
$database = '*database*'
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
if ($dbh) {
echo 'Connected to database';
} else {
echo 'Could not connect to database';
}
Теперь имена функций разные, поэтому больше не будут работать мои mysql_query
, mysql_fetch_array
, mysql_num_rows
и т.д. Поэтому мне приходится читать/запоминать загрузку новых, но здесь я смущаюсь.
Если бы я хотел вставить данные из формы регистрации/регистрации, как бы я это сделал, но в основном, как бы я мог сделать это безопасно? Я предполагаю, что это то, где приходят подготовленные заявления, но, используя их, это устраняет необходимость использовать что-то вроде mysql_real_escape_string
? Я знаю, что mysql_real_escape_string
требует, чтобы вы подключались к базе данных с помощью mysql_connect
/mysql_pconnect
, так что теперь мы не используем, не будет ли эта функция выдавать ошибку?
Я видел различные способы подхода к методу PDO, например, я видел :variable
и ?
как то, что, как я думаю, называется владельцами мест (извините, если это не так).
Но я думаю, что это примерно идея о том, что нужно сделать для извлечения пользователя из базы данных
$user_id = $_GET['id']; // For example from a URL query string
$stmt = $dbh->prepare("SELECT * FROM `users` WHERE `id` = :user_id");
$stmt->bindParam(':user_id', $user_id, PDO::PARAM_INT);
Но тогда я застрял на нескольких вещах, если переменная не была числом и была строкой текста, вам нужно дать длину после PDO:PARAM_STR
, если я не ошибаюсь. Но как вы можете дать заданную длину, если вы не уверены в значении, указанном в пользовательских данных, он может меняться каждый раз? В любом случае, насколько я знаю, чтобы отобразить данные, которые вы затем выполняете
$stmt->execute();
$result = $stmt->fetchAll();
// Either
foreach($result as $row) {
echo $row['user_id'].'<br />';
echo $row['user_name'].'<br />';
echo $row['user_email'];
}
// Or
foreach($result as $row) {
$user_id = $row['user_id'];
$user_name = $row['user_name'];
$user_email = $row['user_email'];
}
echo("".$user_id."<br />".$user_name."<br />".$user_email."");
Теперь, это все безопасно?
Если я прав, вставка данных будет одинаковой, например:
$username = $_POST['username'];
$email = $_POST['email'];
$stmt = $dbh->prepare("INSERT INTO `users` (username, email)
VALUES (:username, :email)");
$stmt->bindParam(':username, $username, PDO::PARAM_STR, ?_LENGTH_?);
$stmt->bindParam(':email, $email, PDO::PARAM_STR, ?_LENGTH_?);
$stmt->execute();
Будет ли это работать, и это тоже безопасно? Если правильно, какое значение я бы добавил для ?_LENGTH_?
? У меня все это было совершенно неправильно?
UPDATE
Ответы, которые у меня были до сих пор, были чрезвычайно полезны, не могу поблагодарить вас, ребята, достаточно! У каждого есть +1 для открытия моих глаз до чего-то другого. Трудно выбрать верный ответ, но я думаю, что Col. Shrapnel заслуживает этого, поскольку все в значительной степени покрыто, даже если он входит в другие массивы с пользовательскими библиотеками, о которых я не знал!
Но спасибо всем вам:)