Вот мой код.
function login($username,$password){
global $db;
$sql = "SELECT * FROM users133 WHERE username=:username";
$stmt = $db->prepare($sql);
$stmt->execute(array(':username' => $username));
if ($stmt->rowCount() > 0){
$result = $stmt->fetchAll();
$hash = $result[0]['password'];
if (password_verify($password, $hash)) {
$_SESSION['loggedIn'] = $result[0]['id'];
header("location: ?page=profile"); /*<----AFTER LOGING IN YOU GET TO THIS PAGE*/
}else{
header("location: ?page=loginfailed");
}
}
else{
header("location: ?page=loginfailed");
}
}Да, я знаю, что этот пост дублируется, но есть дополнительные вещи, которые мне нужно спросить!! Сегодня я провожу около 6 часов, читая, как делать подготовленные операторы. я читал о команде $stmt->bindParam, которая заставляет базу данных проверять, является ли входное значение целым, строковым и т. д. (на случай, если пользователь играл с параметром элемента проверки или поместил вредоносный код в форму). Это необходимо для подготовленного оператора SELECT? Я планирую скопировать код этой функции входа в систему и использовать его в другом месте на своем сайте. Вот почему мне нужно спросить, на 100% ли это так, как сейчас.






Да, вы используете подготовленный оператор с параметром. Это правильно. В большинстве случаев параметры — это лучший способ написать безопасные операторы SQL. Есть всего несколько крайних случаев, когда они не помогают (см. мой ответ на насколько безопасны подготовленные операторы PDO)
Я могу предложить некоторые небольшие изменения в зависимости от того, как я буду писать код.
$sql = "SELECT id, password FROM users133 WHERE username=:username";
Избегайте SELECT *, всегда четко указывайте столбцы. Видеть
$stmt = $db->prepare($sql);
$stmt->execute(['username' => $username]);
Если вы включили исключения PDO, это нормально, потому что любая ошибка SQL прервет код и вызовет исключение. Но если вы не включили исключения, вы всегда должны проверять возвращаемое значение как prepare(), так и execute(). См. http://php.net/manual/en/pdo.error-handling.php и http://php.net/manual/en/pdo.errorinfo.php
Синтаксис array() взят из старых версий PHP, а начиная с PHP 5.4 вы можете использовать более короткий синтаксис с квадратными скобками.
Вам не нужно использовать : в вашем ключе для параметра PDO. Только в строке SQL. В старых версиях PDO вам нужно было : в обоих местах, но не сейчас.
while (row = $stmt->fetch()) {
$hash = $row['password'];
if (password_verify($password, $hash)) {
$_SESSION['loggedIn'] = $row['id'];
header("location: ?page=profile");
}else{
header("location: ?page=loginfailed");
}
}
header("location: ?page=loginfailed");
Вышеизложенное позволяет избежать вызова rowCount(). Если рядов нет, то while() естественно завершается, не сделав ни одного цикла, а потом проваливается до последнего вызова header().
Я предпочитаю не звонить rowCount(), потому что сложно вспомнить, когда это работает, а когда нет. rowCount() вернет 0 до того, как клиент получит все строки с сервера MySQL. Иногда выполнение запроса неявно извлекает все строки в память клиента, а затем вызов fetch() просто перебирает их. Это называется буферизованным запросом. Но небуферизованные запросы полезны, если ваш результат будет содержать слишком много строк для буферизации. Так что не всегда ясно, когда rowCount() вернет точный счет.
Большое спасибо за ваше время. Честно говоря, ваш вариант мне кажется немного сложным. Я даже никогда не использовал команду «пока». Я буду продолжать свой путь. Еще раз спасибо за ваше время. Да, исключения PDO включены.
В этом случае, поскольку вы ищете только один результат, вы можете использовать «если» вместо «пока». Аргумент для оператора while является важной вещью. Он делает две вещи одновременно: извлекает следующую строку, но если строки не существует, условное выражение терпит неудачу. Это очень полезная практика, которой стоит научиться. Не говоря уже о том, что это позволяет избежать душевной боли, которая может быть у rowCount.
Комментарии не для расширенного обсуждения; этот разговор был перешел в чат.