Fehler beim updaten von werten in der Datenbank


Sullaysur

Mitglied
Hallo Forum, ich habe einen weiteren Fehler wo ich nicht weiter komme.
Ich habe ein "Formular" wo der eingellogte Benutzer Profil anpassungen durchführen kann.

Nun gibt es dabei 2 Probleme.
1. Ich möchte nicht jedesmal alles Updaten sondern nur geänderte Werte.
2. Funktioniert etwas beim Updaten der Werte nicht, aber ich finde den Fehler nicht, ich vermute es liegt beim letzten $sql = "Update...
Auf jedenfall habe ich euch hier mal den Code mit beigepackt:
PHP:
<?php
session_start();
if(isset($_POST['settings-submit'])){

    require 'dbh.inc.php';

    $username = $_POST['uid'];
    $email = $_POST['mail'];
    $password = $_POST['pwd'];
    $confirmpassword = $_POST['cpwd'];

    if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        header("Location: ../settings.php?error=invalidmail");
        exit();
    }
    else if(!preg_match("/^[\w\- ]*$/", $username)) {
        header("Location: ../settings.php?error=invalidusername");
        exit();
    }
    else if($password !== $confirmpassword){
        header("Location: ../settings.php?error=passwordcheck");
        exit();
    }
    else {

        $sql = "SELECT * FROM users WHERE id='" . $_SESSION['id'] . "'";
        $stmt = mysqli_stmt_init($conn);
        if(!mysqli_stmt_prepare($stmt, $sql)){
            header("Location: ../settings.php?error=sqlerror1");
            exit();
        }
        else {
            mysqli_stmt_bind_param($stmt, "s", $username);
            mysqli_stmt_execute($stmt);
            mysqli_stmt_store_result($stmt);
            $resultCheck = mysqli_stmt_num_rows($stmt);
            if($resultCheck > 0){
                header("Location: ../settings.php?error=usertaken");
                exit();
            }
            else {
                $sql = "UPDATE users SET (uid, email, pwd) VALUES (?, ?, ?) WHERE id='" . $_SESSION['id'] . "'";
                $stmt = mysqli_stmt_init($conn);
                if(!mysqli_stmt_prepare($stmt, $sql)){
                    header("Location: ../settings.php?error=sqlerror2");
                    exit();
                }
                else {
                    $hashedPwd = password_hash($password, PASSWORD_DEFAULT);

                    mysqli_stmt_bind_param($stmt, "sss", $username, $email, $hashedPwd);
                    mysqli_stmt_execute($stmt);
                    header("Location: logout.inc.php?settings=success");
                    exit();
                }

            }
        }

    }
    mysqli_stmt_close($stmt);
    mysqli_close($conn);
}
else {
    header("Location: ../settings.php");
    exit();
}
Ich freue mich wie immer über schnelle und freundliche Hilfe.
 

Sullaysur

Mitglied
Hat noch jemand eine idee oder einen Tipp für mich?
Kann ich noch was abändern oder kann ich noch was verbessern?
Und wo liegt der Fehler, suche jetzt seid 3Tagen danach.
 

Yaslaw

n/a
Moderator
2. Funktioniert etwas beim Updaten der Werte nicht, aber ich finde den Fehler nicht, ich vermute es liegt beim letzten $sql = "Update...
.
Etwas funktioniert nicht. Es steht jemand auf der Leitung?
Im Ernst. Hast du eine Fehlermeldung? Oder wie ist das Fehlverhalten?
Ist die uid wirklich der username?
Warum behandelst du im SQL die id als String? IDs sollten Zahlen sein.
Warum setzt du die id nicht auch mit bind-param?
 

Sullaysur

Mitglied
Ja ich erhalte ?error=usertaken zurück.
Ja die uid ist der Username, in der Datenbank heißt der Username uid und bei der SESSION ist er als userUID eingetragen.
Den fehler mit der id als String ist mir schon selber aufgefallen und den habe ich schon behoben.
Weil ich dafür dass ich es gemacht habe von Personen aus einen anderen Forum kritisiert wurde.
 

Yaslaw

