Kirjoittaja: Antti Laaksonen (2003).
⚠ Huomio! Tämä opas on vanhentunut. Oppaan sisältöön ei voi enää luottaa. Opas on säilytetty vain sen historiallisen arvon vuoksi. ⚠
Tämä opas kertoo, kuinka MySQL-tietokantaa käytetään PHP-skriptin kautta. Oppaassa on myös jonkin verran perustietoa tietokannoista ja SQL-kielestä. Ohjelmointiputkan opassarja MySQL ja PHP käsittelee perusteellisesti MySQL-tietokannan käyttöä PHP:llä.
Tietokanta on tehokas tapa tallentaa suuri (ja myös pieni) määrä tietoa. Tallennetusta tiedosta on helppo hakea monimutkaisinkin ehdoin. Tietokanta koostuu tauluista, jotka taas sisältävät joukon tietueita, joilla on ennalta määritetty rakenne. Yhdessä taulussa voi olla esimerkiksi varaston tavaroiden tiedot, jolloin jokaista tavaraa vastaa yksi tietue. Erilaisia tietokantamuotoja on lukematon määrä, mutta yleensä niiden perustana on SQL-kyselykieli.
Tämän oppaan tietokannaksi on valittu MySQL, koska se on ilmainen, toimii useilla järjestelmillä ja on varsin usein mukana huokeissakin sivustopaketeissa. Tietokannan dokumentaatio sekä kopioitavat versiot eri järjestelmille ovat osoitteessa http://www.mysql.com/. MySQL sisältää oman komentorivipohjaisen hallintaohjelman, mutta graafinen käyttöliittymä, kuten Windowsissa toimiva MySQL-Front, helpottaa tietokannan hallintaa ja auttaa ymmärtämään sen rakenteen.
Oppaan esimerkeissä käytetään varasto-nimistä taulua, joka sisältää varastossa olevien tavaroiden nimet, hinnat ja kappalemäärät. Taulu sisältää kolme kenttää: merkkijono nimi, kokonaisluku hinta ja kokonaisluku maara. Seuraava SQL-kysely luo kuvauksen mukaisen taulun:
CREATE TABLE varasto (nimi TEXT, hinta INT, maara INT);
Tauluun lisätään valmiiksi kolme tietuetta, joiden nimet ovat laskin, kamera ja televisio.
INSERT INTO varasto (nimi, hinta, maara) VALUES ('laskin', '10', '10'); INSERT INTO varasto (nimi, hinta, maara) VALUES ('kamera', '120', '5'); INSERT INTO varasto (nimi, hinta, maara) VALUES ('televisio', '950', '5');
Näin ollen taulu sisältää kolme tietuetta ja näyttää kokonaisuudessaan seuraavalta:
nimi TEXT | hinta INT | maara INT |
---|---|---|
laskin | 10 | 10 |
kamera | 120 | 5 |
televisio | 950 | 5 |
Yhteys tietokantapalvelimeen muodostetaan mysql_connect
-funktiolla. Funktion parametrit ovat palvelimen nimi, käyttäjätunnus ja salasana. Jos parametreja ei anneta, yhteys yritetään muodostaa omalle palvelimelle (localhost) ilman salasanaa. Funktion palauttama yhteyden tunniste on syytä ottaa talteen, sillä sitä tarvitaan myöhemmin.
//yhteys omalle palvelimelle $yhteys = mysql_connect(); //yhteys ulkoiselle palvelimelle $yhteys = mysql_connect("db.palvelin.fi", "käyttäjä", "salasana");
Tämän jälkeen valitaan käytettävä tietokanta mysql_select_db
-funktiolla. Funktion parametrit ovat tietokannan nimi ja yhteyden tunniste. Jos tunnistetta ei anneta, käytetään viimeksi luotua yhteyttä.
//valitaan tietokanta "testi" mysql_select_db("testi", $yhteys);
Nyt yhteys palvelimelle on kunnossa, ja tietokanta on valittu, joten tietokannan tauluihin voidaan tehdä tarvittavat kyselyt (lisätietoa seuraavissa kappaleissa). Lopuksi yhteys suljetaan mysql_close-funktiolla. Ilman parametreja funktio sulkee viimeksi luodun yhteyden.
//suljetaan yhteys mysql_close($yhteys);
Seuraava esimerkkiskripti sisältää pohjan palvelimen tietokantaa hyödyntävälle skriptille. Jos yhteyttä palvelimeen ei jostain syystä saada, tai tietokantaa ei löydy, skriptin suoritus lopetetaan virheilmoituksen kera.
<?php //muodostetaan yhteys tietokantapalvelimeen $yhteys = mysql_connect() or die("Yhdistäminen ei onnistunut!"); //valitaan tietokanta "testi" mysql_select_db("testi", $yhteys) or die("Tietokantaa ei löytynyt!"); //tähän tulevat tietokantakyselyt! //suljetaan yhteys mysql_close($yhteys); ?>
Tietokantakyselyjen kautta paitsi haetaan tietoa tietokannasta myös lisätään, muokataan ja poistetaan sitä. Seuraavassa on joitakin esimerkkejä SELECT
-, INSERT
-, UPDATE
- ja DELETE
-kyselyistä, joita varasto-tauluun voitaisiin kohdistaa. Tietokannasta hakeva SELECT
-kysely on monimutkaisin ja siitä onkin koko joukko esimerkkejä. Suluissa olevat arvot kuvaavat haun tuloksia.
SELECT * FROM varasto
SELECT nimi, maara FROM varasto
SELECT * FROM varasto WHERE nimi = 'laskin'
SELECT * FROM varasto WHERE hinta < 500 AND maara > 5
SELECT * FROM varasto WHERE nimi LIKE '%a%'
SELECT * FROM varasto ORDER BY nimi
SELECT * FROM varasto ORDER BY hinta DESC
SELECT * FROM varasto LIMIT 2
SELECT COUNT(*) FROM varasto
SELECT MAX(hinta) FROM varasto
SELECT SUM(maara) FROM varasto
SELECT ROUND(hinta * 5.94573, 2) FROM varasto
SELECT LEFT(nimi, 2) FROM varasto
SELECT DISTINCT maara FROM varasto
SELECT COUNT(*), maara FROM varasto GROUP BY maara
Tähti (*) kuvaa kaikkia tietueen kenttiä. Merkkijonot on ympäröitävä aina heittomerkeillä; luvut voi kirjoittaa ilmankin. WHERE
-ehto voi sisältää vertailuoperaattoreita =
, <>
, <
, >
, <=
ja >=
, ja vertailut voidaan yhdistää AND
- ja OR
-operaattoreilla. Peruslaskutoimitukset tarvittaessa sulkumerkein varustettuna ja funktiot ovat käytössä SELECT
- ja WHERE
-lausekkeissa.
Kaikkia edellä kuvattuja kyselyitä on mahdollista yhdistää toisiinsa, kunhan avainsanojen järjestys on oikea: SELECT
– DISTINCT
– FROM
– WHERE
– GROUP BY
– ORDER BY
– LIMIT
.
Seuraavassa on pari esimerkkiä tietueiden lisäämisestä (INSERT
), muuttamisesta (UPDATE
) ja poistamisesta (DELETE
):
INSERT INTO varasto(nimi, hinta, maara) VALUES ('radio', 175, 15)
UPDATE varasto SET hinta = 185 WHERE nimi = 'radio'
UPDATE varasto SET maara = maara - 1 WHERE nimi = 'radio'
DELETE FROM varasto WHERE nimi = 'radio'
Tässä kappaleessa on esitelty vasta pieni osa MySQL:n ominaisuuksista ja mahdollisuuksista. Kuitenkin jonkinlainen yleiskuva SQL-kyselyjen luonteesta on varmaan muodostunut, ja nyt on aika katsoa, kuinka sama tapahtuu PHP:n puolella.
SQL-kysely tietokantaan suoritetaan mysql_query
-funktion avulla. Toinen parametri, yhteyden tunniste, ei ole pakollinen, jos käytetään viimeksi avattua yhteyttä. SELECT
palauttaa taulukon, kun taas esimerkiksi INSERT
, UPDATE
ja DELETE
palauttavat pelkästään tiedon kyselyn onnistumisesta.
//haetaan kaikki tietueet $kysely = "SELECT * FROM varasto"; //suoritetaan kysely $haku = mysql_query($kysely, $yhteys);
Tämän kyselyn tulos olisi seuraavanlainen taulukko:
+-----------+-------+-------+ | nimi | hinta | maara | +-----------+-------+-------+ | laskin | 10 | 10 | | kamera | 120 | 5 | | televisio | 950 | 5 | +-----------+-------+-------+
Kyselyn ollessa SELECT
on haun tulokset jollakin tavalla käsiteltävä. Eräs keino on käyttää mysql_result-funktiota. Funktion ensimmäinen parametri on kyselyn tuloksena syntynyt taulukko, toinen parametri on rivin numero ja kolmas parametri on kentän numero tai kentän otsikko. Rivien ja kenttien laskeminen aloitetaan nollasta. Seuraavat funktiot palauttavat saman tuloksen, 'kamera':
//toisen rivin nimi-kenttä echo mysql_result($haku, 1, "nimi"); //toisen rivin ensimmäinen kenttä echo mysql_result($haku, 1, 0);
Funktio mysql_num_rows
palauttaa taulukon rivien määrän ja mysql_num_fields
palauttaa kenttien määrän. Tässä tapauksessa sekä rivien että kenttien määrä on 3:
//rivien määrä echo mysql_num_rows($haku); //kenttien määrä echo mysql_num_fields($haku);
Seuraava esimerkkiskripti, yhdistettynä tietokantayhteyden avaamiseen ja sulkemiseen, hakee varaston kaikki tavarat täydellisine tietoineen ja muodostaa niistä HTML-taulukon:
<?php echo "<html><body>"; //haetaan kaikki tavarat $kysely = "SELECT * FROM varasto"; //suoritetaan kysely $haku = mysql_query($kysely, $yhteys) or die("Virhe kyselyssä!"); echo "<table border>"; echo "<tr><td><b>nimi</b></td><td><b>hinta</b></td><td><b>määrä</b></td></tr>"; //käydään tavarat läpi for ($i = 0; $i < mysql_num_rows($haku); $i++) { //haetaan nimi, hinta ja määrä muuttujiin $nimi = mysql_result($haku, $i, "nimi"); $hinta = mysql_result($haku, $i, "hinta"); $maara = mysql_result($haku, $i, "maara"); //tulostetaan taulukon rivi echo "<tr><td>$nimi</td><td>$hinta €</td><td>$maara kpl</td></tr>"; } echo "</table>"; echo "</body></html>"; ?>
Skriptin tuloksena syntyvä taulukko näyttää tältä:
nimi | hinta | määrä |
---|---|---|
laskin | 10 € | 10 kpl |
kamera | 120 € | 5 kpl |
televisio | 950 € | 5 kpl |
Taulukon rivejä voi käsitellä myös mysql_fetch_array
-funktiolla, joka palauttaa seuraavan rivin taulukkomuodossa. Taulukon indekseinä on kenttien nimet (MYSQL_ASSOC
), kenttien numerot (MYSQL_NUM
) tai kummatkin (MYSQL_BOTH
).
<?php echo "<table border>"; echo "<tr><td><b>nimi</b></td><td><b>hinta</b></td><td><b>määrä</b></td></tr>"; //käydään tavarat läpi while ($rivi = mysql_fetch_array($haku, MYSQL_ASSOC)) { //haetaan nimi, hinta ja määrä muuttujiin $nimi = $rivi["nimi"]; $hinta = $rivi["hinta"]; $maara = $rivi["maara"]; //tulostetaan taulukon rivi echo "<tr><td>$nimi</td><td>$hinta €</td><td>$maara kpl</td></tr>"; } echo "</table>"; ?>
Kolmas toteutustapa on käyttää mysql_fetch_object
-funktiota, joka palauttaa taulukon seuraavan rivin objektina. Tällöin taulukon kenttiin viittaaminen on mahdollista ainoastaan nimen perusteella.
<?php echo "<table border>"; echo "<tr><td><b>nimi</b></td><td><b>hinta</b></td><td><b>määrä</b></td></tr>"; //käydään tavarat läpi while ($rivi = mysql_fetch_object($haku)) { //haetaan nimi, hinta ja määrä muuttujiin $nimi = $rivi->nimi; $hinta = $rivi->hinta; $maara = $rivi->maara; //tulostetaan taulukon rivi echo "<tr><td>$nimi</td><td>$hinta €</td><td>$maara kpl</td></tr>"; } echo "</table>"; ?>
Edelleen hyödyllistä luettavaa ovat PHP:n ja MySQL:n dokumentaatio. Opassarjan seuraava osa on myös viimeinen, mutta enpä osaa vielä luvata, mitä siihen tulee. Ehdotuksia oppaan aiheista kuten myös kommentteja ja palautetta voi lähettää sähköpostilla.
Antti Laaksonen, 1.7.2003
Seuraavasta osasta tulee vissiin aika iso :) kun on jo näin kauan kestänyt...
"WHERE-ehto voi sisältää vertailuoperaattoreita =, <>, <, >, <= ja >=, ja vertailut voidaan yhdistää AND- ja OR-operaattoreilla. Peruslaskutoimitukset tarvittaessa sulkumerkein varustettuna ja funktiot ovat käytössä SELECT- ja WHERE-lausekkeissa."
Kai muuttujia voi käyttää SELECT/WHERE-lauseessa? En selviä ilman niitä :|
Tuo eka komento, jonka suoritin eli:
CREATE TABLE varasto (nimi TEXT, hinta INT (6), maara INT (4));
antoi seuraavan virheen: ERROR 1046: No Database Selected
joten miten tuon kannan voi valita?
Mihinkäs väliin BETWEEN sijoitetaan, kun sitä ei ole tuolla mainittu? En jostain syystä saa sitä toimimaan.
"Seuraava SQL-kysely luo kuvauksen mukaisen taulun:
CREATE TABLE varasto (nimi TEXT, hinta INT (6), maara INT (4));"
Miten tuo tehdään PHP:llä? Ainakaan tuollainen rivi ei toiminut...
suoritin sen suoraan myslin komentokehotteessa :)
lainaus:
"Seuraava SQL-kysely luo kuvauksen mukaisen taulun:
CREATE TABLE varasto (nimi TEXT, hinta INT (6), maara INT (4));"
Miten tuo tehdään PHP:llä? Ainakaan tuollainen rivi ei toiminut...
Voit tehdä sen php:llä näin:
<?php mysql_query("CREATE TABLE varasto (nimi TEXT, hinta INT(6), maara INT(4))"); ?>
Huomaa: Ei puolipistettä SQL-komennon loppuun.
mysql_query()-funktiolla voidaan ajaa tietokantakomentoja.
Miten tuon COUNT() -funktion tuloksen sais näytettyä PHP:llä?
Vaikkapa seuraavasti (pelkistetty esimerkki):
<?php $kysely = mysql_query("SELECT COUNT(*) FROM varasto"); $rivi = mysql_fetch_row($kysely); $lkm = $rivi[0]; ?>
voiko tietokannan päivittämiseen käyttää tämmöstä komentoa:
<?php
mysql_query("UPDATE maara (nimi, hinta, maara) VALUES('uusinimi', 'uusihinta', 'uusimaara') WHERE nimi = 'radio'");
?>
mulla ei toiminu yhteys omaa palvelimeen mysql_connect()-tavalla, mutta pääsin tällee:
mysql_connect("localhost", "root", "");
irwinace, no sulta puuttuu tosta updatesta ainakin taulu, mihin muutoksen teet..
Mitenkäs tommonen TABLE sitten tapetaan? Minä kun innoissani tein niitä vähän liikaa ja vääränlaisia =p
edit: HAA se on "DROP TABLE nimi"! hassua...
Testasin tuossa tuota tietokannasta hakua ja jotenkin en vain tiedä mistä mättää, kun aina tulee vain se kirjoittamani tiedosto selaimeen eikä se luo mitään html-taulukkoa, kuten pitäisi. Eli johtuuko tämä siitä, etten ole onnistunut avaamaan yhteyttä tietokantaan? Vaan tulee jotain
<?php
echo "<html><body>";
//haetaan kaikki tavarat
$kysely = "SELECT * FROM varasto";
etc etc...
SELECT * FROM varasto ORDER BY hinta DESC
Miten tuo saadaan niin että se ottaa kaksi lukua huomioon? Kun tilanne on nyt se että on luvut 2, 5 ja 10 nii se heittää 5 ensimmäiseksi sitten 2 ja viimeseks 10? eli miten saan 10 ekaks?
Vulcan: kokeiles seuraavaa: SELECT * FROM varasto ORDER BY hinta ASC
Vulcan, sulla on kenttätyyppinä joku tekstityyppi tms, vaikka kentän pitäis olla numeraalinen.
INSERT INTO varasto(nimi, hinta, maara) VALUES ('radio', 175, 15) Lisää tauluun uuden tietueen annetuilla arvoilla.
Eikös tässä pitäisi olla väli tuon "varasto"-tekstin jälkeen:
INSERT INTO varasto (nimi, hinta, maara) VALUES ('radio', 175, 15) Lisää tauluun uuden tietueen annetuilla arvoilla.
TatuSalin:
Sulla on siis asennettuna PHP koneelle? ja otat selaimella yhteyden (kotikoneella usein localhost) ja katsot tulkattua koodia näin. Ethän siis yritä avata tiedostoa suoraan ilman tulkkia?
Hei miten saisi sellatis että kun rekisteröityis foorumille niin pääsisi samoilla käyttäjätunnuksilla kirjautumaan sivulle minulla on phpBB2 foorumi ja eikös se mysql onnistu?
aarnis, otat yhteyden sinne phpBB2 tietokantaan josta haet login-tiedot ja vertaat mitä käyttäjä syötti.
Tämmönen koodi ois, missä vika?:
<?php
//muodostetaan yhteys tietokantapalvelimeen
$yhteys = mysql_connect("localhost","root","") or die("Yhdistäminen ei onnistunut!");
//valitaan tietokanta "testi"
mysql_select_db("testi", $yhteys) or die("Tietokantaa ei löytynyt!");
$kysely="INSERT INTO tiedot (nimi, salasana) VALUES ('asd', 'dsa')";
mysql_query($kysely,$yhteys);
//suljetaan yhteys
mysql_close($yhteys);
?>
Ja kyseinen taulu nimi ja salasana-sarakkeilla on kannassa ja molemmat muotoa TEXT.
EDIT: Joo, ei mitään, puhuin lämpimikseni. :D
Heh, jos MBNetissäki toimis mysli... Ois aika helppoa se elämä :)
Oli paljon kysymyksiä ilman vastauksia. Suurimpaan osaan löytyy vastaus osoitteesta http://www.w3schools.com/sql/default.asp . Säästyn vaivalta kirjottaa samat asiat tänne.
Pakko sanoa että kiitos, tästä ollut aikoinaan todella paljon hyötyä :)
Kiitoksia paljon loistavasta oppaasta. Löytyisipä samankaltaista materiaalia useamminkin :)
Hei!
Miten saisin seuraavanlaisesta taulukosta haettua länpötilatiedot jotta saisin jpgraphilla net piirrettyä, array sen pitää kuitenkin olla
table temps
ID temp time
0121202 24 11:00
5453453 4 11:00
3423432 10 11:00
0121202 24 12:00
5453453 6 12:00
3423432 11 12:00
0121202 24 13:00
5453453 5 13:00
3423432 12 13:00
0121202 24 14:00
jtapio kirjoitti:
Hei!
Miten saisin seuraavanlaisesta taulukosta haettua länpötilatiedot jotta saisin jpgraphilla net piirrettyä, array sen pitää kuitenkin olla
table temps
ID temp time
0121202 24 11:00
5453453 4 11:00
3423432 10 11:00
0121202 24 12:00
5453453 6 12:00
3423432 11 12:00
0121202 24 13:00
5453453 5 13:00
3423432 12 13:00
0121202 24 14:00
Explodella väännät tekemään joka kolmannelle jotain jollain funktiolla.
hyvä opas!
pääse hyvin alkuun.
<?php $e = "laskin"; $yhteys = mysql_connect("localhost","root","") or die("ei toimi O_o!"); mysql_select_db("varasto", $yhteys) or die("Virhe, taulua varasto ei löytynyt"); $tieto = mysql_query("SELECT (nimi, $e) FROM varasto ") or die("Error, kysely ei onnistunut!"); echo $tieto; mysql_close($yhteys); ?>
Miks tää antaa ton "error, kysely ei onnistunut" kaikki nuo taulut ja salasanat asetettu oikein, onko koodissa vikaa?
Kenties kuitenkaan haettavia kenttiä ei kuulu laittaa sulkeisiin.
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.