Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: PHP, HTML: Taulukon lähetys ja tallennus tietokantaan

storm5 [31.10.2015 17:01:38]

#

Hei,

Väsäilen tässäurheiluun liittyvää tulostensyöttö-sivua

Tarkoitus että sivu listaa pelaajat kannasta tauluun ja lomakkeen kenttään voi syöttää tuloksen. tämän jälkeen lisää score-napilla tulokset päivittyisi kantaan.

Koodini toimii osaksi, listaus onnistuu ja tuloksia voi muuttaa ja kun painan lisää score painiketta niin vain taulukon viimeinen score päivittyy.
Miten tämä oikein pitäisi tehdä?


Lomake:

<h3>tulosten muuttaminen</h3>
<form action="insert_action2.php" id="form2" title="form2" method="post">
<table id="table1">
<?php

		$link = mysqli_connect("localhost", "form", "form", "form");

// Check connection
if($link === false){
    die("ERROR: Could not connect. " . mysqli_connect_error());
}

$sql = "SELECT * FROM form2" ;
$result = $link->query($sql);


        while($row = $result->fetch_assoc()){
        ?>

		  <tr>
			<td>
				<input type="text" name="id" id="id" value="<?php echo $row["id"]; ?>">
				<input type="text" name="name" id="name" value="<?php echo $row["name"]; ?>">
			</td>
			<td>
				<input type="text" name="score" id="score" size="2" value="<?php echo $row["score"]; ?>">
			</td>
        </p>
		<?php
        }
		$link->close();
        ?>

	</tr>
	</table>




	    <input type="submit" value="Lisää scoret">
</form>

insert_action2.php

<?php
		$link = mysqli_connect("localhost", "form", "form", "form");

// Check connection
if($link === false){
    die("ERROR: Could not connect. " . mysqli_connect_error());
}


foreach($_POST as $players => $value) {

$id = mysqli_real_escape_string($link, $_POST['id']);
$name = mysqli_real_escape_string($link, $_POST['name']);
$score = mysqli_real_escape_string($link, $_POST['score']);

	$sql = "UPDATE form2 SET score='$score', name='$name' WHERE id=$id";
		if(mysqli_query($link, $sql)){
				echo "lines updated to database: <br>$id - $name - $score <br><br><p><p>";
			} else{
				echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
			}
}

mysqli_close($link);


?>

php-koodi tulostaa nyt tämän:

lines updated to database:
98 - Jouko jormalainen - 150

lines updated to database:
98 - Jouko jormalainen - 150


lines updated to database:
98 - Jouko jormalainen - 150

Mod. korjasi kooditagit: tuloste ei ole PHP-koodia!

The Alchemist [31.10.2015 18:15:19]

#

Iteroit $_POST-taulukkoa väärin. Voisit aloittaa siitä, että otat selvää, mitä dataa siellä $_POST-taulukossa ylipäätään on. Debuggauksen alkeet.

Metabolix [31.10.2015 18:51:03]

#

$_POST-taulukkosi sisältää kolme arvoa: id, name, score. Lomakkeelta ei välity PHP:lle kuin yhden rivin tiedot, koska samannimisiä muuttujia voi olla vain yksi ja siis myöhempi samanniminen kenttä ylikirjoittaa aiemman. Silmukkasi siis kiertää läpi kohdat id, name ja score, ja joka kohdassa tallennat tietokantaan samat arvot. Silmukassa ei ole mitään järkeä, koska et edes yritä käyttää nykyistä arvoa ($players/$value) vaan käytät aina samoja kolmea arvoa. Ohjelmoinnin alkeet hakusessa?

Järkevin tapa usean rivin lähetykseen on käyttää indeksejä kenttien nimissä. Itse pidän selvimpänä, että $_POST-taulukkoon muodostetaan jo lähtökohtaisesti looginen rakenne:

<input type="text" name="data[1][id]" value="1" />
<input type="text" name="data[1][name]" value="Apina" />
<input type="text" name="data[1][score]" value="123" />

<input type="text" name="data[2][id]" value="2" />
<input type="text" name="data[2][name]" value="Banaani" />
<input type="text" name="data[2][score]" value="456" />

Näistä kentistä muodostuu seuraava $_POST-taulukko:

$_POST = [
  "data" => [
    "1" => ["id" => "1", "name" => "Apina", "score" => "123"],
    "2" => ["id" => "2", "name" => "Banaani", "score" => "456"],
  ]
];

Tulokset on helppo käydä läpi silmukalla:

foreach ($_POST["data"] as $vanha_id => $rivi) {
  $kysely = $pdo->prepare("UPDATE taulu SET id = ?, name = ?, score = ? WHERE id = ?");
  $kysely->execute([$rivi["id"], $rivi["name"], $rivi["score"], $vanha_id]);
}

Tietokantakyselyssä kannattaisi käyttää valmisteltuja kyselyitä (prepared statement) eikä vanhanaikaista, virhealtista escape-kikkailua. Yllä esitin tämän PDO:lla; en nyt suoralta kädeltä tiedä, miten sama tehtäisiin MySQLi:llä.

storm5 [01.11.2015 00:25:26]

#

Ehdinkin saada homman toimimaan stackoverflow.comista löytämilläni vihjeillä.

Kiitos avusta ja oikein huomasitte että alottelija olen näissä hommissa ja googlen avulla kauhotaan eteenpäin.

Näillä rimpsuilla sain homman toimimaan:

<input type="text" name="score_<?php echo $row["id"]; ?>" id="score_<?php echo $row["id"]; ?>" size="2" value="<?php echo $row["score"]; ?>">
<input type="hidden" name="id[<?php echo $row["id"]; ?>]" id="id[<?php echo $row["id"]; ?>]" value="<?php echo $row["id"]; ?>">
<input type="hidden" name="name_<?php echo $row["id"]; ?>" id="name_<?php echo $row["id"]; ?>" value="<?php echo $row["name"]; ?>">
foreach($_POST['id'] as $pid){
    $name = $_POST["name_$pid"];
    $score = $_POST["score_$pid"];


	$sql = "UPDATE form2 SET score='$score', name='$name' WHERE id=$pid";
		if(mysqli_query($link, $sql)){
				echo "lines updated to database: <br>$pid - $name - $score <br><br><p><p>";
			} else{
				echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
			}
}

Metabolix [01.11.2015 12:43:17]

#

Noissa rimpsuissa on vikaa. Hakasulut eivät ole id:ssä sallittuja. SQL-kyselyistä puuttuu nyt kokonaan syötteen käsittely (kuten escape), eli kyselyissä on vakava SQL-injektion mahdollistava tietoturva-aukko. Myös tulosteesta puuttuu käsittelu (kuten htmlspecialchars), joten siinä on myös XSS-tietoturva-aukko. Ylipäänsä ratkaisu on rumempi kuin minun esittämäni, kun kenttien nimissä on kikkailtu osittain taulukoilla ja osoittain alaviivoilla.

Lisäksi jos nyt id:tä ja nimeä ei ole tarpeen muuttaa lomakkeella, kannattaisi poistaa kyseiset kentät kokonaan.

Vastaus

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

Tietoa sivustosta