I have a complex form that has 11 columns. As for rows they will vary from about 20 to 50 depending on number of students. I am capturing data via a php script as arrays. Each column produces an array. Example, from the form I have fname[], lname[], exam_no[] etc so when the form is submitted with say, 10 rows, I end up with 11 arrays each with 10 entries, which I pass through some php function to remove empty elements. The arrays are being generated with no issues.
I want to insert data from these arrays into mysql using a loop. Basically, lname array will have all first_name for the first name column, lname array will feed the last_name column of the db and so on.
I am just unable to even start constructing the MySQL query to insert the data, I am well conversant with the 'ordinary' insert where you have columns and values and you already know how many rows will insert, mostly one row per insert.
Is is even possible to populate a MySQL Database Table with an insert using a PHP loop and with this many number of columns and making it flexible to insert any number of rows as that will vary each time a user enters student data?
UPDATE
This is what I came up with. It works but NOT as desired!
Arrays are coming like $fname[], lname[] etc
Then I built the master array to be $master_array=array['$fname, $lname];
$sql = "INSERT INTO testing (date, fname, lname) VALUES ";
foreach($master_array as $subarray) {
$sql .= "(NOW( )";
echo 'A nested array: '.$subarray.'<br />';
foreach($subarray as $value) {
$sql .= ", '$value'";
echo 'A Name: '.$value.'<br />';
}
$sql.= "), ";
}
$sql = substr($sql,0,-2); //removes extraneous , at end.
echo $sql;
$result=mysqli_query($dbc, $sql)
or die('Query Failed!');
?>
Since my query involves conactinating small pieces of code, I was printing it after its built to see what is to be inserted. It looked like so;
INSERT INTO table (date, fname, lname) VALUES (NOW( ), 'Andrew', 'Alex'), (NOW( ), 'Peterson', 'Marlon')
As I suspected, it inserts all first names in the first row, and all last names in the second row. The desired result is to insert first names in the first-name column and second names in the second name column. So now I need a way to insert all elements of one array into a single column and then move to the second array and insert it in the next column. That sounds complex, and I wonder if it's doable! Let me be educated by the masters of the php language as I am an intermediate or may be brand new newbie!
Isn't it better to group the information by student?
Example:
<form...>
<? foreach ($students as $id => $info) : ?>
<input type="text" name="fname;<=$id;?>" value="<?=$info['fname'];?>" />
<input type="text" name="lname;<=$id;?>" value="<?=$info['lname'];?>" />
etc
<? endforeach ?>
</form>
(I'm using PHP short tags here)
Then, when you process the form:
$update = array();
foreach ($_POST as $key => $value) {
// key will look like: fname;1, fname;2, etc
// so, split it on the ; sign to separate the field name from the student's id
$data = explode(';',$key);
// result:
// $data[0] = fname, lname, etc
// $data[1] = 1, 2, etc
// you can add some checks to make sure that this field is valid
// and that the id is in fact a valid id (number, > 0, etc)
// sanitize data (however you want, just an example)
$value = mysql_real_escape_string(trim($value));
// now add it to the update array, grouped by student id
$update[$data[1]][$data[0]] = $value;
// result:
// $update[1]['fname'] = 'First name student 1';
// $update[1]['lname'] = 'Last name student 1';
// $update[2]['fname'] = 'First name student 2';
// $update[2]['lname'] = 'Last name student 2';
// etc
}
After that, go through the update array:
foreach ($update as $id => $info) {
$sql = "UPDATE students
SET fname = '".$info['fname']."', lname = '".$info['lname']."'
WHERE id = $id";
mysql_query($sql);
}
Related
I am looking for some inspiration from someone wiser than me with PHP/MySQL.
In have a database application, and in this instance there are two primary tables and one child table.
Primary Table 1 - Documents
Primary Table 2 - JobDesriptions
Child Table - LnkDocuments_JobDescriptions, which as the title suggests is a one to many relational table between the Document and Job Description Table. In my Documents Table I have a field which is a lookup of JobDescriptions and presents options as a checkbox, this field is called 'AppliesTo', because of the way the application works, the field stores the results as a string, eg "1,2,3,4,5) I have used the explode function to turn this into an array and then insert each record into the child table, as I prefer 1-2-many relationships. This is the code that I have, and it works.
$jdarray = explode(',',$values['AppliesTo']);
foreach($jdarray as $item)
{
$sql2 = "INSERT INTO LnkDocuments_JobDescriptions (DocumentFk, JobDescriptionFk)
values ('".$keys["DocumentPk"]."', '$item')"; CustomQuery($sql2);
}
The problem I now have is that if that table gets updated, I need to also update the child table, i have tried this code (but quickly realised that it is wrong):
$jdarray = explode(',',$values['AppliesTo']);
foreach($jdarray as $item)
{
$sql = "SELECT * FROM LnkDocuments_JobDescriptions WHERE DocumentFk='".$keys["DocumentPk"]."' AND JobDescriptionFk='$item'"; ;
$num_rows = mysql_num_rows(CustomQuery($sql));
if ($num_rows > 0) //Delete Record
{
$sql2 = "DELETE FROM LnkDocuments_JobDescriptions WHERE DocumentFk='".$keys["DocumentPk"]."' AND JobDescriptionFk='$item'"; CustomQuery($sql2);
echo "JD FK : ".$item." deleted";
}
else //Insert Record
{
$sql3 = "INSERT INTO LnkDocuments_JobDescriptions (DocumentFk, JobDescriptionFk)
values ('".$keys["DocumentPk"]."', '$item')"; CustomQuery($sql3);
echo "JD FK : ".$item." added";
}
}
It occured to me that I need to compare differences in the arrays, but havent got a clue how to do this, but this is what I need:
If I can get $oldarray and $new array to compare, for example
if in old array there were values 1,2,3,4 and in $newarray there were values 1,2,3,5, I want the code to loop through each value to determine if there is a change, e.g. if value exists in old and new array then do nothing, if value exists in old array but not new then delete, if value exists in new array but not old then insert.
I have also thought about just deleting all associated records and adding again, but think this is bad practice and will result in high number primary key, also it is worth noting that in my example there are only 5 options, this is just for testing, in reality there could be dozens.
Thanks in advance
If you are trying to optimize things I'm not sure that reading the values already present in the table and then deleting only those are not in the new version while inserting the missing records is the best way to go. In my opinion it would be much faster to just delete everything in one query, then insert all records in one query. Try something like this:
$item_list = implode( ',' , $jdarray );
$delete_query = "DELETE FROM LnkDocuments_JobDescriptions WHERE DocumentFk='".$keys["DocumentPk"]."' AND JobDescriptionFk IN ( $item_list )";
CustomQuery($delete_query);
$document_key = "'" . $keys["DocumentPk"] . "'";
$item_list_to_insert = "($document_key, " . implode( "), ($document_key, ", $jdarray ) . ")";
$insert_query = "INSERT INTO LnkDocuments_JobDescriptions (DocumentFk, JobDescriptionFk) VALUES " . $item_list_to_insert;
CustomQuery($insert_query);
Note: I didn't test this, there might some debugging needed.
Im trying to insert Data into a table named team. The table holds 4 colums. selection_id(primary key), player_name, position, and fixture id.
The selection_id has a value of auto_increment. Im adding the player names and position to the table. However the problem is, for each value it extracts out of the arrays, $playnames and $positions, the selection_id updates. Like this:
This is not what I want. 5 names should be stored (thus storing the team selected) in the table before the selection_id updates. OR for each new row, where a new team selection is made, the selection_id must be the same.
Im not sure how to get around this problem. I thought about doing another query after the data has been inserted to overwrite the selection_id and making all the rows (in this case) equal to 117. But im sure this is not the most effecient way to do it.
If anyone can give me a couple of pointers it would be greatly appreciated.
Code follows:
if ( isset($_POST['submit']) ) {
$player_ids = array_map('intval', $_REQUEST['players']);
var_dump($player_ids);
$query = 'SELECT `name`, `position`
FROM `player_info`
WHERE `player_id` IN (' . implode(',', $player_ids) . ')';
$return_names = mysql_query($query) or die(mysql_error());
while ( $row = mysql_fetch_assoc($return_names) ) {
$selected[] = $row['name'];
$position[] = $row['position'];
}
for ($i=0; sizeof($selected) > $i; $i++){
$sql = mysql_query("INSERT INTO `team`(`selection_id`,`player_position`,`player_name`) VALUES ('selection_id\"\"','$position[$i]','$selected[$i]')")
or die(mysql_error());
echo $selected[$i];
echo $position[$i];
echo'<br>';
}
var_dump($selected);
}
I am using php to insert element values of a form in MYSQL. My form contains 20 different elements, that means
count($_POST)
returns 20. How can I make an INSERT query efficiently in PHP.
I will extract 20 values one by one then concatenate them again one by
one. I do not want to follow this method. Do you have some better
method?
Yes, you can use foreach. Example below assumes 3 thigs:
all of your form fields are text fields,
form fields are in the same order as columns in your table
form elements (<input>) have the same name attribute as columns names in your table
It can go like this:
$sql = 'INSERT INTO table_name VALUES (';
foreach ($_POST as $key => $value)
$sql .= mysqli_real_escape_string($value);
$sql .= ')';
I am trying to use a database where the email can have multiple entries, but i would like to prevent duplicate entries. Currently i have:
<?php
"SELECT Notes, itemName from UserItems where email = '$email'";
if("itemName" == $name && "Notes" == $desc) {
echo "duplicate";
}
?>
But itemName and Notes need to become strings for my if statement to work
My insert function is lower in my code but ill post it
$insert = ("insert into UserItems (itemName, ItemNumber, email, Price, Notes) Value (\"$name\", \"$ItemNumber\", \"$email\", \"$price\", \"$desc\")");
Am I missing something here? I held off answering cause I thought this would be too obvious and my post would waste time -
<?php
// add actual db connection info here
$email = 'someon#somewhere.com';
$name = 'John';
$desc = 'Some Description';
$row = mysql_fetch_array(mysql_query("SELECT Notes, itemName from UserItems where email = '$email'"));
if($row['itemName'] == $name && $row['Notes'] == $desc) {
echo "duplicate";
}
?>
You never actually run a query or fetch the results. Or define the variables you're comparing against. Are they $_POST, $_GET, results of the last row or something?
What about counting the number of entries where email = '$email'?
Based off the conversation we had in the comments, it sounds like your best bet is to handle this functionality at the database layer, by adding a unique contraint across all three columns (email, itemName, notes). With this solution the database will not allow more than one row with the same value for all three columns.
The mysql command would be:
alter table <your_table> add unique (`email`, `itemName`, `notes`);
// Will be inserted/updated no problem
foo#bar.com, itemName1, notes1
foo#bar.com, itemName1, notes2
foo#bar.com, itemName2, notes1
// An error will be returned because this row already exists
foo#bar.com, itemName1, notes2
The only drawback is that writes to the database will more costly as all three columns (notes especially) will have to be considered for the unique constraint.
Your other option is to load all rows matching the email address, then step through each row searching for matches against itemname and notes, which will be even more painful.
I am still learning PHP and MYSQL and trying to make a program to list all tables and data in database (that's done), edit selected row (that's done) and now add new record on selected table. Now the problem is with variable number of fields. Table could be with 3 fields, could be 4 and so on. On my code here $getValue is an array. I am printing it out only for testing. It could look like "Array ( [name] => Tomas [lastName] => Timas )" or "Array ( [stufName] => Phone [stufPrice] => 58 [comments] => My new phone )"
$getTable returns name of a table to insert into.
This has to be a new record on the table, so stufID or nameID or what ever ID will be NULL
How do I use "INSERT INTO table VALUES (value1, value2, value3,...)" if I do not know the number of values?
<?php
include "conf.ini"; //connection to the db
$getValue=$_REQUEST['value'];
$getTable=$_REQUEST['table'];
// test********************
print_r($getValue);
print '<br>';
print $getTable;
// test********************
if (!$_POST['submit']) {
print 'Please input data';
} else {
mysql_query ("INSERT INTO $getTable VALUES (?????)");
}
?>
I hope you know this is very dangerous, so do this only if you're sure there are no potentional attackers!
$all_keys = array_keys($getValue);
$getValue = array_map('mysql_real_Escape_string', $getValues);
mysql_query ("INSERT INTO $getTable (`".implode('`,`', $all_keys)."`) VALUES ('".(implode(",", $getValue))."')");
$values = array_map('mysql_real_escape_string', array_values($getValue));
$keys = array_keys($getValue);
mysql_query("INSERT INTO $getTable (".implode(',', $keys).") VALUES ('".implode('\',\'', $values)."')");
Perhaps you should create an include file to execute the values for $gettables and then it include that where you want $gettables values to be picked up.