Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: PHP ja MySQL tietokanta FATAL ERROR

JML [22.06.2011 12:52:29]

#

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ä

Teuro [22.06.2011 13:00:48]

#

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.

JML [22.06.2011 13:18:37]

#

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();
	}
?>

Teuro [22.06.2011 14:45:39]

#

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.

JML [23.06.2011 12:26:51]

#

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.

The Alchemist [23.06.2011 12:43:33]

#

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

Metabolix [23.06.2011 14:43:58]

#

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

if (!isset($_POST["juttu"], $_POST["toinen"], $_POST["kolmas"])) {
  // 400 Bad Request
  die();
}

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.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta