Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: PHP/MySQL gallupin vastausten tallentamista

Omasual [02.02.2008 03:03:07]

#

Olen väkertänyt pientä kyselyjärjestelmää. Yksi tärkeä ominaisuus on kysymysten muokkaus ja se onkin aika hyvin valmis. Eli kysymyksiä voi admin-tunnuksilla lisätä, muokata ja poistaa itse.

Nyt pitäisi jotenkin näppärästi tallentaa vastaukset kantaan. Kysymysten lukumäärä saattaa muuttua, joten miten tehdä tallennusskripti?

Kanta on niin, että jokaiselle kysymykselle on oma tietue, malliltaan numero. Esimerkiksi 1, 2, 3 jne.
Näihin siis tallennetaan jokaiselta vastaajalta yksi tieto. Numero siis vastaa kysymykset-taulun kysymyksen id:tä.

Onko tätä järkevää toteuttaa niin, että tallennusskripti käy for-lausetta tarpeeksi monta kertaa läpi ja näin saadaan se oikea määrä kannan tietueita ja muuttujia Myslin INSERT INTO-rimpsuun?

Antti Laaksonen [02.02.2008 13:54:00]

#

Jos kysymyksiin vastataan sanallisesti, minusta kannattaa tallentaa jokainen käyttäjän vastaus omaksi rivikseen.

Seuraavassa esimerkissä käynnissä voi olla monta kyselyä, joissa jokaisessa on tietty määrä kysymyksiä. Vastaajille valitaan jollakin tavalla yksilölliset tunnusnumerot, ja tietokannassa lukee, mitä on vastattu kuhunkin kysymykseen.

kysely    kysymys   vastaaja  vastaus
--------------------------------------------------
3         1         77        Mielestäni...
3         2         77        Olen usein...
3         3         77        Vuosia sitten...
3         1         78        Tällä kertaa...
3         2         78        Ehdottomasti...
3         3         78        Jos kerran...

Jos kysymykset ovat monivalintoja, sama toteutus kelpaa, mutta vastaustekstin kohdalle tallennetaan vastauksen numero. Mutta jos ei tarvitse pitää kirjaa erillisten käyttäjien vastauksista eli ei ole kiinnostavaa, miten joku on vastannut kyselyyn kokonaisuutena, voikin tallentaa vain tiedon, kuinka monta kertaa tietty vastaus on valittu.

Seuraavassa esimerkissä kyselyyn 3 on vastannut 54 henkilöä. Ensimmäisen kysymyksen vastaajista 27 on valinnut vaihtoehdon 1, 13 vaihtoehdon 2 ja 14 vaihtoehdon 3. Tätä menetelmää käyttämällä kysymysten vastausten viemä tila tietokannassa ei riipu vastaajien määrästä.

kysely    kysymys   vastaus   maara
----------------------------------------
3         1         1         27
3         1         2         13
3         1         3         14
3         2         1         5
3         2         2         22
3         2         3         27

Ensimmäisessä toteutuksessa jokainen vastaus täytyy tallentaa INSERT INTO -komennolla. Toisessa toteutuksessa jokaisen vastauksen vastausmäärää täytyy kasvattaa UPDATE-komennolla.

Omasual [04.02.2008 22:41:21]

#

Kiitos kattavasta vastauksesta. Ihan ei ollut sitä mitä haettiin, mutta kysyn hieman eri tavalla:

Lomake (kyselylomake) on perinteinen form ja siinä kysymykset eroteltuina kysymyksen id-numerolla. Ja kun näitä kysymyksiä voi muokata, poistaa, lisätä makunsa mukaan, voisi lopputulos olla esimerkiksi tälläinen:

Kerro jotain <input type="text" name="3" />

Valitse radiobutton <input type="radio" name="12" value="1" />

Kerro jotain II <input type="text" name="57" />

Miten lisään nämä kantaan? Kanta olisi siis vain vastauskerran id ja vastaukset, eli:

id    3         12     57
1     Jotain    1      Jotainlisää
2     Enpäs     1      En taaskaan

Onko tässä mitään järkeä? Ja miten tuon teen, olen tottunut vain peruslisäykseen, eli kerrotaan, että lisätään kannan soluihin a, b, c tiedot muuttujista $_GET['a'], $_GET['b'], $_GET['c']. Tämähän ei nyt oikein toimi, kun voi olla ettei a, b ja c soluihin tule mitään, vaan ne tuleekin d, n ja r soluihin.

Antti Laaksonen [04.02.2008 23:41:09]

#

Tietokannan taulun rakenne on pysyvä, eikä kenttiä ole järkevää lisätä ja poistaa sen mukaan, mitä kysymyksiä sivulla sattuu sillä hetkellä olemaan. Ymmärsinhän oikein, että kysymykset 3, 12 ja 57 eivät olisi millään tavalla pysyviä, vaan viikon päästä esillä voisivat olla vaikka kysymykset 3, 5, 29 ja 70?

Kun nyt yrität tallentaa tietoa vaakasuuntaisesti, minä ehdotan sen tallennusta pystysuuntaisesti. Aiemman viestini ylemmän esimerkin mukaan kysymysten 3, 12 ja 57 vastaukset tallennettaisiin näin:

vastaaja  kysymys   vastaus
-----------------------------------
1         3         Jotain
1         12        1
1         57        Jotainlisää
2         3         Enpäs
2         12        1
2         57        En taaskaan

Sitten kun joku vastaisi kyselyyn, suoritettaisiin seuraavat SQL-komennot:

INSERT INTO vastaukset (vastaaja, kysymys, vastaus) VALUES (3, 3, 'AAAAA')
INSERT INTO vastaukset (vastaaja, kysymys, vastaus) VALUES (3, 12, '1')
INSERT INTO vastaukset (vastaaja, kysymys, vastaus) VALUES (3, 57, 'BBBBB')

Ja tauluun ilmestyisivät uudet rivit:

vastaaja  kysymys   vastaus
-----------------------------------
3         3         AAAAA
3         12        1
3         57        BBBBB

Näin voisi tutkia, mitä henkilö 2 on vastannut eri kysymyksiin:

SELECT kysymys, vastaus FROM vastaukset WHERE vastaaja = 2
kysymys   vastaus

-------------------------
3         Enpäs
12        1
57        En taaskaan

Näin voisi tutkia, mitä kysymykseen 57 on yleisesti vastattu:

SELECT vastaus FROM vastaukset WHERE kysymys = 57
vastaus
---------------
Jotainlisää
En taaskaan
BBBBB

Ja kun kysymyksiä lisättäisiin tai poistettaisiin, vastaukset sisältävä tietokantataulu pysyisi muuttumattomana.

Omasual [05.02.2008 00:27:41]

#

Kiitos vastauksesta ja hyvistä selityksistä, aion käyttää mainitsemaasi tapaa.

Mutta, kysymys kuuluu, millainen pitäisi formin käyttämän lisäyslauseen olla? Pitäisi siis saada se niin, että tallentaa vain ne tuoreet kysymykset, jotka sillä hetkellä on näkyvissä/olemassa.

Antti Laaksonen [06.02.2008 19:23:11]

#

Ensinnäkin lomakkeen kenttien nimiä kannattaa muuttaa niin, että nimen alussa on k-kirjain ja sitten vasta tulee kysymyksen numero. Nimittäin jos nimet ovat pelkkiä numerosarjoja, niiden käsittelyssä voi tulla vaikeuksia.

<form action="vastaus.php" method="post">
<input type="text" name="k5">
<input type="radio" name="k9" value="1">
<input type="radio" name="k9" value="2">
<input type="radio" name="k9" value="3">
<input type="submit">
</form>

Sitten PHP:n puolella tämän lomakkeen kentistä voi ottaa tarkempaan käsittelyyn k-kirjaimella alkavat ja muodostaa jokaisesta sopiva SQL-komento. Seuraavassa koodissa SQL-komennot vain tulostetaan, mutta yhtä hyvin ne voisi kohdistaa tietokantaan.

<?php
// vastaajan numero pitää valita jollain tavalla
$vastaaja = 123;
// käydään läpi kaikki lomakkeen kautta lähetetyt kentät
foreach ($_POST as $kysymys => $vastaus) {
    // jos kentän nimi muodostuu k-kirjaimesta ja numeroista...
    if (preg_match("/^k[0-9]+$/", $kysymys)) {
        // erotetaan pelkkä numero-osa
        $kysymys = substr($kysymys, 1);
        // jos tulee liikaa kenoviivoja, poista seuraava rivi
        $kysymys = mysql_escape_string($kysymys);
        // muodostetaan ja näytetään SQL-komento
        $sql = "INSERT INTO vastaukset (vastaaja, kysymys, vastaus) VALUES ($vastaaja, $kysymys, '$vastaus')";
        echo $sql;
    }
}
?>

En pysty nyt testaamaan tätä koodia, joten siinä saattaa olla pikku virheitä, mutta ajatus on toimiva. Joka tapauksessa PHP-skripti tunnistaa lomakkeen kenttien nimistä, mihin kysymyksiin on vastattu, joten lomaketta muuttamalla vastaukset ohjautuvat oikeisiin kysymyksiin PHP-skriptin pysyessä samana.

Omasual [17.02.2008 00:21:55]

#

Kiitos paljon, tämä selkeytti huomattavasti. Tuli esiin asioita, jotka on hyvä tietää, muttei niitä osannut ajatella.

Kiitti Antti!

Vastaus

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

Tietoa sivustosta