Beste allemaal,

Ik ben sinds een tijdje begonnen met het leren van PHP. Ik ben nu een tutorial aan het volgen om een simpel PHP/MySQL-forum te maken. Echter gebruikt deze tutorial nog de mysql* functies. Op zich geen probleem want ik heb al veel van deze functies omgezet naar de PDO-manier. Echter bij deze functie kom ik er niet uit:

             $sql = "SELECT 
                        user_id,
                        user_name,
                        user_level
                    FROM
                        users
                    WHERE
                        user_name = '" . mysql_real_escape_string($_POST['user_name']) . "'
                    AND
                        user_pass = '" . sha1($_POST['user_pass']) . "'";
                         
            $result = mysql_query($sql);
            if(!$result)
            {
                //something went wrong, display the error
                echo 'Something went wrong while signing in. Please try again later.';
                //echo mysql_error(); //debugging purposes, uncomment when needed
            }
            else
            {
                //the query was successfully executed, there are 2 possibilities
                //1. the query returned data, the user can be signed in
                //2. the query returned an empty result set, the credentials were wrong
                if(mysql_num_rows($result) == 0)
                {
                    echo 'You have supplied a wrong user/password combination. Please try again.';
                }
                else
                {
                    //set the $_SESSION['signed_in'] variable to TRUE
                    $_SESSION['signed_in'] = true;
                     
                    //we also put the user_id and user_name values in the $_SESSION, so we can use it at various pages
                    while($row = mysql_fetch_assoc($result))
                    {
                        $_SESSION['user_id']    = $row['user_id'];
                        $_SESSION['user_name']  = $row['user_name'];
                        $_SESSION['user_level'] = $row['user_level'];
                    }
                     
                    echo 'Welcome, ' . $_SESSION['user_name'] . '. <a href="index.php">Proceed to the forum overview</a>.';
                }
            } 


Dit was de oorspronkelijke code van de tutorial. Die heb ik zo aangepast:
 $sql = "SELECT 
                        user_id, 
                        user_name, 
                        user_level 
                    FROM 
                        users 
                    WHERE
                        user_name = '" . ($_POST['user_name']) . "'
                    AND
                        user_pass = '" . sha1($_POST['user_pass']) . "'";
            
            $stmt = $db->prepare($sql);
            $stmt->execute();
            
            if(!$stmt)
            {
                // Er is iets fout gegaan, laat de error zien
                echo 'Er is iets fout gegaan bij het registreren, probeer het later nog eens.';
            } 
            else
            {
                /* De query is succesvol uitgevoerd, nu zijn er twee mogelijkheden
                1. De query geeft data terug, de gebruiker kan inloggen
                2. De query geeft een lege set resultaten terug, de ingevoerde gegevens zijn fout
                */
                $rows = $stmt->fetchAll();
                $num_rows = count($rows);
                
                if($num_rows == 0)
                {
                    echo 'Je hebt een verkeerde gebruikersnaam/wachtwoord combinatie ingevuld. Probeer het opnieuw.';
                }
                else
                {
                    // Zet de $_SESSION['signed_in']- variabele op TRUE
                    $_SESSION['signed_in'] = true;
                    
                    // We plaatsen ook de user_id en user_name waarden in de $_SESSION, zodat we het kunnen gebruiken op verschillende pagina's
                    while($row = $stmt->fetch(PDO::FETCH_ASSOC))
                    {
                        $_SESSION['user_id']    = $row['user_id'];
                        $_SESSION['user_name']  = $row['user_name'];
                        $_SESSION['user_level'] = $row['user_level'];
                    }
                    
                    echo 'Welcome, ' . $_SESSION['user_name'] . '. <a href="index.php">Ga door naar het forumoverzicht!</a>.';
                }
            }           
        } 


Als een gebruiker inlogt, kan hij de gebruikersnaam niet weergeven. Het probleem speelt zich dus af in de while loop, maar ik kom er maar niet achter wat het probleem is. Hij kan op een of andere manier de query niet fetchen bij de while-loop, waardoor er geen betekenis aan de sessie-variabelen wordt gegeven en ik de gebruikersnaam niet kan teruggeven.

Iemand enig idee wat ik fout doe?

Alvast bedankt, Mike
Los van dit alles gebruik je PDO op dit moment op de verkeerde manier. Alle DATA die je in je query stopt zou via de placeholders in je prepared statement moeten verlopen, je plakt deze nu in de querystring (zonder deze zelfs te escapen, dus je bent wat dat betreft al nat). Hiermee omzeil je de hele methodiek die prepared statements "veilig" zouden moeten maken.

