Meerdere records via PHP form in SQL database

Status
Niet open voor verdere reacties.

steef27

Gebruiker
Lid geworden
16 sep 2007
Berichten
51
Hallo,

Voor een simpel adressenboek zoek ik een script om meerdere adressen in één keer in te kunnen voeren in een formulier, om deze vervolgens in een sql database weg te schrijven.
Een formulier met een enkel record heb ik nu, maar nu moet ik record voor record invoeren.
Er bestaan veel varianten op het internet heb ik al gezien, maar de meeste zijn veel te complex.

Heeft iemand een voorbeeld voor mij?

Groet
Steef
 
Hoe zie je dat interactief gezien voor je?
 
Een multi-line invoerscherm waarbij gebruik gemaakt wordt van array's voornaam[], achternaam[], etc.
Dus één knop "submit" om alle records in één keer in de database op te nemen.

Geeft dit antwoord op jouw vraag?
 
Niet helemaal, wil je in plaats van één serie met invoervelden gewoon een vast aantal extra series tonen of moet dat interactief met een "+"-knopje en dan steeds een nieuwe serie tonen?

Het eerste is redelijk eenvoudig te realiseren door één serie te maken, de namen van alle invoervelden (name="") op array-notatie te zetten en dan de serie te kopiëren. Vervolgens kun je dan in de afhandeling van het formulier wel uitlezen hoeveel series er zijn door van één array de sizeof (of count) op te vragen en dan een for-loop te genereren.

De tweede is ingewikkelder omdat je dan met Javascript moet werken bij het formulier, de afhandeling is echter wel gelijk aan hierboven omdat je uiteindelijk weer een array qua velden krijgt.
 
Het gaat om een vast aantal velden en rijen.
Het moet dus ook om kunnen gaan met het opslaan van lege velden (rijen die ik nu nog niet gebruik).
 
Kun je aangeven hoe jouw HTML er uit gaat zien/ziet? Dan kunnen van daaruit verder naar de afhandeling :)
 
HTML:
<table width="500" border="0" cellspacing="1" cellpadding="0">
	<form name="form1" method="post" action="">
	<tr> 
	<td>
<table width="500" border="0" cellspacing="1" cellpadding="0">
	<tr>
		<td align="center"><strong>Voornaam</strong></td>
		<td align="center"><strong>Achternaam</strong></td>
	</tr>

	<tr>
		<td align="center">
			<input name="voornaam" type="text" id="voornaam">
		</td>
		<td align="center">
			<input name="achternaam" type="text" id="achternaam">
		</td>
	</tr>


	<tr>
		<td colspan="2" align="center"><input type="submit" name="Submit" value="Submit"></td>
	</tr>
</table>
		</td>
	</tr>
	</form
</table>
 
Laatst bewerkt door een moderator:
Gaat het alleen om voornamen en achternamen of moet er nog data opgeslagen worden? Zet die velden er dan ook bij zodat we straks het in één keer kunnen behandelen.

PS: Een tabel in een tabel is meestal geen goed idee, in dit geval lijkt het gewoon om de weergave van het formulier te gaan. Een tabel is eigenlijk bedoelt om data te tonen, niet om een indeling te bepalen :)
 
Je hebt helemaal gelijk, qua opmaak.
Voorlopig is dit mijn HTML:
HTML:
<html>
<form>
ID:				<input name="id" type="text" id="id">
Voornaam:		<input name="voornaam" type="text" id="voornaam">
Achternaam:		<input name="achternaam" type="text" id="achternaam">
Geslacht:		<select>
					<option value="man">Man</option>
					<option value="vrouw">Vrouw</option>
				</select>
Geboortejaar:	<input name="geboortejaar" type="number" id="geboortejaar">
Memo:			<input name="memo" type="text" id="memo">
</form>
</html>
 
Laatst bewerkt door een moderator:
Ben je van plan om die ID steeds zelf uniek in te gaan voeren? Het lijkt mij makkelijker om gebruik te maken van de AUTO_INCREMENT functie op een kolom in MySQL :)

Om er een array van de maken hoef je alleen maar blokhaken toe te voegen aan de name=""-waardes :) Vervolgens kun je de serie invoervelden gewoon kopiëren.

