Implode array and insert dynamic data to mysql database - php

This is code for insert dynamic data to mysql database.
$name = $_POST['name'];
for ($i = 0; $i < count($name); $i++) {
if ($name[$i] != "") {
$test= implode(", ", (array)$name[$i]);
print_r($test);
$sql = "INSERT INTO employee_table (name)
VALUES ('$test')";
if ($conn->query($sql) === true) {
echo ('ok');
}
}
}
$conn->close();
I used implode(", ", (array)$name[$i]) to returns a string from $name by comma but when print_r($test); like this:
AlexBrownHelloHugo
I got 2 problems and hope your help:
Result when print_r($test); is Alex,Brown,Hello,Hugo
Store $test [Alex,Brown,Hello,Hugo] same row into dabase.
Thanks all.

Something like this:
$names = empty($_POST['name']) ? [] : $_POST['name'];
foreach($names AS $name){
if (!empty($name)) {
$test= '['.implode(", ", (array)$name).']';
print_r($test);
$sql = "INSERT INTO employee_table (name)
VALUES ('$test')";
if ($conn->query($sql) === true) {
echo ('ok');
}
}
}
I wanted to repost this comment I made:
its a bad idea to store data as a delimited list when you can make it a related table. In any case I would save it as this ,Alex,Brown,Hello,Hugo, with leading and trailing delimiters, that way when you query it you can do this field LIKE '%,Alex,%'. The difference is if you have foo,some,bar and foo,something,bar and you do field LIKE '%some%' note no , you will find both of those some and something. To query the first and last items like I showed above with , they would need the , around them. You can just use trim($field, ',') to remove them before explode etc
UPDATE
And this one
its unclear the structure of $name is it implode($name[$i]) or impode($name) You use the first one in your code which implies name is [['foo','bar'], [...]] not ['foo','bar', ...] If it's the second your also storing it multiple times which you probably don't want.
So you may be able to do just this:
//$_POST['name'] = ['foo','bar', ...]
//remove the loop
//we can assign $name in the if condition and save a line or 2
//the second part, the assignment, will always return true.
if (!empty($_POST['name']) && $name = $_POST['name']) {
$test= '['.implode(',', (array)$name).']'; //changed mainly this line
print_r($test);
$sql = "INSERT INTO employee_table (name) VALUES ('$test')";
if ($conn->query($sql) === true) {
echo 'ok';
}
}
With no loop, because when you loop over the count of names, your inserting the same data each time, up to the number of items in the names variable.
Explaining your code
So with my example data $_POST['name'] = ['foo','bar', ...] and a simplified version of your original code, you would be doing this:
Assuming you meant implode($name) and not implode($name[$i]) in your original code, which is the only sane thing if your data looks like my example data
//canned example data
$name = ['foo','bar'];
for ($i = 0; $i < count($name); $i++) {
if ($name[$i] != "") {
$test= implode(", ", (array)$name); //changed from $name[$i]
//just output this stuff so we can see the results
print_r($test);
echo "\nINSERT INTO employee_table (name) VALUES ('$test')\n";
}
}
Outputs:
foo, bar
INSERT INTO employee_table (name) VALUES ('foo, bar')
foo, bar
INSERT INTO employee_table (name) VALUES ('foo, bar')
Sandbox
If should be obvious but if you changed this line $test= implode(", ", (array)$name); to $test= '['.implode(',', (array)$name).']; in the above code the output would be this:
foo, bar
INSERT INTO employee_table (name) VALUES ('[foo,bar]')
foo, bar
INSERT INTO employee_table (name) VALUES ('[foo,bar]')
Which still saves it more then one time. So we need to dump that loop, which basically forces us into the code I put at the top of this update.
Hopefully that all makes sense.
Cheers

Try this code, in fact your $_POST['name'] store your value as an array, so you don't need to cast it.
$name = $_POST['name'];
for ($i = 0; $i < count($name); $i++) {
if ($name[$i] != "") {
$test= '['.implode(', ', $_POST['name']).']';
print_r($test);
$sql = "INSERT INTO employee_table (name)
VALUES ('$test')";
if ($conn->query($sql) === true) {
echo ('ok');
}
}
}
$conn->close();

