Tervehdys Ohjelmointiputkalaiset.
Tarvitsen neuvoja hyvään toteutus tapaan päivittäessä useaa riviä yhdellä formilla tietokantaan.
Tein esimerkin, josta saatte käsityksen mitä olen hakemassa.
Esimerkki tarvitsee tietokannan db, taulun maat, jossa sarakkeet id, nimi, kansalaisuus sekä muutaman rivin tietoja.
<?php //Yhdistetään tietokantaan $yhteys = mysql_connect("localhost" , "username", "password"); if(!$yhteys) { die('Could not connect: ' . mysql_error()); } //Valitaan tietokanta $tietokanta = mysql_select_db("db", $yhteys); if(!$tietokanta) { die(mysql_error()); } //Valitaan PHP:n merkistö mysql_set_charset('utf8',$yhteys); //Uusien tietojen tallennus tietokantaan if(isset($_POST['submit'])) { //Haetaan lähetetyt tiedot array-muuttujiin $id = array(); $nimi = array(); $kansalaisuus = array(); $id = $_POST['id']; $nimi = $_POST['nimi']; $kansalaisuus = $_POST['kansalaisuus']; for($i = 0; $i < count($id); $i++) { $sql = "UPDATE maat SET nimi = '".mysql_real_escape_string($nimi[$id[$i]])."', kansalaisuus = '".mysql_real_escape_string($kansalaisuus[$id[$i]])."' WHERE id = '".$id[$i]."'"; $result = mysql_query($sql) or trigger_error(mysql_error(), E_USER_ERROR); } } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <meta http-equiv = "Content-Type" content = "text/html; charset=UTF-8" /> <title></title> </head> <body> <form method = "post" action = "<?php echo $_SERVER['PHP_SELF']?>"> <table> <tr> <th>Maan nimi:</th> <th>Kansalaisuus:</th> </tr> <?php //Haetaan maiden nimet tietokannasta $sql = "SELECT * FROM maat"; $result = mysql_query($sql) or trigger_error(mysql_error, E_USER_ERROR); //Jos haku onnistui tulostetaan input-kentät if($result) { for($i = 0; $info = mysql_fetch_row($result); $i++) { echo '<tr><td>'; echo '<input type = "hidden" name = "id['.$i.']" value = "'.$info[0].'" />'; echo '<input type = "text" name = "nimi['.$info[0].']" value = "'.htmlspecialchars($info[1]).'" />'; echo '</td>'; echo '<td>'; echo '<input type = "text" name = "kansalaisuus['.$info[0].']" value = "'.htmlspecialchars($info[2]).'" />'; echo '</td></tr>'."\n"; } } ?> <tr> <td><input type = "submit" name = "submit" value = "Tallenna" /></td> </tr> </table> </form> </body> </html>
Tulisiko minun hakea vanhat tiedot tietokannasta ja verrata if-lauseella uusiin ja vain tietojen vaihtuessa tallentaa tiedot tietokantaan?
Yksi ratkaisu on käyttää piilokenttiä, jotka sisältävät rivien vanhat tiedot. Riviä täytyy päivittää vain, jos piilokentät eroavat tekstikentistä.
Toisaalta nykyinen toteutuksesikin lienee käytännössä riittävä.
Kikkailet turhaan for-silmukalla ja piilotetuilla id-kentillä. Voisit tehdä suoraan näin:
<?php foreach ($_POST['nimi'] as $id => $nimi) { $kansalaisuus = $_POST['kansalaisuus'][$id]; // Nyt on kätevästi muuttujat $nimi, $kansalaisuus, $id. }
Koodissasi on SQL-injektion paikka, koska et tarkista id-syötettä mitenkään. Voisit varmuuden vuoksi muuttaa sen kokonaisluvuksi ((int)$id).
HTML:ssä =-merkin ympärille ei kuulu välejä.
Ja PHP_SELF on turvaton (vieläkö/-kin?), käytä sen tilalla SCRIPT_NAMEa.
Kiitos todella hyvistä ajatuksista, joilla voin korjata koodinkirjoitustani entistä paremmaksi. Taidan lukea vielä PHP-oppaan uudelleen lävitse, koska kyseinen foreach-funktio on jäänyt minulta kokonaan käyttämättä ja nopeasti vilkaistuna todellakin helpottaa ainakin tässä tilanteessa.
"Piilokentät" olisi koodin optimoinnin kannalta varmaan parempi ratkaisu, kuin nykyinen, jos ajatellaan, että rivejä olisi yli 20 ja sarakkeita noin sama määrä. Ei taida tosin nykytekniikalla tuottaa hirveitä eroja, mutta en tiedä miten laajoja projekteja joudun tulevaisuudessa käsittelemään.
Jos joku vielä edellä mainittujen tapojen lisäksi keksii jotain rakentavaa palautetta ottaisin sen mielihyvin vastaan.
Kyseistä aihetta sivuten olisi vielä yksi javascript-ongelma.
Olen tulostanut jokaiselle riville samaa metodia käyttäen checkbox-kentät joiden avulla on tarkoitus määrittää mitkä rivit tallennetaan yms. Ongelmani on saada "check/uncheck all checkboxes" ominaisuus toimimaan.
Sain koodattua seuraavan esimerkin, mutta se toimii vain jos jokaisella checkboxilla on sama nimi, joka tässä tapauksessa ei ole mahdollista.
<html> <head> <script type="text/javascript"> function selection() { //Noudetaan valitse_kaikki-checkboxin arvo muuttujaan valitse_kaikki = document.getElementById('valitse_kaikki'); //Jos checkbox valittu valitaan kaikki valinta-checkboxit if(valitse_kaikki.checked == true) { //Ongelman ydin. Kuinka saada esimerkiksi hakemaan divin perusteella tai että hakee kaikki joiden nimenalku on valinta*? valinta = document.getElementsByName('valinta'); for(i = 0; i < valinta.length; i++) valinta[i].checked = true; } //Muuten tyhjennetään valinnat else { valinta = document.getElementsByName('valinta'); for(i = 0; i < valinta.length; i++) valinta[i].checked = false; } } </script> </head> <body> <p>Valitse kaikki: <input type="checkbox" id="valitse_kaikki" onclick="selection()" /></p> <!-- Todelliset nimet valinta$id eli valinta1, valinta2 jne. --> <p>Valinta 1: <input type="checkbox" name="valinta" /></p> <p>Valinta 2: <input type="checkbox" name="valinta" /></p> <p>Valinta 3: <input type="checkbox" name="valinta" /></p> </body> </html>
Aihe on jo aika vanha, joten et voi enää vastata siihen.