Aangezien efficient programmeren (DRY-principe: Don't Repeat Yourself) het mooiste is (en programmeurs lui zijn :D) maak ik gebruik van een for-lus:
PHP:
<?php
// Configuratie    
$aantalFormulieren = 5;

if ("POST" === $_SERVER['REQUEST_METHOD']) {
    var_dump($_POST);
} else {
    // Formulier(en) tonen
?>
<html>
<form method="post" action="">
    <?php for ($i = 0; $i < $aantalFormulieren; $i++) { ?>
    <div>
    ID:             <input name="id[]" type="text">
    Voornaam:       <input name="voornaam[]" type="text">
    Achternaam:     <input name="achternaam[]" type="text">
    Geslacht:       <select name="geslacht[]">
                        <option value="man">Man</option>
                        <option value="vrouw">Vrouw</option>
                    </select>
    Geboortejaar:   <input name="geboortejaar[]" type="number">
    Memo:           <input name="memo[]" type="text">
    </div>
    <?php } ?>
    <input type="submit" value="Verstuur" />
</form>
</html>
<?php } ?>
Omdat een CSS id per definitie uniek op een pagina hoort te zijn heb ik ze nu uit de formulier elementen gehaald, je zou ze desgewenst kunnen vervangen door een CSS class. Verder was je vergeten om een naam mee te geven aan het element voor het geslacht dus die heb ik toegevoegd.

Voor het gemak heb ik een configuratie variabele aangemaakt waarmee je het aantal series aan kunt geven.

Geef aan wanneer je dingen niet begrijpt dan kan ik het je wel uitleggen.
 
Laatst bewerkt:
Thanks, super! Een mooie korte code!
Waar vind ik het stukje voor de connectie met de server/database en het wegschrijven van gegevens in de database?

o ja, en je hebt gelijk, ID wil ik niet invoeren maar gebruik maken van AUTO_INCREMENT.
Wat moet ik hiervoor in het script veranderen? In mysql heb ik het al aangepast.
 
Laatst bewerkt door een moderator:
Dat stukje moet je er zelf nog bij zetten. Meestal wordt het connectie maken in een apart bestand gezet en die dan via require_once ingeladen.

Het wegschrijven zal moeten komen op het gedeelte waar nu var_dump($_POST); staat, dat is het moment dat het formulier is verzonden en daar ga je de query opbouwen. Aangezien ik jouw database-structuur niet ken zul je die zelf eerst moeten maken, dan kan ik eventueel wel aanvullen. Het is mogelijk in één INSERT query meerdere waardes direct mee te geven, maak daar dus ook gebruik van zodat je niet 5x (in dit geval) de query op gaat bouwen, uitvoeren en dan opnieuw de query bouwen, weer uitvoeren, etc.

Het ID kun je gewoon uit het formulier halen, aangezien je dit nu door MySQL laat regelen :)
 
Zoiets?
PHP:
<?php
// Connectie met database
$con = mysql_connect( 'localhost', 'root', '******' );
$db = mysql_select_db( 'MijnData', $con );
if ( $db == false )
	die( mysql_error() );
	
// Configuratie    
$aantalFormulieren = 5;
 
if ("POST" === $_SERVER['REQUEST_METHOD']) {
//    var_dump($_POST);

		$voornaam = mysql_real_escape_string($_POST["voornaam"][$i]);
		$achternaam = mysql_real_escape_string($_POST["achternaam"][$i]);
		$geslacht = mysql_real_escape_string($_POST["geslacht"][$i]);
		$geboortejaar = mysql_real_escape_string($_POST["geboortejaar"][$i]);
		$memo = mysql_real_escape_string($_POST["memo"][$i]);
		$update=" UPDATE `test` SET `voornaam` = '$voornaam', `achternaam` = '$achternaam', `geslacht` = '$geslacht', `geboortejaar` = '$geboortejaar', `memo` = '$memo' WHERE
					`id` =$id LIMIT 1; ";
		mysql_query($update) or die( mysql_error());

} else {
    // Formulier(en) tonen
?>
<html>
<form method="post" action="">
    <?php for ($i = 0; $i < $aantalFormulieren; $i++) { ?>
    <div>
    Voornaam:       <input name="voornaam[]" type="text">
    Achternaam:     <input name="achternaam[]" type="text">
    Geslacht:       <select name="geslacht[]">
                        <option value="man">Man</option>
                        <option value="vrouw">Vrouw</option>
                    </select>
    Geboortejaar:   <input name="geboortejaar[]" type="number">
    Memo:           <input name="memo[]" type="text">
    </div>
    <?php } ?>
    <input type="submit" value="Verstuur" />
</form>
</html>
<?php } ?>
 
Laatst bewerkt door een moderator:
Je hebt nu een UPDATE-query :) Dat moet een INSERT worden ;)

Realiseer je wel dat $i niet gedefineerd is, je zou de for-lus kunnen kopiëren die bij velden weergeven gebruikt wordt.
 
