Foutmelding in PDO script

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Sander J

Sander J

22/11/2019 11:45:47
Quote Anchor link
Hoi ik ben een beginnend php student en zit met een probleem (de leraar wilt me niet helpen omdat ik al veel verder ben als de klas dus kom ik hierheen)
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)
PHP script in nieuw venster Selecteer het PHP script
1
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!");


?>

php stukje waar de tabbelen moeten worden getoond uit de database:
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
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>

Het stukje wat niet echt uitmaakt maar misschien beter voor de context(het aanmeld stukje):
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
<!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"> &nbsp;&nbsp;&nbsp;&nbsp;Man<br>
  <input type="radio" name="geslacht" value="Vrouw"> &nbsp;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 -
 
PHP hulp

PHP hulp

29/03/2024 13:35:18
 
- Ariën  -
Beheerder

- Ariën -

22/11/2019 12:02:46
Quote Anchor link
Kan je jouw code tussen code tags plaatsen? Zie ook de Veelgestelde Vragen.

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 -
 
Sander J

Sander J

22/11/2019 12:10:13
Quote Anchor link
wat bedoel je precies tussen code tags plaatsen? error heb ik aangepast en bedankt voor de hulp nogmaals!
 
- Ariën  -
Beheerder

- Ariën -

22/11/2019 12:12:02
Quote Anchor link
Je script tussen code-tags plaatsen, zodat deze beter leesbaarder zijn. De opmaakcodes staan in de Veelgestelde Vragen.
Gewijzigd op 22/11/2019 12:14:19 door - Ariën -
 
Adoptive Solution

Adoptive Solution

22/11/2019 12:24:05
Quote Anchor link
Probeer het eens zonder spatie.

Dus $conn->close();
In plaats van $conn-> close();
 
Sander J

Sander J

22/11/2019 12:28:52
Quote Anchor link
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 :)
 
- Ariën  -
Beheerder

- Ariën -

22/11/2019 12:37:14
Quote Anchor link
Er bestaat geen close() functie in PDO. Je kan je $conn aan het eind voorzien van null
 
Sander J

Sander J

22/11/2019 12:38:09
Quote Anchor link
Je bedoeld dus $conn->null(); begrijp ik? als dat zo is geeft hij dezelfde error met ipv close null...
 
Adoptive Solution

Adoptive Solution

22/11/2019 12:45:56
Quote Anchor link
Als de meester niks wilt uitleggen, kan je als student altijd nog de handleiding raadplegen.

https://www.php.net/manual/en/pdo.connections.php
 
Thomas van den Heuvel

Thomas van den Heuvel

22/11/2019 14:12:23
Quote Anchor link
En misschien wil je dan ook meteen even het hoofdstuk over prepared statements raadplegen want dit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
$query
= "INSERT INTO info VALUES
('$naam', '$adres', '$email', '$woonplaats', '$postcode')"
;
?>

Is absoluut NIET de bedoeling van prepared statements.

En dit:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
<?php
#try catch is beter voeg dat later toe
?>

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
 
Ivo P

Ivo P

22/11/2019 14:19:07
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
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) {

?>


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.
 
Michael -

Michael -

22/11/2019 14:23:50
Quote Anchor link
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.
 
Sander J

Sander J

22/11/2019 14:36:38
Quote Anchor link
Dank voor alle reacties nogmaals ik heb hier over dit alles GEEN uitleg gehad en probeer het ZELF uit te vinden ik kom hier alleen voor hulp en snap niet waarom er door sommige hier zo agressief word op gereageerd ik ben hier om wat te leren anyway na een tijdje verder heb ik de 2 errors verholpen maar krijg ik deze error Notice: Undefined property: PDOStatement::$num_rows in C:\xampp\htdocs\phpsite\php\sitephpp.php on line 52
Ivo P dankje voor je reactie / hulp ik was er zelf indd ook achter gekomen dat ik een komma teveel erin had staan.
 
Michael -

Michael -

22/11/2019 15:09:04
Quote Anchor link
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.
Volgens mij bestaat num_rows ook niet in PDO. num_rows bestaat niet in PDO. Gebruik $result->rowCount()
Gewijzigd op 22/11/2019 15:11:03 door Michael -
 
Thomas van den Heuvel

Thomas van den Heuvel

22/11/2019 15:32:24
Quote Anchor link
@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 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):
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
<?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]

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".
 
Sander J

Sander J

22/11/2019 18:29:05
Quote Anchor link
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 :)
 
- Ariën  -
Beheerder

- Ariën -

22/11/2019 18:34:32
Quote Anchor link
Je moet altijd oplettend zijn met betrekking tot veiligheid, ongeacht welke drivers je gebruikt (PDO, MySQLi etc..). Ook als je bij PDO de foute stappen maakt, kan je ook een SQL-injection naar binnen laten sluipen. PDO is dan ook geen magisch 'iets' wat altijd veilig is.

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 -
 
Sander J

Sander J

22/11/2019 18:38:10
Quote Anchor link
Ja, ik heb geen idee maar het is een must het is niet alsof ik zelf de keuze heb jammer genoeg....
 
Thomas van den Heuvel

Thomas van den Heuvel

22/11/2019 20:06:08
Quote Anchor link
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:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
"INSERT INTO info VALUES
('$naam', '$adres', '$email', '$woonplaats', '$postcode')";

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
 



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.