Inhoudelijk over je probleem: je hebt al een fetchAll uitgevoerd, en daarmee heb je alle resultaten al opgehaald, dit houdt waarschijnlijk in dat er verder niets meer op te halen valt. Waarom zou je trouwens een while gebruiken als je maar 1 resultaat verwacht?

Maar los daarvan, ga eerst terug naar de theorie van PDO en hoe je met prepared statements zou moeten omgaan.
Ohh, ik dacht dat die placeholders niet persé nodig waren.
Met PDO hoefde je strings toch niet meer te escapen, omdat je met prepare de server al de boel laat checken, of heb ik dat fout?

Dus als je al eens gefetcht hebt, kun je iets niet nog een keer fetchen?
Wat zou jij dan gebruiken i.p.v. die while?

Misschien domme vragen, maar ik ben er nog niet zo lang mee bezig.
In ieder geval bedankt haha, en ik ga me zeker nog eens even verder verdiepen in PDO.

Mvg, Mike
Ook zie ik meteen dat je in je query bij WHERE dat je 'user_pass' gebruikt, maar dan moet je deze ook selecteren bij de SELECT
Maarten, waarom zou dat moeten? Die heb ik nog niet eerder gehoord.
Daarnaast: ja, je moet gewoon escapen, tenzij je netjes prepared statements met placeholders gebruikt. De placeholders zorgen dan "magisch" voor je escaping. Je kunt inderdaad maar 1 keer een resultset fetchen. Je kan dus fetchAll gebruiken, en daar met foreach overheen gaan, bijvoorbeeld met iets als foreach ($rows as $row).
Dan zou dit je query moeten worden:

$sql = "SELECT 
                        user_id, 
                        user_name, 
                        user_pass,
                        user_level
                    FROM 
                        users 
                    WHERE
                        user_name = '" . mysql_real_escape_string($_POST['user_name']) . "'
                    AND
                        user_pass = '" . sha1($_POST['user_pass']) . "'";
Ik zou het dan wel beveiligen.
@- SanThe -: Done, wel op de manier van de topic starter
Bedankt voor de reacties, ik ben nu heel wat wijzer geworden.
Het script werkt nu in ieder geval gelukkig :).

@PHP-Maarten, waarom moet je de user_pass ook selecteren bij SELECT, want zonder werkt hij nu ook gewoon.

Ik heb nu dit:

            $sql = "SELECT 
                        user_id, 
                        user_name, 
                        user_level 
                    FROM 
                        users 
                    WHERE
                        user_name = :user_name
                    AND
                        user_pass = :user_pass";
            
            $stmt = $db->prepare($sql);
            
            $stmt->bindParam(':user_name', $user_name, PDO::PARAM_STR);   
            $stmt->bindParam(':user_pass', $user_pass, PDO::PARAM_STR); 
            
            $user_name = $_POST['user_name'];
            $user_pass = sha1($_POST['user_pass']);
            
            $stmt->execute();
            
            if(!$stmt)
            {
                // Er is iets fout gegaan, laat de error zien
                echo 'Er is iets fout gegaan bij het registreren, probeer het later nog eens.';
            } 
            else
            {
                /* De query is succesvol uitgevoerd, nu zijn er twee mogelijkheden
                1. De query geeft data terug, de gebruiker kan inloggen
                2. De query geeft een lege set resultaten terug, de ingevoerde gegevens zijn fout
                */
                $rows = $stmt->fetchAll();
                $num_rows = count($rows);
                
                if($num_rows == 0)
                {
                    echo 'Je hebt een verkeerde gebruikersnaam/wachtwoord combinatie ingevuld. Probeer het opnieuw.';
                }
                else
                {
                    // Zet de $_SESSION['signed_in']- variabele op TRUE
                    $_SESSION['signed_in'] = true;
                    
                    // We plaatsen ook de user_id en user_name waarden in de $_SESSION, zodat we het kunnen gebruiken op verschillende pagina's
                    foreach($rows as $row)
                    {
                        $_SESSION['user_id']    = $row['user_id'];
                        $_SESSION['user_name']  = $row['user_name'];
                        $_SESSION['user_level'] = $row['user_level'];
                    }
                    
                    echo 'Welcome, ' . $_SESSION['user_name'] . '. <a href="index.php">Ga door naar het forumoverzicht!</a>.' . $_SESSION['user_level'];
                }
            }           
        }
    }
} 


Mvg, Mike
Mike Kuiper op 27/02/2016 13:34:24

... waarom moet je de user_pass ook selecteren bij SELECT ...


Dat is ook eigenlijk overbodig.
Ooh. Ik dacht dat het verplicht was om dat veld te gebruiken, mijn fout..

Reageren