vergeef me voor m'n kennisgebrek, maar ik kom er niet uit. Deze code heb ik nu met als gevolg dat er na "verstuur" een blanco pagina verschijnt en na elke "verzending" opnieuw 5 records worden vastgelegd i.p.v. bijgewerkt.

PHP:
<?php
// Connectie met database
$con = mysql_connect( 'localhost', 'root', '' );
$db = mysql_select_db( 'MijnData', $con );
if ( $db == false )
    die( mysql_error() );
    
// Configuratie    
$aantalFormulieren = 5;
 
if ("POST" === $_SERVER['REQUEST_METHOD']) {
        for ($i = 0; $i < $aantalFormulieren; $i++) {
        $voornaam = mysql_real_escape_string($_POST["voornaam"][$i]);
        $achternaam = mysql_real_escape_string($_POST["achternaam"][$i]);
        $geslacht = mysql_real_escape_string($_POST["geslacht"][$i]);
        $geboortejaar = mysql_real_escape_string($_POST["geboortejaar"][$i]);
        $memo = mysql_real_escape_string($_POST["memo"][$i]);
        $update=" INSERT INTO `test2` (`voornaam`, `achternaam`, `geslacht`, `geboortejaar`, `memo`)
					VALUES ('$voornaam', '$achternaam', '$geslacht', '$geboortejaar', '$memo')";
        mysql_query($update) or die( mysql_error());
 		}
		} 
		else {
    // Formulier(en) tonen
?>
<html>
<form method="post" action="">
    <?php for ($i = 0; $i < $aantalFormulieren; $i++) { ?>
    <div>
    Voornaam:       <input name="voornaam[]" type="text">
    Achternaam:     <input name="achternaam[]" type="text">
    Geslacht:       <select name="geslacht[]">
                        <option value="man">Man</option>
                        <option value="vrouw">Vrouw</option>
                    </select>
    Geboortejaar:   <input name="geboortejaar[]" type="number">
    Memo:           <input name="memo[]" type="text">
    </div>
    <?php } ?>
    <input type="submit" value="Verstuur" />
</form>
</html>
<?php } ?>
 
Dat je steeds vijf nieuwe records krijgt is logisch want je wilde
een script om meerdere adressen in één keer in te kunnen voeren in een formulier, om deze vervolgens in een sql database weg te schrijven.

Dat je niets te zien krijgt is logisch, er wordt immers bij het verwerken van het formulier geen output gegenereerd :)

Dit is iets efficiënter:
PHP:
if ("POST" === $_SERVER['REQUEST_METHOD']) {
    // Query opbouwen
    
    $query = 'INSERT INTO test2 (voornaam, achternaam, geslacht, geboortejaar, memo) VALUES ';
    
    for ($i = 0; $i < $aantalFormulieren; $i++) {
        if ($i > 0) {
            $query .= ',';
        }
        
        $query .= sprintf(
            '(%1$s, %2$s, %3$s, %4$s, %5$s)',
            mysql_real_escape_string($_POST["voornaam"][$i]),
            mysql_real_escape_string($_POST["achternaam"][$i]),
            mysql_real_escape_string($_POST["geslacht"][$i]),
            mysql_real_escape_string($_POST["geboortejaar"][$i]),
            mysql_real_escape_string($_POST["memo"][$i])
        );
    }
    mysql_query($query) or die( mysql_error());
    echo $aantalFormulieren .' records toegevoegd!';
} else {
// Formulier(en) tonen
?>
Nu wordt er één query uitgevoerd (in plaats van vijf) en wordt er feedback getoond.

Wil je rijen aanpassen dan zul je een specifieke set op moeten vragen of alles opnieuw in een formulier tonen.
 
Ik krijg nu de melding:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ' , man, , ),(, , man, , ),(, , man, , ),(, , man, , )' at line 1

Je hebt gelijk, ik was niet duidelijk genoeg. Ik wil records kunnen wegschrijven, maar daarna ook kunnen updaten. Na het toevoegen moet het formulier en de data dus in beeld blijven, zodat gegevens gewijzigd of aangevuld kunnen worden.

Zit ik met onderstaande in de juiste richting te denken?

<input type="text" name="voornaam[' . $i["id"] . ']" value="'.$i["voornaam"].'"
 
Ah ja, laat ik ook strings quoten :D
Dit:
PHP:
'(%1$s, %2$s, %3$s, %4$s, %5$s)',
Moet dit worden:
PHP:
'("%1$s", "%2$s", "%3$s", "%4$s", "%5$s")',

Het updaten zou ik gescheiden houden, wat je zou kunnen doen is eerst een lijst met alle namen opvragen en die tonen met een linkje naar het bewerkformulier of voor alle rijen in de database een formulier tonen. Het is aan jou hoe je het wilt, maar je zult in ieder geval eerst een SELECT-query uit moeten voeren om data op te vragen :)
 
