I am trying to insert an unknown number of rows into MySQL using PHP. This is how it should work:
Javascript parses HTML DOM to create a multi-dimensional array based on a css class. The array will have a certain number of rows(or sub-arrays) corresponding to the number of elements that have that class. (This could be any integer 0 or greater... obviously).
Then, on a JavaScript event, the array is sent to a PHP script.
The PHP script will INSERT data from the array into MySQL.
My problem is that I don't know how to tell my PHP script how many values are in the array. And I don't know how to write the mysql_query() without knowing the number of values (or rows) that should be inserted.
You can insert more than one row at a time to MySQL:
INSERT INTO table1 (column1, column2, ...) VALUES (value_col1, value_col2), (value2_col1, value2_col2), ...;
In PHP, you can build your query by looping through rows and adding them to the SQL string:
$sql = "INSERT INTO table1 (col1, col2) VALUES ";
foreach($rows as $i=>$row) {
if ($i>0) {
$sql .= sprintf(",(%s,%s)", $row["col1_value"], $row["col2_value"]);
} else {
$sql .= sprintf("(%s,%s)", $row["col1_value"], $row["col2_value"]);
}
}
mysql_query($sql);
You have to be sure to properly escape your values depending upon what you're actually inserting.
Why don't you prepare a two dimensional array while searching with the css class identifier like this?
//This is jquery code - you can write javascript to do the same
$(`.class`).each(function(i,e){resultsArray.push($(this).val());});
This will save you from the headache of traversing a multidimensional array in the backend and you can simply do a count() in you PHP code and the following query preparation.
Query preparation
Assuming you have a two dimensional array you can use a bulk insert query like this:-
INSERT INTO tablename (a,b)
VALUES
('1', 'one'),
('2', 'two'),
('3', 'three')
And prepare the query dynamically using PHP like this -
$counter = 0;
$valuesPart = NULL;
foreach($_POST as $each)
{
if($counter > 0)
$appendComma = ",";
else
$appendComma ="";
$valuesPart .= $appendComma."(".$each['key1'].",".$each['key2'].")";
$counter++;
}
if(!empty($valuesPart))
$mysql_query = "INSERT INTO tablename (a,b) VALUES ".$valuesPart;
So, you don't need to know how many results are to be actually inserted.
If you stay with the multidimensional array, you will probably need to code or search for a code to traverse the multidimensional array which will probably involve recursion and a lot of complex code. There will be many chances of errors and it will be a slower (may be little but a finite amount which is not necessary).
So I assume the array is getting to PHP successfully, through $_POST or whatever? If you aren't sure then do a var_dump or echo_r so we can see.
EDIT - wow I put explode where I meant implode several times. fixed.
Assuming that it is, and that each 'sub' array is an associative array in form
[0]
'id' => 1
'name' => 'Billy'
'DOB' => .....
[1]
etc.
And the code to build a single query inserting all rows, like this INSERT INTO table ('f1','f2',f3') VALUES ('v11', 'v22', 'v33'), ('v21', 'v22', 'v23'), ......
$escapeAndQuote = function($x) {return "'".mysql_real_escape_string($x)."'";};
$rowwise = function($x) {return '('. implode(', ', array_map($escapeAndQuote, $x)) .')';
$fieldString = $rowwise(array_keys($arr[0]));
$valString = implode(', ', array_map($rowwise, $arr));
$sql = "INSERT INTO table $fieldString VALUES $valString";
mysql_query($sql, $conn);
Use a foreach loop to cycle through the array.
// Example:
foreach($submitted_array as $insert_array)
{
//php and mysql insert query here
}
Perhaps prepared statements would assist you in your endeavors. Essentially you will declare a generic insert statement and then "bind" values to each input. Read more on PHP PDO Prepared Statements.
Related
This has probably been asked before, but I'm having a hard time finding an answer to this.
Let's say I have an Array and a Variable of unknown length, in PHP.
For example:
$value1 = 123;
$array = array("apples", "oranges", "bananas");
Because the array has 3 values, I want to insert them into 3 MySQL rows like this:
(123, apples)
(123, oranges)
(123, bananas)
But the tricky part is that the array can be any length. Sometimes it's just 1 value, sometimes it's 5 values, etc.
I know I could count the array, and loop the MySQL insert statement in PHP, but I was hoping there was a simpler way to do this with a single MySQL statement.
You can build a single query to execute this.
Given a PDO instance in $pdo, and using prepared statements to prevent SQL injection:
$value1 = 123;
$array = array("apples", "oranges", "bananas");
$values = [];
$list = "";
foreach ($array as $item) {
$values[] = $value1;
$values[] = $item;
$list .= "(?,?),";
}
$list = rtrim($list, ','); // Chop off the last comma
$query = "INSERT INTO table VALUES $list"; // Would be like INSERT INTO table VALUES (?,?),(?,?),(?,?)...
$stmt = $pdo->prepare($query);
$stmt->execute($values);
For($i=0;$i<arr.len;$i++){
//your SQL query be like
Insert into table values($value1,array[$i]);
}
How much more simple do you want? Write a stored procedure then call it from your PHP If you want a one liner SQL statement but the above approach is the simplest I guess
I have a JSON array of occurrences, which occurrence contains a date, a value and a quantity, so:
[["May 09 2014",1.17,63],["May 10 2014",1.01,171],["May 11 2014",1.56,87]]
I need to insert this information in a MySQL database using a stored procedure, so I'm wondering what are all the possible ways to achieve this:
php loop (but each list can have up to 200 occurrences)
Parse a XML string inside the stored procedure
create some crazy logic to parse a string inside the stored procedure
is there another way?
First, create PHP array from JSON:
$jsonString = '[["May 09 2014",1.17,63],["May 10 2014",1.01,171],["May 11 2014",1.56,87]]';
$array = json_decode($jsonString);
Now loop that array, generate inserts and write everything in single go. 200 entries are not so much to loop.
$query = "INSERT INTO `tableName` (`data`, `value`, `quantity`) VALUES ";
$inserts = [];
$params = [];
foreach ($array as $index => $row) {
$inserts[] = "(:data{$index}, :value{$index}, :quantity{$index})";
$params[] = [
":data{$index}" => $row[0],
":value{$index}" => $row[1],
":quantity{$index}" => $row[2],
];
}
$sql = $db->prepare($query.implode(', ', $inserts));
$sql->execute($params);
You can do it in a loop. json_decode() it and loop over it, inserting into MySQL. No need to do 200 requests though, you can grow one single large INSERT request by connecting new and new parts to it and then run it just once at the end. Like this:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
The code would be:
$arr = json_decode($arr);
$data = [];
foreach($arr as $a) $data = "('".$a[0]."',".$a[1].",".$a[2].")";
mysqli_query("INSERT INTO tbl_name(a,b,c) VALUES". join(',', $data));
You can also store it in plain JSON form in a text field.
Depending on circumstances sometimes it's the best solution
You can use json_decode() for decoding the json string.
$json = '[["May 09 2014",1.17,63],["May 10 2014",1.01,171],["May 11 2014",1.56,87]]';
$occu_array = json_decode($json);
Now you can iterate this array and insert the data rows into the database.
Iteration can be done in three ways:
Commit an insert for every item in the array.
Build one sql with one insert command for all items and commit this single sql.
Build one sql with multiple insert commands, one for each item, and commit this single sql.
The SQL can be build up with one code line without iterations:
$sql = 'INSERT INTO table_name (col1, col2, col3) VALUES ' . substr(strtr(trim($json), '[]', '()'), 1, -1);
The json string must be in $json. Consider that there is no conversion of the data type.
I'm passing an html array to php using jquery serializearray() function.
In php I can access the array using $_POST like
$a = $_POST['htmlarray']
The html array, however, is an array of arrays like so
htmlarray[] = [[1,2,3,4,5,6],[7,8,9,10,11,12],[13,14,15,16,17,18]]
I want to format the variable $a so that I can insert all the html array values in one single insert query like
INSERT INTO table
(val1, val2, val3, val4, val5, val6)
VALUES
(1,2,3,4,5,6),
(7,8,9,10,11,12),
(13,14,15,16,17,18)
I know I have to use an implode function, can anyone show how this could be done.
I'm not quite sure what an html array is, but try the following:
$a = $_POST['htmlarray'];
// unserialize $a
// build sql query up to '...VALUES '
foreach ($a as $row) {
$sql .= '(';
$sql .= implode(',', $row);
$sql .= ')',
}
This should iterate through the arrays and append all your rows to the string. Note, however, that this code does not take care of SQL Injections at all! Not to be meant for production.
I have an array stored in a variable $contactid. I need to run this query to insert a row for each contact_id in the array. What is the best way to do this? Here is the query I need to run...
$contactid=$_POST['contact_id'];
$eventid=$_POST['event_id'];
$groupid=$_POST['group_id'];
mysql_query($query);
$query="INSERT INTO attendance (event_id,contact_id,group_id) VALUES ('$eventid','$contactid','$groupid')";
Use a foreach loop.
$query = "INSERT INTO attendance (event_id,contact_id,group_id) VALUES ";
foreach($contactid as $value)
{
$query .= "('{$eventid}','{$value}','{$groupid}'),";
}
mysql_query(substr($query, 0, -1));
The idea here is to concatenate your query string and only make 1 query to the database, each value-set is separated by a comma
Since no one hasn't stated that yet, you actually cannot do this:
$query = '
INSERT INTO [Table] ([Column List])
VALUES ([Value List 1]);
INSERT INTO [Table] ([Column List])
VALUES ([Value List 2]);
';
mysql_query($query);
as this has been prevented to prevent sql injections in the mysql_query code. You cannot have semicolon within the given query param with mysql_query. With the following exception, taken from the manual comments:
The documentation claims that "multiple queries are not supported".
However, multiple queries seem to be supported. You just have to pass
flag 65536 as mysql_connect's 5 parameter (client_flags). This value
is defined in /usr/include/mysql/mysql_com.h:
#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */
Executed with multiple queries at once, the mysql_query function will
return a result only for the first query. The other queries will be
executed as well, but you won't have a result for them.
That is undocumented and unsupported behaviour, however, and easily opens your code to SQL injections. What you can do with mysql_query, instead, is
$query = '
INSERT INTO [Table] ([Column List])
VALUES ([Value List 1])
, ([Value List 2])
[...]
, ([Value List N])
';
mysql_query($query);
so you can actually insert multiple rows with a one query, and with one insert statement. In this answer there's a code example for it which doesn't concatenate to a string in a loop, which is better than what's suggested in this thread.
However, disregarding all the above, you're probably better of still to use a prepared statement, like
$stmt->prepare("INSERT INTO mytbl (fld1, fld2, fld3, fld4) VALUES(?, ?, ?, ?)");
foreach($myarray as $row)
{
$stmt->bind_param('idsb', $row['fld1'], $row['fld2'], $row['fld3'], $row['fld4']);
$stmt->execute();
}
$stmt->close();
Use something like the following. Please note that you shouldn't be using mysql_* functions anymore, and that your code is suseptible to injection.
for ($i = 0; $i < count($contactid); $i++) {
$query="INSERT INTO attendance (event_id,contact_id,group_id) VALUES ('$eventid','$contactid[$i]','$groupid')";
mysql_query($query);
}
I'm not sure running multiple queries is the best thing to do, so won't recommend making a for loop for example, that runs for each element of the array. I would rather say, make a recursive loop, that adds the new elements to a string, that then gets passed to the query. In case you can give us a short example of your DB structure and how you'd like it to look like (i.e. how the array should go into the table), I could give you an example loop syntax.
Cheers!
What about:
$contactIds = $_POST['contact_id'];
$eventIds = $_POST['event_id'];
$groupIds = $_POST['group_id'];
foreach($contactIds as $key => $value)
{
$currentContactId = $value;
$currentEventId = $eventIds[$key];
$currentGroupId = $groupIds[$key];
$query="INSERT INTO attendance (event_id,contact_id,group_id) VALUES ('$currentEventId','$currentContactId','$currentGroupId')";
mysql_query($query);
}
Well, you could refactor that to insert everything in a single query, but you got the idea.
I have a PHP 2D array, many keys, each with one value, I need to put this into a MySQL database.
The database has 8 fields. Eg. Field1, Field2, Field3, etc. I am trying to ensure value1 => field1, value2 =>field2, value3 => field3 and so on, when one record is full (i.e. after 8 values) a new record should be created for the next 8 values and so on.
I am aware that the 1st, 9th, 17th, 26th values etc, will need an insert statement and the intermediate values will be an update statement.
What is the best way of going about this?
array_chunk() is the possible answer if I took this question correct.
And then just something like this
foreach ($chunks as $row) {
array_map $row with mysql_real_escape_string
implode to get VALUES clause
INSERT
}
But the real array sample can save a ton of both your own and other people's time
Say, if you want to have saved the keys, not values, array_reverse must be called first.
Simplest to understand would be to use a counter. Like:
$cc=0;
while(...){ // Whatever your finished condition is
if($cc==0){
//INSERT
}else{
//UPDATE
}
$cc++;
if($cc==8) $cc=0;
}
$records = array_chunk($yourArray);
foreach($records as $record)
{
$record = array_map("mysql_real_escape_string", $record);
$q = 'INSERT INTO `yourTable` VALUES
'.$record[0].',
'.$record[1].',
'.$record[2].',
'.$record[3].',
'.$record[4].',
'.$record[5].',
'.$record[6].',
'.$record[7].',
';
$res = mysql_query($q);
}
I have a PHP 2D array, many keys, each with one value, I need to put this into a MySQL database.
Sounds very odd - PHP doesn't do 2-dimensional arrays. Only nested arrays.
I am aware that the 1st, 9th, 17th, 26th values etc, will need an insert statement
I presume that means that you don't have a 2D array - you've got a 2D data set mapped to a non-nested PHP array....in which case:
for ($x=0; $x<count($data)/8; $x+=8) {
$qry="INSERT INTO sometable (f1, f2, f3,f4,f5,f6,f7,f8) VALUES (";
$join='';
for ($y=0; $y<8; $y++ ) {
$qry.=$join . prep_val($data[$x+$y]);
$join=',';
}
mysql_query($qry);
}
(where prep_val enloses strings and escapes meta chars)
C.
I think you should keep in the db id of the last inserted row, and how many of the fields in this row are free.
This should allow you to make appropriate update and/or inserts when putting new data into db.
For splitting array into parts you may use array_slice() array_splice() and array_chunk() functions.