Foutmelding in PDO script
ik krijg deze error: Notice: Trying to get property of non-object in C:\xampp\htdocs\phpsite\php\sitephpp.php on line 52
0 results
Fatal error: Uncaught Error: Call to undefined method PDO::close() in C:\xampp\htdocs\phpsite\php\sitephpp.php:66 Stack trace: #0 {main} thrown in C:\xampp\htdocs\phpsite\php\sitephpp.php on line 66
En dit is me code tot nu toe
Database:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
<?php
$host = "localhost";
$dbnaam = "phpcursus";
$gebruiker = "root";
$wachtwoord = "";
#try catch is beter voeg dat later toe
$conn = new PDO("mysql:host=$host;dbname=$dbnaam;",
$gebruiker, $wachtwoord) or die ("Verbinding mislukt!");
?>
$host = "localhost";
$dbnaam = "phpcursus";
$gebruiker = "root";
$wachtwoord = "";
#try catch is beter voeg dat later toe
$conn = new PDO("mysql:host=$host;dbname=$dbnaam;",
$gebruiker, $wachtwoord) or die ("Verbinding mislukt!");
?>
php stukje waar de tabbelen moeten worden getoond uit de database:
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
59
60
61
62
63
64
65
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
59
60
61
62
63
64
65
<?php
include("database.php");
if(isset($_POST['verzenden'])) {
$naam = $_POST['naam'];
$adres = $_POST['adres'];
$email = $_POST['email'];
$woonplaats = $_POST['woonplaats'];
$postcode = $_POST['postcode'];
$query = "INSERT INTO info VALUES
('$naam', '$adres', '$email', '$woonplaats', '$postcode')";
#query inelezen om hem om te zetten naar een statement
#die de database begrijpt
$stm = $conn->prepare($query);
#statement uitvoeren op de database
$stm->execute();
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Fetch data van database</title>
</head>
<body>
<table>
<tr>
<th>Naam</th>
<th>Adres</th>
<th>Email</th>
<th>Woonplaats</th>
<th>Postcode</th>
</tr>
</table>
<?php
include("database.php");
$sql = "SELECT, naam, adres, email, woonplaats, postcode from info";
$result = $conn-> query($sql);
if ($result-> num_rows > 0) {
while ($row = $result-> fetch_assoc()) {
echo "<tr><td>" . $row ["naam"] . "</td><td>" . $row ["adres"] . "</td><td>" . $row ["email"] . "</td><td>" . $row ["woonplaats"] . "</td><td>" .
$row ["postcode"] . "</td><td>";
}
echo "</table>";
}
else{
echo "0 results";
}
$conn-> close();
?>
</body>
</html>
include("database.php");
if(isset($_POST['verzenden'])) {
$naam = $_POST['naam'];
$adres = $_POST['adres'];
$email = $_POST['email'];
$woonplaats = $_POST['woonplaats'];
$postcode = $_POST['postcode'];
$query = "INSERT INTO info VALUES
('$naam', '$adres', '$email', '$woonplaats', '$postcode')";
#query inelezen om hem om te zetten naar een statement
#die de database begrijpt
$stm = $conn->prepare($query);
#statement uitvoeren op de database
$stm->execute();
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Fetch data van database</title>
</head>
<body>
<table>
<tr>
<th>Naam</th>
<th>Adres</th>
<th>Email</th>
<th>Woonplaats</th>
<th>Postcode</th>
</tr>
</table>
<?php
include("database.php");
$sql = "SELECT, naam, adres, email, woonplaats, postcode from info";
$result = $conn-> query($sql);
if ($result-> num_rows > 0) {
while ($row = $result-> fetch_assoc()) {
echo "<tr><td>" . $row ["naam"] . "</td><td>" . $row ["adres"] . "</td><td>" . $row ["email"] . "</td><td>" . $row ["woonplaats"] . "</td><td>" .
$row ["postcode"] . "</td><td>";
}
echo "</table>";
}
else{
echo "0 results";
}
$conn-> close();
?>
</body>
</html>
Het stukje wat niet echt uitmaakt maar misschien beter voor de context(het aanmeld stukje):
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
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
<!DOCTYPE html>
<html>
<link rel="stylesheet" type="text/css" href="phpcss.css">
<head>
<title>Site php</title>
</head>
<h1>Webshope workshop!</h1>
<br>
<div class="container">
<form action="Sitephp.php" method="post">
<input type="radio" name="geslacht" value="Man"> Man<br>
<input type="radio" name="geslacht" value="Vrouw"> Vrouw<br>
<input type="radio" name="geslacht" value="Anders"> Anders
<br>
<br>
</form>
<form class="contact" action="sitephpp.php" method="POST">
Voor en achternaam:<br>
<input type="text" name="naam" placeholder="Voornaam en achternaam"><br>
<br>
Adres:<br>
<input type="text" name="adres" placeholder="Adres"><br>
<br>
Email / telefoon(contact):<br>
<input type="text" name="email" placeholder="Email"><br>
<br>
Woonplaats:<br>
<input type="text" name="woonplaats" placeholder="Woonplaats"><br>
<br>
Postcode:<br>
<input type="text" name="postcode" placeholder="Postcode"><br>
<br>
<form action="sitephpp.php" method="POST">
<input type="radio" name="Datum1" value="datum1">Ik kan Disndag 12 febuari 09:00 - 13:30<br>
<input type="radio" name="Datum2" value="datum2">Ik kan woensdag 13 feb 13-17:30<br>
<br>
<button name= "verzenden" type="submit" class="button">Verzenden</button>
</form>
</form>
</div>
<html>
<link rel="stylesheet" type="text/css" href="phpcss.css">
<head>
<title>Site php</title>
</head>
<h1>Webshope workshop!</h1>
<br>
<div class="container">
<form action="Sitephp.php" method="post">
<input type="radio" name="geslacht" value="Man"> Man<br>
<input type="radio" name="geslacht" value="Vrouw"> Vrouw<br>
<input type="radio" name="geslacht" value="Anders"> Anders
<br>
<br>
</form>
<form class="contact" action="sitephpp.php" method="POST">
Voor en achternaam:<br>
<input type="text" name="naam" placeholder="Voornaam en achternaam"><br>
<br>
Adres:<br>
<input type="text" name="adres" placeholder="Adres"><br>
<br>
Email / telefoon(contact):<br>
<input type="text" name="email" placeholder="Email"><br>
<br>
Woonplaats:<br>
<input type="text" name="woonplaats" placeholder="Woonplaats"><br>
<br>
Postcode:<br>
<input type="text" name="postcode" placeholder="Postcode"><br>
<br>
<form action="sitephpp.php" method="POST">
<input type="radio" name="Datum1" value="datum1">Ik kan Disndag 12 febuari 09:00 - 13:30<br>
<input type="radio" name="Datum2" value="datum2">Ik kan woensdag 13 feb 13-17:30<br>
<br>
<button name= "verzenden" type="submit" class="button">Verzenden</button>
</form>
</form>
</div>
alle hulp is welkom bedankt alvast!
Gewijzigd op 22/11/2019 12:34:38 door - Ariën -
En kan je hier ook de error delen voordat de afbeelding straks misschien niet meer bestaat?
Voor de rest heb ik de topictitel van dit topic aangepast in wat duidelijkers. Dat iemand 'hulp nodig heeft' is geen titel waard.
Gewijzigd op 22/11/2019 12:06:39 door - Ariën -
wat bedoel je precies tussen code tags plaatsen? error heb ik aangepast en bedankt voor de hulp nogmaals!
Veelgestelde Vragen.
Je script tussen code-tags plaatsen, zodat deze beter leesbaarder zijn. De opmaakcodes staan in de Gewijzigd op 22/11/2019 12:14:19 door - Ariën -
Dus $conn->close();
In plaats van $conn-> close();
Nee, heeft geen verschil ik denk zelf dat het temaken heeft met die eerdere error en ik heb dus geen idee waarom die die geeft.... anyways bedankt voor alle hulp :)
Er bestaat geen close() functie in PDO. Je kan je $conn aan het eind voorzien van null
Je bedoeld dus $conn->null(); begrijp ik? als dat zo is geeft hij dezelfde error met ipv close null...
Code (php)
1
2
3
4
2
3
4
<?php
$query = "INSERT INTO info VALUES
('$naam', '$adres', '$email', '$woonplaats', '$postcode')";
?>
$query = "INSERT INTO info VALUES
('$naam', '$adres', '$email', '$woonplaats', '$postcode')";
?>
Is absoluut NIET de bedoeling van prepared statements.
En dit:
Sterker nog, dit is verplicht, omdat wanneer de connectie om wat voor reden dan ook faalt, er een PDOException wordt gegenereerd. Een niet gevangen Exception levert je altijd een Fatal Error op. En laat de boodschap in de exception voor het mislukken van de connectie nu de connectie-credentials bevatten... in het meest ongelukkige geval wordt deze boodschap naar het scherm gedumpt waarmee effectief/potentieel gevoelige/geheime gegevens op straat liggen.
Maar wel doen dus...
Dit is net zoals security niet iets wat je er later nog even bijmetselt. Het try-catch stramien hoort nu eenmaal bij PDO.
Je bent dus niet zoveel verder als de klas als jij denkt :p.
NB: ik zou wat meer nadruk leggen op het leren lezen van foutmeldingen en leren om code te debuggen. Stel dat eens voor aan je docent, want volgens mij gebeurt daar echt helemaal niets mee. Tegenwoordig niet, en vroegah waarschijnlijk ook niet.
Als je deze krijgt:
Quote:
Notice: Trying to get property of non-object
Grote kans dat het ding dat jij als object wilt gebruiken geen object is, maar false ofzo (heb je de variabele al eens naar het scherm gedumpt met var_dump() ofzo?). Dit wil zeggen dat het creëren van het object was mislukt omdat er iets (anders) fout was.
En deze is bijna zelfverklarend:
Quote:
Fatal error: Uncaught Error: Call to undefined method PDO::close()
De methode "close" bestaat niet.
Begin ook altijd met de éérste foutmelding, want vaak is de rest een GEVOLG van de eerste fout, los die eerst op, en kijk dan of de rest nog speelt...
Gewijzigd op 22/11/2019 14:23:25 door Thomas van den Heuvel
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
<?php
$sql = "SELECT, naam, adres, email, woonplaats, postcode from info";
$result = $conn-> query($sql);
if ($result-> num_rows > 0) {
?>
$sql = "SELECT, naam, adres, email, woonplaats, postcode from info";
$result = $conn-> query($sql);
if ($result-> num_rows > 0) {
?>
Je foutmelding "Trying to get property of non-object in C:\xampp\htdocs\phpsite\php\sitephpp.php on line 52" gaat over $result->num_rows.
$result is dus geen object.
Niet zo vreemd, als je naar de query kijkt die een komma te veel bevat en dus niet uitgevoerd zal kunnen worden.
Quote:
Sterker nog, dit is verplicht, omdat wanneer de connectie om wat voor reden dan ook faalt, er een PDOException wordt gegenereerd.
Klopt dat wel? En is dat niet afhankelijk van de settings?
Je kunt kiezen voor setAttribute(PDO::ERRMODE_EXCEPTION); zodat je exceptions kunt afvangen, maar je kunt ook kiezen voor PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT, PDO::ERRMODE_WARNING
Volgens mij is het niet altijd standaard dat je exceptions krijgt.
Ivo P dankje voor je reactie / hulp ik was er zelf indd ook achter gekomen dat ik een komma teveel erin had staan.
Quote:
snap niet waarom er door sommige hier zo agressief word op gereageerd
Er wordt helemaal niet agressief gereageerd hoor.
Quote:
Notice: Undefined property: PDOStatement::$num_rows in C:\xampp\htdocs\phpsite\php\sitephpp.php on line 52
Dit is een notice en geen error. En er staat dat je $num_rows aanroept, maar deze niet bestaat.
Gewijzigd op 22/11/2019 15:11:03 door Michael -
documentatie (zie de Note).
@SanderJ dat is prima (zelf dingen uitzoeken), maar realiseer je het volgende goed: PDO zelf is redelijk simpel, dit zijn een handjevol classes. Het "venijn" zit em in de staart.
PDO is niet op voorhand geconfigureerd voor gebruikmaking van een specifieke database, dit doen de database-specifieke drivers. Zo is er ook een driver voor MySQL.
PDO zelf en het MySQL-specifieke deel hebben een groot aantal configuratie-variabelen in de vorm van constanten, waarvan er bepaalde cruciaal zijn voor "normaal" gebruik. Je doet er dan ook verstandig aan om deze altijd expliciet in te stellen zodat je verzekerd bent van "normaal" database-gedrag en dat er geen onverwachte dingen gebeuren.
Een minimale opzet zou de volgende zijn:
- vermelding van een character encoding bij het maken van de connectie, deze kun je in de DSN opnemen met behulp van charset=<de charset>;
- expliciet instellen van de errormodus; omdat je toch al van exceptions gebruik maakte en dit een OOP-ding is is dit een logische keuze;
- expliciet instellen van het emuleren van prepared statements; hierbij moet je goed begrijpen wat dit inhoudt; sommige databases zoals MySQL hebben native ondersteuning voor prepared statements; PDO heeft zelf ook een prepapred statement laag die je query zelf in elkaar metselt voordat deze daadwerkelijk naar de database wordt gestuurd; deze instelling heeft een hele grote impact op de manier waarop je met de database communiceert;
- het gebruik van gebufferde queries; ook dit ontgaat men waarschijnlijk totaal omdat je hier "normaal" (denk aan mysqli) nooit tegenaan loopt; maar dit kan weer consequenties hebben voor functies als num_rows() die geen resultaten opleveren et cetera.
Een minimale opzet (voor ontwikkeling) zou er dus bijvoorbeeld als volgt kunnen uitzien (aanname: database, user en password gelijk aan "test", database toegankelijk via "127.0.0.1" en niet via "localhost", dat scheelt je weer een lookup):
Je zou je docent ook eens aan de tand kunnen voelen over de argumentatie voor gebruikmaking van PDO, als MySQL de enige (?) database is die je gebruikt. Dan is mysqli waarschijnlijk een veel betere keuze omdat je hier niets voor hoeft te configureren en al direct geoptimaliseerd is voor MySQL. Dit in tegenstelling tot PDO.
PDO heeft héél veel haken en ogen die niet zo direct zichtbaar zijn.
En ja, nogmaals, alle vragen die hier tot nu toe voorbij zijn gekomen zijn meer "debugging" problemen en interpretatie van foutmeldingen, en hebben eigenlijk helemaal niet zoveel te maken met PDO. Dit, net zoals vele andere vraagstukken op dit forum, vallen onder de categorie "het probleem is niet het probleem, maar de aanpak ervan".
@Michael ja, het maken van de connectie levert je altijd een Exception op als er iets misgaat, los van de instelling van PDO::ATTR_ERRMODE. Daarom is het zaak dat deze altijd in een try-catch blok staat. Dit staat in de @SanderJ dat is prima (zelf dingen uitzoeken), maar realiseer je het volgende goed: PDO zelf is redelijk simpel, dit zijn een handjevol classes. Het "venijn" zit em in de staart.
PDO is niet op voorhand geconfigureerd voor gebruikmaking van een specifieke database, dit doen de database-specifieke drivers. Zo is er ook een driver voor MySQL.
PDO zelf en het MySQL-specifieke deel hebben een groot aantal configuratie-variabelen in de vorm van constanten, waarvan er bepaalde cruciaal zijn voor "normaal" gebruik. Je doet er dan ook verstandig aan om deze altijd expliciet in te stellen zodat je verzekerd bent van "normaal" database-gedrag en dat er geen onverwachte dingen gebeuren.
Een minimale opzet zou de volgende zijn:
- vermelding van een character encoding bij het maken van de connectie, deze kun je in de DSN opnemen met behulp van charset=<de charset>;
- expliciet instellen van de errormodus; omdat je toch al van exceptions gebruik maakte en dit een OOP-ding is is dit een logische keuze;
- expliciet instellen van het emuleren van prepared statements; hierbij moet je goed begrijpen wat dit inhoudt; sommige databases zoals MySQL hebben native ondersteuning voor prepared statements; PDO heeft zelf ook een prepapred statement laag die je query zelf in elkaar metselt voordat deze daadwerkelijk naar de database wordt gestuurd; deze instelling heeft een hele grote impact op de manier waarop je met de database communiceert;
- het gebruik van gebufferde queries; ook dit ontgaat men waarschijnlijk totaal omdat je hier "normaal" (denk aan mysqli) nooit tegenaan loopt; maar dit kan weer consequenties hebben voor functies als num_rows() die geen resultaten opleveren et cetera.
Een minimale opzet (voor ontwikkeling) zou er dus bijvoorbeeld als volgt kunnen uitzien (aanname: database, user en password gelijk aan "test", database toegankelijk via "127.0.0.1" en niet via "localhost", dat scheelt je weer een lookup):
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
// https://www.phphulp.nl/php/forum/topic/foutmelding-in-pdo-script-/103197
header('Content-Type: text/html; charset=UTF-8'); // force UTF-8 content
// debugging
error_reporting(E_ALL);
ini_set('display_startup_errors', true);
ini_set('display_errors', 'stdout');
try {
$dsn = 'mysql:host=127.0.0.1;dbname=test;charset=utf8';
$db = new PDO($dsn, 'test', 'test', array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => true,
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
));
// code here
} catch (Exception $e) {
echo $e->getMessage().'<br>';
echo nl2br($e->getTraceAsString());
}
?>[end]
// https://www.phphulp.nl/php/forum/topic/foutmelding-in-pdo-script-/103197
header('Content-Type: text/html; charset=UTF-8'); // force UTF-8 content
// debugging
error_reporting(E_ALL);
ini_set('display_startup_errors', true);
ini_set('display_errors', 'stdout');
try {
$dsn = 'mysql:host=127.0.0.1;dbname=test;charset=utf8';
$db = new PDO($dsn, 'test', 'test', array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => true,
PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true,
));
// code here
} catch (Exception $e) {
echo $e->getMessage().'<br>';
echo nl2br($e->getTraceAsString());
}
?>[end]
Je zou je docent ook eens aan de tand kunnen voelen over de argumentatie voor gebruikmaking van PDO, als MySQL de enige (?) database is die je gebruikt. Dan is mysqli waarschijnlijk een veel betere keuze omdat je hier niets voor hoeft te configureren en al direct geoptimaliseerd is voor MySQL. Dit in tegenstelling tot PDO.
PDO heeft héél veel haken en ogen die niet zo direct zichtbaar zijn.
En ja, nogmaals, alle vragen die hier tot nu toe voorbij zijn gekomen zijn meer "debugging" problemen en interpretatie van foutmeldingen, en hebben eigenlijk helemaal niet zoveel te maken met PDO. Dit, net zoals vele andere vraagstukken op dit forum, vallen onder de categorie "het probleem is niet het probleem, maar de aanpak ervan".
Dank voor de vele reacties waarom we pdo moeten gebruiken heeft temaken met sql injections "veiligheid" ik ben iets verder gekomen denk ik (hij geeft nu alleen arrays aan en dat ik een array moet converten naar een string) in ieder geval bedankt voor alle hulp en reacties <3 het heeft me veel geholpen :)
Ikzelf prefereer MySQLi met fatsoenlijke escaping op al je invoer in je query (op gehashte passworden na, die wil je niet verminken met escaping). En het is makkelijker te configureren, en simpeler om mee te werken. Als je maar goed oplet wat je doet, en consistent bent met alles veilig te houden (en doe dit niet later).
Gewijzigd op 22/11/2019 18:36:06 door - Ariën -
Ja, ik heb geen idee maar het is een must het is niet alsof ik zelf de keuze heb jammer genoeg....
Sander J op 22/11/2019 18:29:05:
heeft temaken met sql injections "veiligheid"
PDO is "veiliger" omdat je daarin normaal gesproken gebruik maakt van, of liever gezegd gedwongen wordt om prepared statements (van PDO) te gebruiken. Maar dan moet je dus wel de spelregels van prepared statements volgen. Dit houdt in dat je nooit rechtstreeks waarden invoegt in een SQL(/prepared) statement, maar deze altijd op een indirecte manier aan de query (het prepared statement) voert.
Maar als je dus zoiets doet:
Dan overtreed je deze regels omdat je hier rechtstreeks variabelen in SQL-code invoegt.
Je zou deze (waarden van) variabelen ofwel via een van de bind-methoden aan je prepared statement moeten koppelen, ofwel als argument mee moeten geven aan een aanroep van de execute() methode van zo'n statement.
Sander J op 22/11/2019 18:38:10:
het is een must het is niet alsof ik zelf de keuze heb jammer genoeg...
Okay, dat is een gegeven dan, maar dan is het nog interessant om de redenen te weten en te kennen om voor PDO te kiezen. Vaak wordt bijvoorbeeld als argument genoemd dat "PDO veel meer databases ondersteunt", maar het is echt grote onzin om dat als argument te gebruiken (om een aantal redenen).
Het maakt niet eens zoveel uit wat je gebruikt, zolang je hier maar goede argumenten voor hebt die je jezelf en anderen uit kunt leggen.
Gewijzigd op 22/11/2019 20:07:05 door Thomas van den Heuvel