PDO-manier fetcht de query niet
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)
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
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>.';
}
}
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)
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
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>.';
}
}
}
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
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
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
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
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
Code (php)
1
2
3
4
5
6
7
8
9
10
11
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']) . "'";
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
Ik zou het dan wel beveiligen.
@- SanThe -: Done, wel op de manier van de topic starter
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)
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
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'];
}
}
}
}
}
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
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..
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.
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)
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)
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