Naar aanleiding van jouw tips en voortschrijdend inzicht heb ik met wat geknipt en geplakt de boel omgegooid.
Het is bijna zoals ik het wil hebben, m.u.v. 2 problemen:
1) de checkbox kan ik aanvinken en opslaan, maar na het opslaan is de checkbox weer onaangevinkt (in de database is deze wel "aangevinkt")
2) voor de pulldown bij "geslacht" geldt hetzelfde: de keuze wordt wel opgeslagen, maar niet getoond in het formulier na het opslaan.

Enig idee welke fout ik maak?

Hieronder mijn aangepaste code:

PHP:
<?php
$con = mysql_connect( 'localhost', 'root', '' );
$db = mysql_select_db( 'MijnData', $con );
if ( $db == false )
	die( mysql_error() );
	
if ( isset( $_POST["submit"] ) ) {
	foreach( $_POST["id"] AS $id ) {
		$check = mysql_real_escape_string($_POST["check"][$id]);
		$voornaam = mysql_real_escape_string($_POST["voornaam"][$id]);
		$achternaam = mysql_real_escape_string($_POST["achternaam"][$id]);
		$geslacht = mysql_real_escape_string($_POST["geslacht"][$id]);
		$geboortejaar = mysql_real_escape_string($_POST["geboortejaar"][$id]);
		$memo = mysql_real_escape_string($_POST["memo"][$id]);
		$update=" UPDATE `test2` SET `check` = '$check', `voornaam` = '$voornaam', `achternaam` = '$achternaam', `geslacht` = '$geslacht', `geboortejaar` =' $geboortejaar', `memo` = '$memo' WHERE
					`id` =$id LIMIT 1; ";
		mysql_query($update) or die( mysql_error());
		}
		}	
$sql = " SELECT * FROM `test2`" ;
$res = mysql_query( $sql ) or die( mysql_error() );

if ( mysql_num_rows( $res ) > 0 ) {
	echo '<form method="post">';
		echo '<div><H1>Lijst</H1></div>'."\n";
	while ( $row = mysql_fetch_assoc( $res ) ) {
		echo ' <div>'."\n";
		echo ' <input type="checkbox" name="check[' . $row["id"] . ']" value="J">'."\n";
		echo ' <input type="text" name="voornaam[' . $row["id"] . ']" value="'.$row["voornaam"].'">'."\n";
		echo ' <input type="text" name="achternaam[' . $row["id"] . ']" value="'.$row["achternaam"].'">'."\n";
		echo ' <select name="geslacht[' . $row["id"] . ']">'."\n";
		echo '   	<option value=""></option>'."\n";
		echo '   	<option value="Man">Man</option>'."\n";
		echo '		<option value="Vrouw">Vrouw</option>'."\n";
		echo ' </select>'."\n";
		echo ' <input type="number" name="geboortejaar[' . $row["id"] . ']" value="'.$row["geboortejaar"].'">'."\n";
		echo ' <input type="text" name="memo[' . $row["id"] . ']" value="'.$row["memo"].'" size="100">'."\n";
		echo ' </div>'."\n";
		echo '<input type="hidden" name="id[]" value="' . $row["id"] . '">  ' . "\n";
	}
	echo '<input type="submit" name="submit" value="Bevestigen">';
}
?>
 
Je controle op een verzonden formulier is niet waterdicht, controleren of een element bestaat is geen goede manier om formulieren te controleren. Gebruik daarvoor mijn eerder aangegeven methode :)

Verder wordt de checkbox niet aangevinkt omdat je de waarde niet meestuurt. Een tekstveld moet je vullen met value="" maar een checkbox aanzetten gebeurt door checked="checked" mee te geven aan het element:
PHP:
echo ' <input type="checkbox" name="check[' . $row["id"] . ']" value="J"'. ($row['check'] == 'J' ? ' checked="checked"' : '') .'>'."\n";

Voor een dropdown geldt hetzelfde, alleen moet je daar selected="selected" meegeven aan het juiste <option>-element:
PHP:
        echo '      <option value="Man"'. ($row['geslacht'] == 'Man' ? ' selected="selected"' : '') .'>Man</option>'."\n";
        echo '      <option value="Vrouw"'. ($row['geslacht'] == 'Vrouw' ? ' selected="selected"' : '') .'>Vrouw</option>'."\n";
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan