Kirjoittaja: Antti Laaksonen (2009).
Nykyaikainen tapa käyttää MySQL-tietokantaa PHP:llä on PDO-rajapinta, joka on mukana PHP:ssä versiosta 5.1 alkaen. PDO:lla voi käyttää MySQL:n lisäksi muitakin tietokantoja yhtenäisellä tavalla.
Oppaassa käytetään samaa esimerkkitaulua kuin ensimmäisessä osassa. Taulun nimi on tuotteet
, ja siihen on tallennettu kolme riviä:
+----+----------+-------+ | id | nimi | hinta | +----+----------+-------+ | 1 | kaali | 3 | | 2 | porkkana | 2 | | 3 | peruna | 3 | +----+----------+-------+
Seuraava PHP-koodi yhdistää tietokantaan, hakee taulusta tuotteet
kaikki rivit ja näyttää ne taulukossa. Tässä MySQL-palvelimen osoite on localhost
, käyttäjän nimi on antti
, salasana on abc
ja tietokannan nimi on testit
.
<?php // muodostetaan yhteys tietokantaan try { $yhteys = new PDO("mysql:host=localhost;dbname=testit", "antti", "abc"); } catch (PDOException $e) { die("VIRHE: " . $e->getMessage()); } // virheenkäsittely: virheet aiheuttavat poikkeuksen $yhteys->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // merkistö: käytetään latin1-merkistöä; toinen yleinen vaihtoehto on utf8. $yhteys->exec("SET NAMES latin1"); // valmistetaan kysely $kysely = $yhteys->prepare("SELECT * FROM tuotteet"); // suoritetaan kysely $kysely->execute(); // näytetään kyselyn tulokset taulukossa echo "<table>"; // käsitellään tulostaulun rivit yksi kerrallaan while ($rivi = $kysely->fetch()) { // $rivi["nimi"] sisältää nimen // $rivi["hinta"] sisältää hinnan echo "<tr>"; echo "<td>" . htmlspecialchars($rivi["nimi"]) . "</td>"; echo "<td>" . htmlspecialchars($rivi["hinta"]) . "</td>"; echo "</tr>"; } echo "</table>"; ?>
Yllä oleva koodi tulostaa sivulle seuraavan taulukon:
Kyselyssä on kaksi vaihetta: ensin kysely valmistetaan metodilla prepare
, sitten se suoritetaan metodilla execute
. Metodi fetch
palauttaa yksi kerrallaan kyselyn tuottamat rivit, kunnes rivejä ei enää ole, jolloin metodi palauttaa arvon false
ja silmukka päättyy.
Kun kysely suoritetaan PHP:n kautta, sen loppuun ei tarvitse kirjoittaa puolipistettä.
Jos kyselyssä on muuttuvia parametreja, kuten rivien hakuehdot, niiden kohdalle merkitään kysymysmerkki kyselyn valmistuksessa. Sitten kyselyn suorituksessa ilmoitetaan parametrien senkertaiset arvot niiden esiintymisjärjestyksessä.
Seuraava koodi hakee vain rivit, joissa hinta on 3:
// valmistetaan kysely $kysely = $yhteys->prepare("SELECT * FROM tuotteet WHERE hinta = ?"); // suoritetaan kysely $kysely->execute(array(3));
Seuraava koodi taas hakee rivit, joissa nimi on peruna tai porkkana:
// valmistetaan kysely $kysely = $yhteys->prepare("SELECT * FROM tuotteet WHERE nimi = ? OR nimi = ?"); // suoritetaan kysely $kysely->execute(array("peruna", "porkkana"));
Tässä kyselyssä PDO lisää merkkijonojen ympärille heittomerkit. Muutenkin PDO huolehtii automaattisesti siitä, että parametrit lisätään kyselyyn oikein.
Seuraava koodi tulostaa rivien määrän taulussa tuotteet
:
$kysely = $yhteys->prepare("SELECT COUNT(*) FROM tuotteet"); $kysely->execute(); $tulos = $kysely->fetch(); echo "Taulussa on " . $tulos["COUNT(*)"] . " riviä.";
Kyselyt INSERT
, UPDATE
, DELETE
suoritetaan vastaavasti kuin kysely SELECT
.
Seuraava koodi muuttaa porkkanan hinnaksi 4:
$kysely = $yhteys->prepare("UPDATE tuotteet SET hinta = ? WHERE nimi = ?"); $kysely->execute(array(4, "porkkana"));
Seuraava koodi kertoo äskeisessä kyselyssä muuttuneiden tai poistettujen rivien määrän:
$maara = $kysely->rowCount(); echo "Kysely vaikutti " . $maara . " riviin.";
Seuraavan koodin kysely ei toimi, koska taulun nimi on väärin:
$kysely = $yhteys->prepare("SELECT * FROM tuoteet"); $kysely->execute();
Virhettä voi etsiä lisäämällä koodiin poikkeusten käsittelyn:
try { $kysely = $yhteys->prepare("SELECT * FROM tuoteet"); $kysely->execute(); } catch (PDOException $e) { die("VIRHE: " . $e->getMessage()); }
Tässä tilanteessa virheviesti on "Table 'testit.tuoteet' doesn't exist", joka kertoo jo melko tarkasti, mistä virhe johtuu.
Seuraavassa esimerkissä luodaan järjestelmä, jonka kautta voi katsella tuotteiden tietoja sekä lisätä uusia tuotteita. Voit kokeilla toimivaa järjestelmää tässä.
Luodaan aluksi tiedosto yhteys.php
, joka luo yhteyden tietokantaan:
<?php try { $yhteys = new PDO("mysql:host=localhost;dbname=testit", "antti", "abc"); } catch (PDOException $e) { die("VIRHE: " . $e->getMessage()); } $yhteys->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $yhteys->exec("SET NAMES latin1"); ?>
Tämän jälkeen tietokantaa voi käyttää, kunhan liittää mukaan tiedoston yhteys.php
, eikä yhdistyskomentoa tarvitse kirjoittaa joka tiedoston alkuun.
Tiedosto lista.php
näyttää listan kaikista tuotteista:
<?php include("yhteys.php"); echo "<h1>Tuotelista</h1>"; $kysely = $yhteys->prepare("SELECT * FROM tuotteet"); $kysely->execute(); echo "<ul>"; while ($rivi = $kysely->fetch()) { $id = $rivi["id"]; $nimi = htmlspecialchars($rivi["nimi"]); echo "<li><a href=\"tuote.php?id=$id\">$nimi</a>"; } echo "</ul>"; echo "<p><a href=\"uusi.php\">Uusi tuote</a></p>"; ?>
Tuotelistassa tuotteen nimi on linkki tiedostoon tuote.php
, jossa näkyy yhden tuotteen nimi ja hinta. Listan alapuolella on linkki tiedostoon uusi.php
, jonka kautta voi lisätä uuden tuotteen.
Tiedosto tuote.php
näyttää yhden tuotteen tiedot:
<?php include("yhteys.php"); $kysely = $yhteys->prepare("SELECT * FROM tuotteet WHERE id = ?"); $kysely->execute(array($_GET["id"])); $tulos = $kysely->fetch(); echo "<p>Tuotteen nimi: " . htmlspecialchars($tulos["nimi"]) . "</p>"; echo "<p>Tuotteen hinta: " . htmlspecialchars($tulos["hinta"]) . "</p>"; echo "<p><a href=\"lista.php\">Takaisin</a></p>"; ?>
Näytettävän tuotteen tunnusnumero ilmoitetaan sivun osoitteessa: esimerkiksi tuote.php?id=3
näyttää sen tuotteen tiedot, jonka tunnusnumero on 3.
Tiedosto uusi.php
sisältää lomakkeen uuden tuotteen lisäämiseen:
<h1>Tuotteen lisäys</h1> <form action="lisays.php" method="post"> <p>Nimi: <input type="text" name="nimi"></p> <p>Hinta: <input type="text" name="hinta"></p> <p><input type="submit" value="Lisää"></p> </form>
Tiedosto lisays.php
lisää tuotteen tietokantaan ja ohjaa vastaavalle tuotesivulle:
<?php include("yhteys.php"); $kysely = $yhteys->prepare("INSERT INTO tuotteet (nimi, hinta) VALUES (?, ?)"); $kysely->execute(array($_POST["nimi"], $_POST["hinta"])); $id = $yhteys->lastInsertId(); header("Location: tuote.php?id=$id"); ?>
Tässä käytettiin hyödyllistä metodia lastInsertId
, joka ilmoittaa viimeksi lisätyn rivin tunnusnumeron. Näin käyttäjä voidaan ohjata uutta tuotetta vastaavalle sivulle.
Upeita nämä oppaat, toteutus aivan huipputasoa, kiitos valtavasta työmäärästä tämänkin amatöörin hyväksi.
Todella hyvä opas ja paljon hyödyllisiä vinkkejä aloittelijoille, mutta sen verran haluan korjata, että tuossa kohtaa "Yhdistys ja kysely" taulukon tulostamiseen, että jos haluttaisiin tuollainen taulukko, pitäisi vielä lisätä <table border> nykyisen pelkän <table> tilalle.
TeamSakke kirjoitti:
pitäisi vielä lisätä <table border> nykyisen pelkän <table> tilalle.
Noin ei ainakaan pitäisi tehdä. Taulukon ulkonäkö riippuu taulukon CSS-tyyleistä; myös pelkkä <table> voi sisältää tuollaiset reunat, jos niin säädetään. Joka tapauksessa ulkonäkö on täysin epäolennainen tämän oppaan kannalta.
Hyödyllinen perusopas. Nopeasti muistuu asiat mieleen. Itse aion kokeilla tuota PDO-tekniikkaa Symfonyn parissa. Näyttäisi toimivan samankaltaisesti.
Huomio! Kommentoi tässä ainoastaan tämän oppaan hyviä ja huonoja puolia. Älä kirjoita muita kysymyksiä tähän. Jos koodisi ei toimi tai tarvitset muuten vain apua ohjelmoinnissa, lähetä viesti keskusteluun.