Related

How to pass multiple variables in foreach php

I'd like to pass multiple variables in a foreach loop to add the value from $array_sma[] into my database. But so far I can only insert the value from $short_smas, while I'd also like to insert the values from $mid_smas. I have tried nested foreach but it's multiplying the values.
$period = array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
$sma = array(6,9);
foreach ($sma as $range) {
$sum = array_sum(array_slice($period, 0, $range));
$result = array($range - 1 => $sum / $range);
for ($i = $range, $n = count($period); $i != $n; ++$i) {
$result[$i] = $result[$i - 1] + ($period[$i] - $period[$i - $range]) / $range;
}
$array_sma[] = $result;
}
list($short_smas,$mid_smas)=$array_sma;
foreach ($short_smas as $short_sma) {
$sql = "INSERT INTO sma (short_sma)
VALUES ('$short_sma') ";
if ($con->query($sql) === TRUE) {
echo "New record created successfully<br><br>";
} else {
echo "Error: " . $sql . "<br>" . $con->error;
}
}
The code in my question works fine i.e. the value from the first sub array ($short_smas) of $array_sma[] gets inserted into the column short_sma of my msql database. The problem I have is when I try to insert the second sub array $mid_smas (see list()) from $array_sma[] in my second column of my database call mid_sma.
I think this is closed to what I want to achieve but still nothing gets inserted in the DB, source: php+mysql: insert a php array into mysql
I don't have any mysql syntax error.
$array_sma[] = $result;
$sql = "INSERT INTO sma (short_sma, mid_sma) VALUES ";
foreach ($array_sma as $item) {
$sql .= "('".$item[0]."','".$item[1]."'),";
}
$sql = rtrim($sql,",");
Main problem is that $short_smas and $mid_smas have different size. Moreover they are associative arrays so either you pick unique keys from both and will allow for empty values for keys that have only one value available or you pick only keys present in both arrays. Code below provides first solution.
// first lets pick unique keys from both arrays
$uniqe_keys = array_unique(array_merge(array_keys($short_smas), array_keys($mid_smas)));
// alternatively we can only pick those present in both
// $intersect_keys = array_intersect(array_keys($short_smas),array_keys($mid_smas));
// now lets build sql in loop as Marcelo Agimóvel sugested
// firs we need base command:
$sql = "INSERT INTO sma (short_sma, mid_sma) VALUES ";
// now we add value pairs to coma separated list of values to
// insert using keys from prepared keys array
foreach ($uniqe_keys as $key) {
$mid_sma = array_key_exists($key, $mid_smas)?$mid_smas[$key]:"";
$short_sma = array_key_exists($key, $short_smas)?$short_smas[$key]:"";
// here we build coma separated list of value pairs to insert
$sql .= "('$short_sma', '$mid_sma'),";
}
$sql = rtrim($sql, ",");
// with data provided in question $sql should have string:
// INSERT INTO sma (short_sma, mid_sma) VALUES, ('3.5', ''), ('4.5', ''), ('5.5', ''), ('6.5', '5'), ('7.5', '6'), ('8.5', '7'), ('9.5', '8'), ('10.5', '9'), ('11.5', '10'), ('12.5', '11')
// now we execute just one sql command
if ($con->query($sql) === TRUE) {
echo "New records created successfully<br><br>";
} else {
echo "Error: " . $sql . "<br>" . $con->error;
}
// don't forget to close connection
Marcelo Agimóvel also suggested that instead of multiple inserts like this:
INSERT INTO tbl_name (a,b,c) VALUES (1,2,3);
its better to use single:
INSERT INTO tbl_name
(a,b,c)
VALUES
(1,2,3),
(4,5,6),
(7,8,9);
That's why I append value pairs to $sql in foreach loop and execute query outside loop.
Also its worth mentioning that instead of executing straight sql its better to use prepared statements as they are less prone to sql injection.

