Попытка обновить поле в моей БД, используя подготовленный оператор - PullRequest
0 голосов
/ 31 октября 2018

Я занимался этим весь день, и после поиска по многим веб-сайтам (включая этот) я пришел к выводу, что мой вопрос ранее не задавался, возможно, из-за моей некомпетентности.

У меня есть готовое заявление, что я хотел бы обновить поле моего пароля в моей БД в зависимости от имени пользователя и адреса электронной почты, причина, по которой он обновляется, а не вставляется, потому что это часть моей безопасности - не одобрять фотографов сайта, пока они была отправлена ​​ссылка

<?php
if (isset($_POST['approved-photographer'])) {
    require 'dbh.php';

    $username  = $_POST['username'];
    $email     = $_POST['mail'];
    $password  = $_POST['password'];
    $password2 = $_POST['password-repeat'];

    if (empty($username) || empty($email) || empty($password) || 
        empty($password2)) 
    {
        header("location:signup.php?error=emptyfields&username=" . $username 
    . "&mail=.$email");
        exit();
     } elseif ($password !== $password2) {
        header("location:approvedphoto.php?error=passwordcheck&username=" . 
        $username . "&mail=" . $email);
        exit();
    } else {
        $sql = "SELECT Password 
                FROM photographers 
                WHERE Username= '$username' 
                AND Email= '$email'";

    $stmt = mysqli_stmt_init($conn);
    if (!mysqli_stmt_prepare($stmt, $sql)) {
        header("location:approvedphoto.php?error=sqlerror");
        exit();
    } else {
        $sql = "INSERT INTO photographers (Password) VALUES (?)";
        $stmt = mysqli_stmt_init($conn);
        if (!mysqli_stmt_prepare($stmt, $sql)) {
            header("location:approvedphoto.php?error=sqlerror2");
            exit();
        } else {
            $hashedpwd = password_hash($password, PASSWORD_DEFAULT);

            mysqli_stmt_bind_param($stmt, "s", $hashedpwd);
            mysqli_stmt_execute($stmt);
            header("location:signin.php?signup=success");
            exit();
        }
        }
        }
        }

Любая помощь будет принята с благодарностью. Спасибо за чтение

1 Ответ

0 голосов
/ 31 октября 2018

Короткий ответ для использования MySQLi: вы не связали параметры, что можно сделать с помощью mysqli_stmt_bind_param (Будущие читатели, это последнее утверждение теперь неактуально из-за правок). В целом, после редактирования ваши заявления sql кажутся неясными, вы обычно либо обновляете пароль (в этом случае вам нужно предложение WHERE, чтобы не обновлять пароль для всех), либо вам следует вставить новый пользователь с паролем.

Это более или менее тангенциальный ответ, но я хотел бы бросить свою шляпу в кольцо для использования PDO (вместо mysqli). MySQLi работает только с одной формой базы данных, MySQL. Кроме того, он позволяет гораздо менее объектно-ориентированное решение для взаимодействия БД. Вот пример того, как вы могли бы сделать это через PDO:

//specifies the driver, ip/database etc. Swap out for your ip and database used
$driverStr = 'mysql:host=<ip>;dbname=<database>;charset=utf8';
//you can set some default behaviors here for your use, I put some examples
//I left a link below so you can see the different options
$options = [
    //spew exceptions on errors, helpful to you if you have php errors enabled
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

//substite what you need for username/password here as well, $options can be omitted
$conn = new PDO($driverStr, '<username>', '<password>', $options);

Ссылка на вышеупомянутые атрибуты

Теперь, когда мы установили соединение:

//I used a "named parameter", e.g. :password, instead of an anonymous parameter
$stmt = $conn->prepare("UPDATE Photographers SET password = :password WHERE Username = :username");

//with our prepared statement, there's a few ways of executing it

//1) Using #bind*
//there's also #bindValue for not binding a variable reference
//for params, PARAM_STR is default and can be safely omitted
$stmt->bindParam(':password', $password, PDO::PARAM_STR);
$stmt->bindParam(':username', $username);
$stmt->execute();

//2) Using execute directly
$stmt->execute(['password' => $password, 'username' => $username]);

Тогда, если оператор был запросом, а не просто обновлением / вставкой базы данных, мы можем просто получить результаты оператора. Используя #bindParam, вы также можете просто обновить значения переменной и повторно выполнить оператор, если хотите, что может быть полезно для некоторых других операторов.

//see #fetch and #fetchAll's documentation for the returned data formatting
$results = $stmt->fetchAll(PDO::FETCH_OBJ); //return it as a php object
$results = $stmt->fetch(PDO::FETCH_NUM)[0]; //unsafely retrieve the first value as a number

На протяжении многих лет я обнаружил, что это намного чище и более управляемо, чем любой из mysqli_* или даже устаревших mysql_* методов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...