n/a
Moderator
Dann liegt es nicht am Update. Der kommt ja erst nach dem usertaken.
Deine Logik hat einen Hacken drin, if($resultCheck > 0){ prüft ob ein user zu der id vorhanden ist.
Wenn ja: Ausstieg mit ?error=usertaken
Wenn nicht: Update des nicht vorhandenen Datensatzes

Ich würde mal auf if($resultCheck == 0){ prüfen.
 

Sullaysur

Mitglied
Dann liegt es nicht am Update. Der kommt ja erst nach dem usertaken.
Deine Logik hat einen Hacken drin, if($resultCheck > 0){ prüft ob ein user zu der id vorhanden ist.
Wenn ja: Ausstieg mit ?error=usertaken
Wenn nicht: Update des nicht vorhandenen Datensatzes

Ich würde mal auf if($resultCheck == 0){ prüfen.
Habe es auf == 0 gesetzt, jetzt erhalte ich den error=sqlerror2
Ich bin mir halt nicht sicher ob man Set Values Machen kann.
 

Yaslaw

n/a
Moderator
Jetzt kommt er immerhin zum update.
Aber der Update scheint falsch zu sein. Normalerweise ordnet man direkt zu
PHP:
$sql = "UPDATE users SET uid=?, email=?, pwd=? WHERE id= ?;"
...
mysqli_stmt_bind_param($stmt, "sssi", $username, $email, $hashedPwd, $_SESSION['id']);
 

Yaslaw

n/a
Moderator
Noch was.
Du solltest die Fehler von mysqli ausgeben. Die sagen mehr als nur "hier ist was faul"
PHP:
printf("Error: %s.\n", mysqli_stmt_error($stmt));
 

Sullaysur

Mitglied
Noch was.
Du solltest die Fehler von mysqli ausgeben. Die sagen mehr als nur "hier ist was faul"
PHP:
printf("Error: %s.\n", mysqli_stmt_error($stmt));
Die oben genannten änderungen habe ich auch durchgeführt, jetzt läuft er zwar durch, ändert die Werte aber nicht.
Danke für den hinweis, gibt mir einen Fehler zurück:
Warning[/B]: mysqli_stmt_bind_param(): Number of variables doesn't match number of parameters in prepared statement in [B]G:\Sullaysur\Documents\xampp\htdocs\website\dashboard\includes\settings.inc.php[/B] on line [B]34[/B]
 

Sullaysur

Mitglied
Ja der Code sieht jetzt wie folgt aus:
PHP:
<?php
session_start();
if(isset($_POST['settings-submit'])){

    require 'dbh.inc.php';

    $username = htmlspecialchars($_POST['uid'], ENT_QUOTES, "UTF-8");
    $email = htmlspecialchars($_POST['mail'], ENT_QUOTES, "UTF-8");
    $password = htmlspecialchars($_POST['pwd'], ENT_QUOTES, "UTF-8");
    $confirmpassword = htmlspecialchars($_POST['cpwd'], ENT_QUOTES, "UTF-8");
    $id = htmlspecialchars($_SESSION['userId'], ENT_QUOTES, "UTF-8");

    if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
        header("Location: ../settings.php?error=invalidmail");
        exit();
    }
    else if(!preg_match("/^[\w\- ]*$/", $username)) {
        header("Location: ../settings.php?error=invalidusername");
        exit();
    }
    else if($password !== $confirmpassword){
        header("Location: ../settings.php?error=passwordcheck");
        exit();
    }
    else {

        $sql = "SELECT * FROM users WHERE id='" . $id . "'";
        $stmt = mysqli_stmt_init($conn);
        if(!mysqli_stmt_prepare($stmt, $sql)){
            header("Location: ../settings.php?error=sqlerror1");
            exit();
        }
        else {
            mysqli_stmt_bind_param($stmt, "s", $username);
            mysqli_stmt_execute($stmt);
            mysqli_stmt_store_result($stmt);
            $resultCheck = mysqli_stmt_num_rows($stmt);
            if($resultCheck == 0){
                header("Location: ../settings.php?error=usertaken");
                exit();
            }
            else {
                $sql = "UPDATE users SET uid=?, email=?, pwd=? WHERE id= ?;";
                $stmt = mysqli_stmt_init($conn);
                if(!mysqli_stmt_prepare($stmt, $sql)){
                    header("Location: ../settings.php?error=sqlerror2");
                    exit();
                }
                else {
                    $hashedPwd = password_hash($password, PASSWORD_DEFAULT);

                    mysqli_stmt_bind_param($stmt, "sssi", $username, $email, $hashedPwd, $_SESSION['id']);
                    mysqli_stmt_execute($stmt);
                    printf("Error: %s.\n", mysqli_stmt_error($stmt));
                    header("Location: logout.inc.php?settings=success");
                    exit();
                }

            }
        }

    }
    mysqli_stmt_close($stmt);
    mysqli_close($conn);
}
else {
    header("Location: ../settings.php");
    exit();
}
Sollte so eigentlich richtig sein.
 

Yaslaw

n/a
Moderator
Ich seh den Fehler auch nicht. Das mit der Zuweisung solltge mMn funktionieren. Bin aber nicht siher, da ich immer mit PDO und nicht mit mysqli arbeite
 

Yaslaw

n/a
Moderator
Grundsätzlich währe es eine Umstellung auf Objekte.. Dann kann man mit benamsten Platzhaltern arbeiten
Beispiel aus der PHP-Doku. Man sieht wie die Platzhalter mit :name drin sind.
PHP:
<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE calories < :calories AND colour = :colour');
$sth->bindParam(':calories', $calories, PDO::PARAM_INT);
$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);
$sth->execute();
?>
Aber eigentlich müsste es mit mysqli auch funktionieren
 

Sullaysur

Mitglied
Das ganzte mit dem pdo hört sich zwar interessant an, möchte ich mir aber gerade nicht unbedingt antun.
Das mit dem Fehler aus geben habe ich jetzt auch noch so geändert, nehme diese sachen aber eigentlich raus.

Die Frage ist halt nur was hier dran falsch ist?
PHP:
mysqli_stmt_bind_param($stmt, "s", $username); //Zeile 34
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$resultCheck = mysqli_stmt_num_rows($stmt);
if($resultCheck == 0){
    header("Location: ../settings.php?error=usertaken");
    exit();
}
Das war ja der Fehlermysqli_stmt_bind_param(): Number of variables doesn't match number of parameters in prepared statement in settings.inc.php on line 34
 

ComFreek

Mod | @comfreek
Moderator
Übrigens ist es falsch, Werte vor Einpflegen in eine Datenbank durch htmlspecialchars zu schicken. Warum machst du das?
 

Neue Beiträge