Elikkäs kun yritin hakea rivejä tietokannasta niin alkoi herjaamaan seuraavasta asiasta:
Fatal error: Call to a member function fetch() on a non-object on line 29
kurssin_tiedot.php tiedostosta otettu palanen:
<?php try{ // Luodaan uusi PDO-olio $kanta = new PDO("mysql:host=localhost;dbname=kurssitiedot;port=3306", "root", ""); $sql = "SELECT * FROM kurssit WHERE tunnus=" . $_GET['tunnus']; $lause = $kanta->query($sql); $rivi = $lause->fetch(PDO::FETCH_ASSOC); $kanta = null; } catch(PDOException $e) { print "Tietokantavirhe! : " . $e->getMessage() . "<br/>"; die(); } ?>
Mikähän tässä mahtaa olla vikana, kun olen tehnyt jo yhden samanlaisen ja se toimii mutta nyt tämä ei toimi?
tunnus on pääavain ja merkkimuuttuja (esim. LUD1002) mikäli sillä tiedolla on merkitystä
Sinun pitäisi kutsua tuon $kanta muuttujan kautta metodia PDO::prepare(), jolle annat tuon kyselyn parametriksi. Sitten Kutsut PDO::execute() metodia, jolle annata tuon $_GET muuttujan parametriksi.
<?php try{ // Luodaan uusi PDO-olio $kanta = new PDO("mysql:host=localhost;dbname=kurssitiedot;port=3306", "root", ""); $sql = $kanta->prepare("SELECT * FROM kurssit WHERE tunnus = ?"); $sql->execute(Array($_GET['tunnus'])); $rivi = $sql->fetch(PDO::FETCH_ASSOC); } catch(PDOException $e) { print "Tietokantavirhe! : " . $e->getMessage() . "<br/>"; die(); } ?>
Eli siis yritit käyttää metodia fetch() ilman oliota, jos kääntää tuon virheilmoituksen.
Kiitos Teuro! Pelastit päiväni. Mikäli ilmenee muita ongelmia tehdessäni tätä tietokantaa loppuun, ilmoitan luultavasti tähän perään.
Lisäys:
Kuten arvelin, en saanut tehtyä tietokantaani loppuun ilman ongelmia. Kurssin tietojen muokkaamisessa ja poistamisessa tuli ongelmia. Ne molemmat ei tee mitään, eli ei tee muutoksia tietokantaa tai poista rivejä tietokannasta, mutta ei heitä mitään herjaa.
Niihin varmastikin pitäisi hyökyntää noita antamiasi koodipätkiä, mutta kun olen tälläinen typerä amatööri, niin en tietenkään onnistunut edes siinä.
tallenna_muokkaus.php
<?php try{ // Luodaan uusi PDO-olio $kanta = new PDO("mysql:host=localhost;dbname=kurssitiedot;port=3306", "root", ""); // Päivitettävän kurssin tiedot lomakkeelta $paivitys_tunnus = $_POST['tunnus']; $muokattu_tunnus = $_POST['uusi_tunnus']; $muokattu_nimi = $_POST['uusi_nimi']; $muokattu_pituus = $_POST['uusi_pituus']; $muokattu_aloituspvm = $_POST['uusi_aloituspvm']; $muokattu_lopetuspvm = $_POST['uusi_lopetuspvm']; $muokattu_arvosana = $_POST['uusi_arvosana']; // Luodaan päivityslause $sql = "UPDATE kurssit SET tunnus = :eka, nimi = :toka, pituus = :kolmas, aloituspvm = :neljas, lopetuspvm = :viides, arvosana = :kuudes WHERE tunnus = $paivitys_tunnus" ; $lause = $kanta->prepare( $sql ); $lause->bindParam(":eka", $muokattu_tunnus); $lause->bindParam(":toka", $muokattu_nimi); $lause->bindParam(":kolmas", $muokattu_pituus); $lause->bindParam(":neljas", $muokattu_aloituspvm); $lause->bindParam(":viides", $muokattu_lopetuspvm); $lause->bindParam(":kuudes", $muokattu_arvosana); $lause->execute(); echo "Kurssin tiedot on muutettu!" . "<br/>"; echo "<br/>"; echo "<a href=index.php </a>Palaa etusivulle"; $kanta = null; } catch(PDOException $e) { print "Tietokantavirhe! : " . $e->getMessage() . "<br/>"; die(); } ?>
ja suorita_poisto.php
<?php try{ // Luodaan uusi PDO-olio $kanta = new PDO("mysql:host=localhost;dbname=kurssitiedot;port=3306", "root",""); // Poistettavan kurssin tiedot lomakkeelta // (Poistaminen tehdään tässä annetun tunnuksen mukaan) $id = $_GET['tunnus']; // Luodaan poistolause $sql = "DELETE FROM kurssit WHERE tunnus = $id"; $lause = $kanta->prepare( $sql ); $lause->execute(); echo "Kurssin tiedot on poistettu!" . "<br/>"; echo "<br/>"; echo "<a href=index.php </a>Palaa etusivulle"; } catch(PDOException $e) { print "Tietokantavirhe! : " . $e->getMessage() . "<br/>"; die(); } ?>
Tällaiseksi muunnettuna toimii tuo muokkaaminen muunna itse tuo poisto samanlaiseksi.
<?php try{ // Luodaan uusi PDO-olio $kanta = new PDO("mysql:host=localhost;dbname=kurssitiedot;port=3306", "root", ""); // Luodaan päivityslause $sql = "UPDATE kurssit SET tunnus = :uusi_tunnus, nimi = :nimi, pituus = :pituus, aloituspvm = :alpvm, lopetuspvm = :lopvm, arvosana = :asana WHERE tunnus = :tunnus"; $lause = $kanta->prepare($sql); $lause->bindParam(":uusi_tunnus", $_POST['uusi_tunnus']); $lause->bindParam(":nimi", $_POST['nimi']); $lause->bindParam(":pituus", $_POST['pituus']); $lause->bindParam(":alpvm", $_POST['aloituspvm']); $lause->bindParam(":lopvm", $_POST['lopetuspvm']); $lause->bindParam(":asana", $_POST['arvosana']); $lause->bindParam(":tunnus", $_POST['tunnus']); $lause->execute(); } catch(PDOException $e) { print "Tietokantavirhe! : " . $e->getMessage() . "<br/>"; die(); } ?>
Mietin vielä, että miksi ihmeessä laitat lopuksi null arvon tuolle yhteydelle? Sivun suoritus ja sitä myöten koko yhteyden olemassa olo loppuu muutenkin muutaman rivin päästä.
Lisäksi teit ihan turhaa työtä muuttamalla $_POST[...] muuttujat tavallisiksi muuttujiksi.
Noniin. Nyt sain noi molemmat toimimaan. Piti hieman muokata antamaasi koodia (vain tuo $_POST[] sisältö).
Toi arvo null tuolle yhteydelle jäi vahingossa roikkumaan ja tuo turha työ johtu siitä että minut opetettiin tekemään niin, en tiedä miksi.
Ja kiitokset vielä kerran avustasi.
Teuro kirjoitti:
Lisäksi teit ihan turhaa työtä muuttamalla $_POST[...] muuttujat tavallisiksi muuttujiksi.
Kyllähän niiden olemassaolo olisi hyvä tarkistaa ennen kuin niitä yrittää käyttää. Jos tuollaisia kämmejä tekee skriptissä, joka tuottaa esim. HTML-sivuja, niin koko sivu täyttyy noticeista. Silloin kun skripti vain kirjoittaa kantaan, niin on periaatteessa kätevämpää vain laittaa output bufferin päälle tai noticet pois käytöstä.
The Alchemist kirjoitti:
Teuro kirjoitti:
Lisäksi teit ihan turhaa työtä muuttamalla $_POST[...] muuttujat tavallisiksi muuttujiksi.
Kyllähän niiden olemassaolo olisi hyvä tarkistaa ennen kuin niitä yrittää käyttää.
Suora sijoittaminen tavalliseen muuttujaan ei kuitenkaan ole minkään sortin tarkistus vaan nimenomaan turhaa työtä. Tarkistaminen tehdään vaikka issetillä.
The Alchemist kirjoitti:
Silloin kun skripti vain kirjoittaa kantaan, niin on periaatteessa kätevämpää vain laittaa output bufferin päälle tai noticet pois käytöstä.
Kätevää ja kätevää. Kyllä minusta on paljon kätevämpää vain kirjoittaa se yksi isset-tarkistus ja ottaa sitten kiitollisena vastaan kaikki noticet, jotka vielä sen jälkeen ovat tallella.
Aihe on jo aika vanha, joten et voi enää vastata siihen.