PHP Dynamic insert function is inserting duplicate rows

I have created a function that inserts data into MYSQL database dynamically to avoid code repetition just like so :
function insert($table, $data)
{
// connection
global $db;
if(!is_array($data)) die("Error : second parameter must be an array of keys and values");
$keys = array_keys($data);
$values = array_values($data);
// sql query
$sql = "INSERT INTO `$table` (";
// if more than one column
if(count($data) > 1)
{
for($i = 0; $i < count($data) -1; $i++)
{
$sql .= "`$keys[$i]`, ";
}
$sql .= "`" . end($keys) . "`) VALUES (";
for($i = 0; $i < count($data) -1; $i++)
{
$sql .= ":$keys[$i], ";
}
$sql .=":" . end($keys) . ")";
}else{ // only one column
$sql .= "`$keys[0]`) VALUES(:$keys[0])";
}
// make keys as named placeholders
$binds = array_map(function($elem){
return ":".$elem;
}, $keys);
// combine placeholders with values
$binds = array_combine($binds, $values);
$stmt = $db->prepare($sql);
return $stmt->execute($binds) ? true : false;
}
So Later on i can insert data just like that :
echo insert("users",[
"Name" => "Timino",
"Email" => "admin#timino.io"
]); // result 1 inserted or 0 failed
However its inserting duplicate rows ??
when i debug the code everything looks okay
echo $sql; //INSERT INTO `users` (`Name`, `Email`) VALUES (:Name, :Email)
print_r($binds) // Array
(
[:Name] => Timino
[:Email] => admin#timino.io
)
What am i doing wrong ?
Note : i have updated the code to procedural to make it easy for everyone who one to test it quickly !
Are you executing this code in your index.php?
echo $db->insert("users",[
"Name" => "Timino",
"Email" => "admin#timino.io"
]); // result 1 inserted or 0 failed
It might not be a code issue.
I had a similar issue where I was testing the insert in my index.php, and I had a rule in my .htaccess that would redirect not found files to index.php. And when the browser tries to locate your favicon, it's redirected to the index.php which will execute the code once again.
If that's the case, you can try moving your code into another file test.php and call your domain with http://localhost/test.php and check if it's still duplicating.

Insert NULL values on DB (method)

UPDATE----
Afer using this method:
foreach($_POST as $k => $v) {
$params[] = empty($v)? "NULL":$v;
}
$params_string_values = "'" . implode("','",$params) . "'";
$param_name_list = "tu_id,tu_status,tu_name,tu_fk_tt_id,tu_mon_1_s,tu_mon_1_e,tu_mon_2_s,tu_mon_2_e,tu_mon_3_s,tu_mon_3_e,tu_tue_1_s,tu_tue_1_e,tu_tue_2_s,tu_tue_2_e,tu_tue_3_s,tu_tue_3_e,tu_wed_1_s,tu_wed_1_e,tu_wed_2_s,tu_wed_2_e,tu_wed_3_s,tu_wed_3_e,tu_thu_1_s,tu_thu_1_e,tu_thu_2_s,tu_thu_2_e,tu_thu_3_s,tu_thu_3_e,tu_fri_1_s,tu_fri_1_e,tu_fri_2_s,tu_fri_2_e,tu_fri_3_s,tu_fri_3_e,tu_sat_1_s,tu_sat_1_e,tu_sat_2_s,tu_sat_2_e,tu_sat_3_s,tu_sat_3_e,tu_sun_1_s,tu_sun_1_e,tu_sun_2_s,tu_sun_2_e,tu_sun_3_s,tu_sun_3_e";
$param_values = "'','1',{$params_string_values}";
$insert_query = mysql_query("INSERT into turn_conf( {$param_name_list} ) values ({$param_values})");
It creates a valid query as it seems (here I paste it), but no NULL value is stored on databse, all NULL values go to database as "00:00":
INSERT into turn_conf( tu_id,tu_status,tu_name,tu_fk_tt_id,tu_mon_1_s,tu_mon_1_e,tu_mon_2_s,tu_mon_2_e,tu_mon_3_s,tu_mon_3_e,tu_tue_1_s,tu_tue_1_e,tu_tue_2_s,tu_tue_2_e,tu_tue_3_s,tu_tue_3_e,tu_wed_1_s,tu_wed_1_e,tu_wed_2_s,tu_wed_2_e,tu_wed_3_s,tu_wed_3_e,tu_thu_1_s,tu_thu_1_e,tu_thu_2_s,tu_thu_2_e,tu_thu_3_s,tu_thu_3_e,tu_fri_1_s,tu_fri_1_e,tu_fri_2_s,tu_fri_2_e,tu_fri_3_s,tu_fri_3_e,tu_sat_1_s,tu_sat_1_e,tu_sat_2_s,tu_sat_2_e,tu_sat_3_s,tu_sat_3_e,tu_sun_1_s,tu_sun_1_e,tu_sun_2_s,tu_sun_2_e,tu_sun_3_s,tu_sun_3_e ) values ('','1','12345555','1','10:00','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL','NULL')
This is what it records on DB:
I have this query, in which sometimes variables '$va1', '$val2' and '$val3' will have no value:
$insert = mysql_query("INSERT INTO turn_conf (tu_id,value1,value2,value3) VALUES ('','$va1','$val2','$val3')") or die (mysql_error());
In case any of these variables have no value stored, anything related to it must be sent to the DB (in order to store a NULL value on DB), for exampe if only '$val1' stores info, the final query must be:
$insert = mysql_query("INSERT INTO turn_conf (tu_id,value1) VALUES ('','$va1')") or die (mysql_error());
To solve this I have created an structure for each variable, checking wether it stores something or not, and in case it doesn't, just declarating nothing and sending nothing:
if ($_POST['value1'] == ""){
$val1_p = "";
$val1_s = "";
}else {
$val1_p = ",value1";
$val1_sv = $_POST['value1'];
$val1_s = ", '$val1_sv'" ;}
if ($_POST['value2'] == ""){
$val2_p = "";
$val2_s = "";
}else {
$val2_p = ",value2";
$val2_sv = $_POST['value2'];
$val2_s = ", '$val2_sv'" ;}
if ($_POST['value3'] == ""){
$val3_p = "";
$val3_s = "";
}else {
$val3_p = ",value3";
$val3_sv = $_POST['value3'];
$val3_s = ", '$val3_sv'" ;}
and:
$insert = mysql_query("INSERT INTO turn_conf (tu_id $val1_p $val2_p $val3_p) VALUES ('' $val1_s $val2_s $val3_s)") or die (mysql_error());
This works, and creates the right query, but id like to know if you find ths method proper, or if it would be better to choose another more efficient one. Please not in this example I used only 3 variables, but this query on real has 43 variables, I make this question due to the amount of data.
$insert = mysql_query("INSERT INTO turn_conf (tu_id,value1,value2,value3) VALUES ('','".((isset($va1))?"'".$va1."'":"NULL")."','".((isset($va2))?"'".$va2."'":"NULL")."','".((isset($va3))?"'".$va3."'":"NULL")."')") or die (mysql_error());
Basically you want to test if the value is set. We use the short if-notation for this:
isset($va1)?"'".$va1."'":"NULL"
If $va1 is set (has a value), we will put "'value'" in the query, otherwise "NULL" for an empty value.
If you want to test on an empty string too:
(isset($va1) && $va1 != '')?"'".$va1."'":"NULL"
If you don't use prepared statement Try this:
foreach($_POST as $k => $v) {
$params[] = empty($v)? "NULL":$v;
}
mysql_query("insert into turn_conf(field1,field2...) values(" . implode(",",$params). ");
If you use prepared statement (better!) try something like this:
foreach($_POST as $v) {
$params[] = $v;
}
$sth = $dbh->prepare("INSERT INTO turn_conf (tu_id $val1_p $val2_p $val3_p) VALUES (?,?,?)");
$sth->execute($params);
So simple!
PS: This is an example but doesn't use directly $_POST value, filter it before (http://www.php.net/manual/en/function.filter-input.php, and http://www.php.net/manual/en/filter.filters.sanitize.php). example:
$field_int= filter_input(INPUT_POST, 'field1', FILTER_SANITIZE_NUMBER_INT);
UPDATE
you use this code:
$insert = mysql_query("INSERT into turn_conf(tu_id,tu_name,tu_status,tu_fk_tt_id,tu_mon_1_s,tu_mon_1_e,tu_mon_2_s,t‌​u_mon_2_e,tu_mon_3_s,tu_mon_3_e,tu_tue_1_s,tu_tue_1_e,tu_tue_2_s,tu_tue_2_e,tu_tu‌​e_3_s,tu_tue_3_e,tu_wed_1_s,tu_wed_1_e,tu_wed_2_s,tu_wed_2_e,tu_wed_3_s,tu_wed_3_‌​e,tu_thu_1_s,tu_thu_1_e,tu_thu_2_s,tu_thu_2_e,tu_thu_3_s,tu_thu_3_e,tu_fri_1_s,tu‌​_fri_1_e,tu_fri_2_s,tu_fri_2_e,tu_fri_3_s,tu_fri_3_e,tu_sat_1_s,tu_sat_1_e,tu_sat‌​_2_s,tu_sat_2_e,tu_sat_3_s,tu_sat_3_e,tu_sun_1_s) values('','$newTurnName','1','$newTurnType'," . implode(",",$params). "))")
but change it like this:
$params_string_values = "'" . implode("','",$params) . "'";
$param_name_list = "tu_id,tu_name,tu_status,tu_fk_tt_id,tu_mon_1_s,tu_mon_1_e,tu_mon_2_s,t‌​u_mon_2_e,tu_mon_3_s,tu_mon_3_e,tu_tue_1_s,tu_tue_1_e,tu_tue_2_s,tu_tue_2_e,tu_tu‌​e_3_s,tu_tue_3_e,tu_wed_1_s,tu_wed_1_e,tu_wed_2_s,tu_wed_2_e,tu_wed_3_s,tu_wed_3_‌​e,tu_thu_1_s,tu_thu_1_e,tu_thu_2_s,tu_thu_2_e,tu_thu_3_s,tu_thu_3_e,tu_fri_1_s,tu‌​_fri_1_e,tu_fri_2_s,tu_fri_2_e,tu_fri_3_s,tu_fri_3_e,tu_sat_1_s,tu_sat_1_e,tu_sat‌​_2_s,tu_sat_2_e,tu_sat_3_s,tu_sat_3_e,tu_sun_1_s";
$param_values = "'','{$newTurnName}','1','{$newTurnType}',{$param_string_values}";
$insert_query = mysql_query("INSERT into turn_conf( {$param_name_list} ) values ({$param_values})");

How to get a loop query into one query in php

I got something like this.
It's working, but have to do a mysql query like 40 times is not the best thing.
Can somebody help me get it in to one query?
$string_unique = 'Unique string';
$number = count($something);
for ($i=0; $i < $number; $i++)
{
if(!empty($some_input)) {
$string_one = 'Something_one' . $i;
$string_two = 'Something_two' . $i;
mysql_query("INSERT INTO `table` (`unique_string`, `string_one`, `string_two`) VALUES('$unique_string', '$string_one', '$string_two') ON DUPLICATE KEY UPDATE `string_one` = '$string_one', `string_two` = '$string_two'") or die(mysql_error());
} else {
$string_one = '';
$string_two = '';
mysql_query("INSERT INTO `table` (`unique_string`, `string_one`, `string_two`) VALUES('$unique_string', '$string_one', '$string_two') ON DUPLICATE KEY UPDATE `string_one` = '$string_one', `string_two` = '$string_two'") or die(mysql_error());
}
You can generate a single query in that loop and then execute it only once:
$query = 'INSERT INTO `table` (`unique_string`, `string_one`, `string_two`) VALUES ';
$queryValues = array();
$string_unique = 'Unique string';
$number = count($something);
for ($i=0; $i < $number; $i++)
{
if(!empty($some_input)) {
$string_one = 'Something_one' . $i;
$string_two = 'Something_two' . $i;
$queryValues[] = sprintf('("%s", "%s", "%s")', $unique_string, $string_one, $string_two);
} else {
// I can't understand what are you using this part for... Anyway.
$queryValues[] = sprintf('("%s", "", "")', $unique_string);
}
}
$query .= implode(', ', $queryValues);
// And here is the unique key updating.
// I don't know whole the structure, so I just guess you have the PRIMARY `id` row
// What you did in your ON DUPLICATE KEY was unnecessary.
$query .= ' ON DUPLICATE KEY UPDATE `id`=`id`';
// Don't use mysql_* functions in new code.
// See: http://stackoverflow.com/questions/12859942/why-shouldnt-i-use-mysql-functions-in-php
mysql_query($query);
You're a allowed to add multiple rows of data in an insert statement in MySQL. That way, you can build one big insert statement in the loop, and execute it in one go after the loop. That is way faster and much more efficient.
You can insert multi row with sql,
here an example
insert into table1 (First,Last) values ("Fred","Smith"),
("John","Smith"),
("Michael","Smith"),
("Robert","Smith");

MySQL INSERT - Using a for() loop with query & do non-set values insert as "" by default?

I have two arrays with anywhere from 1 to 5 set values. I want to insert these values into a table with two columns.
Here's my current query, given to me in another SO question:
INSERT INTO table_name (country, redirect)
VALUES ('$country[1]', '$redirect[1]'),
('$country[2]', '$redirect[2]'),
('$country[3]', '$redirect[3]'),
('$country[4]', '$redirect[4]'),
('$country[5]', '$redirect[5]')
ON DUPLICATE KEY UPDATE redirect=VALUES(redirect)
I'm a little concerned however with what happens if some of these array values aren't set, as I believe the above assumes there's 5 sets of values (10 values in total), which definitely isn't certain. If a value is null/0 does it automatically skip it?
Would something like this work better, would it be a lot more taxing on resources?
for($i = 0, $size = $sizeof($country); $i <= size; $i++) {
$query = "INSERT INTO table_name (country, redirect) VALUES ('$country[$i]', '$redirect[$i]) ON DUPLICATE KEY UPDATE redirect='$redirect[$i]'";
$result = mysql_query($query);
}
Questions highlighted in bold ;). Any answers would be very much appreciated :) :)!!
Do something like this:
$vals = array()
foreach($country as $key => $country_val) {
if (empty($country_val) || empty($redirect[$key])) {
continue;
}
$vals[] = "('" . mysql_real_escape_string($country_val) . "','" . mysql_real_escape_string($redirect[$key]) . "')";
}
$val_string = implode(',', $vals);
$sql = "INSERT INTO .... VALUES $val_string";
That'll built up the values section dynamically, skipping any that aren't set. Note, however, that there is a length limit to mysql query strings, set by the max_allowed_packet setting. If you're building a "huge" query, you'll have to split it into multiple smaller ones if it exceeds this limit.
If you are asking whether php will automatically skip inserting your values into the query if it is null or 0, the answer is no. Why dont you loop through the countries, if they have a matching redirect then include that portion of the insert statement.. something like this: (not tested, just showing an example). It's one query, all values. You can also incorporate some checking or default to null if they do not exist.
$query = "INSERT INTO table_name (country, redirect) VALUES ";
for($i = 0, $size = $sizeof($country); $i <= size; $i++) {
if(array_key_exists($i, $country && array_key_exists($i, $redirect)
if($i + 1 != $size){
$query .= "('".$country[$i]."', '".$redirect[$i]).",";
} else $query .= "('".$country[$i]."', '".$redirect[$i].")";
}
}
$query .= " ON DUPLICATE KEY UPDATE redirect=VALUES(redirect);"
$result = mysql_query($query);

Categories