PDO-manier fetcht de query niet

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Mike Kuiper

Mike Kuiper

26/02/2016 16:00:58
Quote Anchor link
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:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
             $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:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
$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
Gewijzigd op 26/02/2016 16:01:53 door Mike Kuiper
 
PHP hulp

PHP hulp

18/01/2021 23:43:57
 
Thomas van den Heuvel

Thomas van den Heuvel

26/02/2016 16:20:42
Quote Anchor link
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.
Gewijzigd op 26/02/2016 16:21:49 door Thomas van den Heuvel
 
Mike Kuiper

Mike Kuiper

26/02/2016 18:02:31
Quote Anchor link
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
Gewijzigd op 26/02/2016 18:03:02 door Mike Kuiper
 
Marthijn Buijs

Marthijn Buijs

26/02/2016 20:43:58
Quote Anchor link
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
 
Ben van Velzen

Ben van Velzen

26/02/2016 22:18:06
Quote Anchor link
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).
Gewijzigd op 26/02/2016 22:46:22 door Ben van Velzen
 
Marthijn Buijs

Marthijn Buijs

27/02/2016 12:00:50
Quote Anchor link
Dan zou dit je query moeten worden:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
$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']) . "'";
Gewijzigd op 27/02/2016 13:06:55 door Marthijn Buijs
 
- SanThe -

- SanThe -

27/02/2016 12:04:38
Quote Anchor link
Ik zou het dan wel beveiligen.
 
Marthijn Buijs

Marthijn Buijs

27/02/2016 13:07:18
Quote Anchor link
@- SanThe -: Done, wel op de manier van de topic starter
 
Mike Kuiper

Mike Kuiper

27/02/2016 13:34:24
Quote Anchor link
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:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
            $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
Gewijzigd op 27/02/2016 13:34:52 door Mike Kuiper
 
- SanThe -

- SanThe -

27/02/2016 13:55:10
Quote Anchor link
Mike Kuiper op 27/02/2016 13:34:24:
... waarom moet je de user_pass ook selecteren bij SELECT ...


Dat is ook eigenlijk overbodig.
 
Marthijn Buijs

Marthijn Buijs

27/02/2016 14:22:18
Quote Anchor link
Ooh. Ik dacht dat het verplicht was om dat veld te gebruiken, mijn fout..
 
- SanThe -

- SanThe -

27/02/2016 14:34:00
Quote Anchor link
Nee, niets is verplicht.
Je wilt weten of de username en het password bestaan en in hetzelfde record zitten.
Meer eigenlijk niet.
Dus je kunt zelfs SELECT 1 gebruiken, dan krijg je 1 terug als het record bestaat.
 
Mike Kuiper

Mike Kuiper

29/02/2016 21:38:41
Quote Anchor link
Ik ben bijna klaar met mijn forum, maar ik heb nog een vraagje waar ik niet uit kom en om daar nu een hele nieuwe topic voor te openen vind ik overdreven.

In de tutorial van het maken van deze forum, willen ze door $_GET['id'] aan te roepen in de query, de topics weergeven in de categorie die de gebruiker op dat moment selecteert. Maar ze hebben nergens in de tutorial $_GET['id'] gedefinieerd. Nu weet ik dat je deze kunt maken door bijv: category.php?id=1 in de URL in te typen, want dan is $_GET['id'] = 1. Maar hoe kan ik er nu voor zorgen dat er automatisch 1,2,3 of 4 etc. achter category.php?id= gezet wordt, wanneer de gebruiker op een categorie klikt.

Want nu geeft hij alleen de categorieën weer als je inderdaad 1 achter ?id= typt in de URL, maar niet als je op een categorie klikt. Ik kom hier maar niet uit.

EDIT: Het is gefixt, de link op de pagina naar de categorie was eerst zo:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
       echo '<h3><a href="category.php?id=">'.$row['cat_name'].'</a></h3>'.$row['cat_description'];

Hier heb ik nu dit van gemaakt:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
             echo '<h3><a href="category.php?id='.$row['cat_id'].'">'.$row['cat_name'].'</a></h3>'.$row['cat_description'];


Eigenlijk heel stom, jammer dat de tutorial onvolledig is en er veel fouten in zitten zoals deze. Maar het is dus opgelost!
Gewijzigd op 29/02/2016 21:48:13 door Mike Kuiper
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.