简体   繁体   中英

PHP single mySQL table plus undefined number of multiple mySQL table entries through a single HTML form

this is my first question posted on the internet ever, I was usually able to find some sort of a solution, but now I'll either have to do this some other more basic way or, as I hope get help from someone on Stack Overflow. I have an idea how to do it another way but I would really like if I can make it work like this.

I am trying to build an internet application through which people or organizations would be able to inform the shelter about the clothes they would like to donate to be picked up by shelter's mobile team.

I'm now putting a simplified version of my HTML form, PHP script, JavaScript function, and mySQL used to make the tables in which I want to store the info from the HTML form.

HTML form:

<form action="apply.php" method="post">
<p>Please enter your personal info so we can make contact with you:<br />
Name: <input type="text" name="name" /><br />
Address: <input type="text" name="addr" /><br />
Phone: <input type="text" name="phon" /><br />
e-mail: <input type="text" name="emai" /><br /><br />
<!--previous part of the form needs to be entered only once in a table named
"application" in real form there are more fields-->     
<div id="dod">
<p><b>I wish to donate:</b> (in case you wish to donate more stuff click on
"Add more"):</p>
<p> <select name="kind">
<option value="Jacket">Jacket</option>
<option value="Shirt">Shirt</option>
<option value="Pants">Pants</option>
</select></p>
<!--there are more options in the actual form-->
<p>How many items of this type would you like to donate?
<input type="text" name="piec"></p>      
<p>Size of the items: <select name="size">
<option value="S">S</option>
<option value="M">M</option>
<option value="L">L</option>
<option value="Other">Other</option>
<option value="Various">Various</option>
</select></p><br />
<!--This part should be entered several times depending on how many types of clothes
and in which sizes people wish to donate. There are more options in actual form-->
</div>
<center>
<a href="#" onclick="JavaScript:addClothes()" style="font-family: 'verdana'">Add more
</a><br /><br />
<input type="submit" value="Submit"></input>
</center>
</form>

This is simplified version of JavaScript which adds form fields into

function addClothes() {
document.getElementById('dod').innerHTML+="<p><select name='kind'><option\n\
value='Jacket'>Jacket</option>\n\
<option value='Shirt'>Shirt</option>\n\
<option value='Pants'>Pants</option>\n\
</select>\n\
</p><p>How many items of this type would you like to donate? <input type='text'\n\
name='piec'></p>
<p>Size: <select name='size'><option value='S'>S</option>\n\
<option value='M'>M</option>\n\
<option value='L'>L</option>\n\
<option value='Other'>Other</option>\n\
<option value='Various'>Various</option></select></p><br />";
}

These are mySQL expression used to create tables in the shelter_db databse:

CREATE TABLE shelter_db.application
(
Name varchar(80) NOT NULL,
Address varchar(80) NOT NULL,
Phone varchar(20) NOT NULL,
Email varchar(50) NOT NULL,
Stamp timestamp NOT NULL,
PRIMARY KEY (Stamp)
);

CREATE TABLE shelter_db.clothes
(
Kind varchar(40) NOT NULL,
Pieces integer(6) NOT NULL,
Size varchar(20),
Stamp timestamp,
FOREIGN KEY (Stamp)
REFERENCES application (Stamp)
);

My idea is for the data from these two tables to be connected by the timestamp when the records were made, since there most certainly wouldn't be simultaneous entries by different parties. The person assigned to contact donors could then see what that particular party wishes to donate and can send a mobile team with a car or a pickup truck accordingly.

What I'm struggling with is how to formulate the php/sql page, and after going through dozens of web pages I couldn't find one solution that would fit my needs. I'm assuming that I should use implode function but after trying various solutions I wasn't able to find the right one. Here is the code:

<?php
$con = mysql_connect('localhost','root','');
if (!$con) {die('Unable to connect: ' . mysql_error());}
mysql_select_db('shelter_db', $con);
//the following part needs only one entry into application table of the db
$sql="INSERT INTO application (Name, Address, Phone, Email, Stamp)
VALUES
('$_POST[name]','$_POST[addr]','$_POST[phone]','$_POST[emai]',time());
//the following part needs multiple entries depending on how many times the Add more 
//button in the HTML form has been clicked
INSERT INTO clothes (Kind, Pieces, Size, Stamp)
VALUES
('$_POST[kind]','$_POST[piec]','$_POST[size]',time())";
if (!mysql_query($sql,$con)) { die('Error: ' . mysql_error()); }
else {
echo 'Database entry successful.';
}
mysql_close($con)
?>

I would be grateful to anyone who could offer me the code that would fit my example. Sorry for the longer post but they said to be thorough. Thanks in advance.

First of all, correlating by timestamp is definitely not a good idea. First of all, it's possible for two people to use your web site at exactly the same time, and their submissions would get confused. Second, the time could change between inserting into the application table and the clothes table (datetimes are precise to the second, and maybe the first insert was at time T.999 and the second at T+1.000; this second problem can be resolved by assigning a variable to the time at the beginning of the script, and using that in all your inserts. But because of the first problem, you should still not use timestamps for this.

Instead, you should assign a unique ID to the application. This is easily done in mysql by having an ID column with the auto-increment option. When you add a row to the table, you leave this column out (or give its value as NULL), and the server will automatically assign a value that's 1 higher than the last value assigned. The function mysql_insert_id() will return the value that was assigned in the last insertion you did. In the clothes table, you add an application_id column, which contains that ID. You use this to correlate the two tables.

The next thing you have to deal with is how to handle multiple clothes column in the form. In each row that you added, you gave the form elements the same names as in the previous row. When PHP is processing the form, $_POST['kind'] can only get one of them. The way this is handled is by giving them named ending in [] , eg <select name="kind[]"> . This tells PHP that it should create an array of these inputs. You can then get the kind of the first row as $_GET['kind'][0] , the second row is $_GET['kind'][1] , and so on. So when you're writing to the database, you can do:

foreach ($_GET['kind'] as $i => $kind) {
  $sql = "INSERT INTO clothes (Application_ID, Kind, Pieces, Size) VALUES ($id, ".$kind.", "$_GET['piec'][$i]", '"$_GET['size'][$i]"')";
  mysql_query($sql, $con) or die ('Error: ' . mysql_error());
}

$id contains the value you got from mysql_insert_id() .

Finally, I wouldn't be doing my duty as a SO answerer if I didn't point out that the mysql_XXX functions are deprecated and should not be used in any new code. They have been superceded by mysqli_XXX and PDO. These allow you to create "prepared" statements, so you don't have to substitute variables into strings as above, which potentially allows SQL-injection attacks unless you're careful to sanitize your data (I didn't do so above for expediency).

BTW, I haven't looked at your JavaScript. It doesn't look like there's much to it. If someone else notices problems in it, please pipe up.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM