Inserting data into MySQL db using PHP - php

I am passing an array to a query. However, I can't seem to add each value `.
The array Im passing is:
Array (
[name] => Name
[address_1] => Address 1
[address_2] => Address 2
[address_3] => Address 3
[address_4] => Address 4
[post_code] => Post COde
[proptype] => rent
[style] => house
[beds] => 1
[bathrooms] => 1
[garden] => 1
[furnished] => yes
[deposit] => Deposit
[available] => 10/18/2013
[description] => Description
)
Below is my code:
foreach ($data as $column => $value) {
$columns .= ($columns == "") ? "" : ", ";
$columns .= $column;
$values .= ($values == "") ? "" : ", ";
$values .= $value;
}
$sql = "INSERT INTO $table ($columns) VALUES ($values)";
echo "--->" . $sql;
exit;
I know I need to enclose each value but I can't see where I need to do this.
Thanks for your time.

Try:
foreach ($data as $column => $value) {
$columns .= ($columns == "") ? "" : ", ";
$columns .= $column;
$values .= ($values == "") ? "" : ", ";
$values .= "'" . $value . "'";
}

You could also to use a few built-in php functions:
// join column names with a comma
$columns = join(array_keys($data),',');
// pass every value through mysql-escape and join the values with quotes and commas
$values = join(array_map("mysql_real_escape_string",array_values($data)),'","');
// use the produced strings; make sure you wrap the values string with double quotes
$sql = "INSERT INTO $table ($columns) VALUES (\"$values\")";
For reference:
array_keys,
array_values,
array_map, mysql_real_escape_string, join
I am using mysql_real_escape_string for security reasons.

Related

PHP convert columns to query

I have a table on the frontend, where the user can choose what types of columns he wants.
After submitting the form I get the array with selected columns.
For instance the user select following columns:
$columns = ["campaign_start_time", "campiagn_end_time", "campaign_id", "campaign_budget", "adset_name", "ad_name"]
Now I have to make the request to the facebook api, but facebook api only request query in form:
$query = "campaign{start_time, end_time, id, budget}, adset{name}, ad{name}"
Here is my question, what is the best way to convert $columns to $query in PHP language?
If you can construct your submitted data to be in this form:
Array
(
[campaign] => Array
(
[0] => start_time
[1] => end_time
[2] => id
[3] => budget
)
[adset] => Array
(
[0] => name
)
[ad] => Array
(
[0] => name
)
)
Maybe using inputs or other constructs such as:
name="campaign[]" value="start_time"
name="campaign[]" value="end_time"
Then looping and building the query with the keys and values will do it:
foreach($columns as $key => $val) {
$query[] = $key . '{' . implode(',', $val) . '}';
}
$query = implode(',', $query);
Otherwise you'll need to parse it to get what you need first, then execute the loop above using $result instead:
foreach($columns as $val) {
preg_match('/^([^_]+)_(.*)/', $val, $match);
$result[$match[1]][] = $match[2];
}
This solution splits apart the values based on underscores and then joins them back together as nested values based on the category/key. Note that this doesn't check for items that don't have a "prefix".
<?php
$columns = ["campaign_start_time", "campaign_end_time", "campaign_id", "campaign_budget", "adset_name", "ad_name"];
$criteria = [];
foreach( $columns as $column ){
$pieces = explode('_',$column);
$category = array_shift($pieces);
if( !isset($criteria[$category]) ){
$criteria[$category] = [];
}
$criteria[$category][] = implode('_', $pieces);
}
$queryPieces = [];
foreach($criteria as $category => $values){
$queryPieces[] = $category.'{'.implode(', ', $values).'}';
}
$query = implode(', ', $queryPieces);

Loop through array in bind parameters - prepared statement

I am writing a function in which I can do a couple of database actions, in this case an insert data based on a simple array
"insert" => array (
"1" => array (
"tnt_role" => array (
"rolename" => array (
"value" => "administrator",
"notation" => "string"
)
)
),
"2" => array (
"tnt_role" => array (
"rolename" => array (
"value" => "user",
"notation" => "string"
)
)
),
"3" => array (
"tnt_users" => array (
"username" => array (
"value" => "administrator",
"notation" => "string"
),
"userpassword" => array (
"value" => md5('admin', FALSE),
"notation" => "string"
),
"email" => array (
"value" => "someone#something.com",
"notation" => "string"
),
"roleid" => array (
"value" => "1",
"notation" => "int"
)
)
)
)
and here is the specific part of the function
case "insert":
foreach ($tables as $instance => $inserttables) {
foreach ($inserttables as $table => $fields) {
// create a count on the number of fields that are being parsed
$countfields = count($fields);
$sql = "INSERT INTO ". $table ." (" ;
$i = 0;
// set up the columns for the insert statement
foreach ($fields as $field => $value) {
$i++;
$sql .= $field;
if ($countfields != $i ) {
$sql .= ", ";
}
}
// close the column statement, open the value statement, since this is prepared, we will add question marks and add later the values
$sql .= ") ";
$sql .= "VALUES (";
$i = 0;
$parameters = "";
$notation = "";
foreach ($fields as $field => $value) {
$i++;
$sql .= "?";
// set up the notation in the bind parameters
switch($value['notation']) {
case "int":
$notation .= "i";
break;
case "string":
$notation .= "s" ;
break;
}
// need to escape the email and username values
$parameters .= "'".$value['value']."'" ;
if ($countfields != $i ) {
$sql .= ", ";
$parameters .= ", ";
}
}
$sql .= ")";
$stmt = mysqli_prepare($con, $sql);
mysqli_stmt_bind_param($stmt, $notation, $parameters);
if(mysqli_stmt_execute($stmt)) {
echo "data entered";
} else {
echo "error in following query:". $sql;
}
}
}
break;
This works all fine except for 1 tiny thing and that is when I enter more than 1 item in the database. It gives me the following error
mysqli_stmt_bind_param(): Number of elements in type definition string
doesn't match number of bind variables in .... line 647
I realized after a while that it is the parameter variable that is the case. The bind parameter here is only 1 variable in which I separate it all nicely with a comma (in order to mimic the list). Viewing this optical would say this looks fine, however I think the bind parameter statement really requires separate variables. At this point it sees actually just one variable, rather than the 4 in my test case.
I tried looping it this way:
mysqli_stmt_bind_param($stmt, $notation,
foreach ($fields as $field => $value) {
echo $value['value'];
if ($countfields != $i ) {
echo ",";
}
}
);
But to no avail, since it will spit out the following.
Parse error: syntax error, unexpected 'foreach' (T_FOREACH) in
Does anybody have an idea how to solve this issue?
== edit ==
table structure as requested, although I doubt it is that problem, since I get a bind parameter error, not an error in executing the statement.
== edit 2 ==
also tried the following, which didn't help, since it didn't stack (I saw this in PDO)
foreach ($fields as $field => $value) {
switch($value['notation']) {
case "int":
$notation = "i";
break;
case "string":
$notation = "s" ;
break;
}
mysqli_stmt_bind_param($stmt, $notation, $value['value']);
}
You need to pass each variable individually to mysqli_stmt_bind_param, so $parameters needs to be an array, not a string. Change the following lines of code:
$parameters = "";
to:
$parameters = array();
and
$parameters .= "'".$value['value']."'" ;
to:
$parameters[] = $value['value'];
(note there is no need to escape values when you are using prepared statements)
remove this line:
$parameters .= ", ";
and finally, change
mysqli_stmt_bind_param($stmt, $notation, $parameters);
to:
mysqli_stmt_bind_param($stmt, $notation, ...$parameters);
and it should work fine.

how to convert base10 number into an array with PHP

The meaning is : How to store in a single database field, multiple value as, for example, Optin data.
In order to do that, i've to know how to code and decode the value.
I've an array with different optin values:
$optin = array (
'1' => 'SMS',
'2' => 'Email',
'4' => 'Mail',
'8' => 'AppsPushNotif',
'16' => 'Partners',
'32' => 'Gaming Partners'
);
ie.: I'll store,in optin field :
- '7' if the user is opt-in for SMS,Email and Mail (4+2+1)
or
- '40' for AppsPushNotif and Gaming_Partners
I would like found a way to decode 7 or 40 values into an array with optin's arrays values.
Many thanks
PS: Thanks to Cyclone for the solution :
$output = '';
$value = 40;
$keys = array_keys($food);
foreach($keys as $key) {
if($value & $key) $output .= $food[$key].',';
}
print rtrim($output, ',');
A solution in one line to unpack $value into individual values that appear as keys in $optin:
$value = 40;
$keys = array_map(
function($i) { return 1 << $i; },
array_keys(array_filter(str_split(strrev(decbin($value)))))
);
print_r($keys);
The output is:
Array
(
[0] => 8
[1] => 32
)
This should work:
$output = '';
$value = 40;
$keys = array_keys($food);
foreach($keys as $key) {
if($value & $key)
$output .= $food[$key].',';
}
print rtrim($output, ',');

Array to DB insert PHP MYSQL

I have a check box which takes some values and the below one is the post value which I get from my matrix form. Now the array value which I have below should be formated as like this
Post values:
Array (
[31_1] => on
[31_2] => on
[31_3] => on
[56_2] => on
[56_4] => on
[66_1] => on
[66_3] => on
)
Expected value:
31=>1,2,3
56=>2,4
66=>1,3
I will be happy if I am able to store the values in a database table (author_book) like this:
S.No Author_ID Book_IDs
1 31 1,2,3
2 56 2,4
3 66 1,3
In short, the post values should be stored in DB tables for me to proceed further. How can I achieve this?
This code would construct the queries for you, remember to use some data injection prevention mechanism
<?php
$x = array (
"31_1" => "on",
"31_2" => "on",
"31_3" => "on",
"56_2" => "on",
"56_4" => "on",
"66_1" => "on",
"66_3" => "on"
);
$newarray = array();
foreach($x as $key => $val){
$key = explode("_", $key);
$newkey = $key[0];
$newval = $key[1];
$newarray[$newkey][] = $newval;
}
foreach($newarray as $key => $val){
$query = "INSERT INTO (Author_ID, Book_IDs) VALUES (" . $key . ",'" . join(',', $val) . "')";
echo $query . "<br />";
}
foreach($array_name as $key=> $value)
{
$var1=$key;
$var2=$value;
// here you can have your db statements to insert the values
}
Here you go. There might be a shorter way of doing it too:
<?php
$array = array (
'31_1' => 'on',
'31_2' => 'on',
'31_3' => 'on',
'56_2' => 'on',
'56_4' => 'on',
'66_1' => 'on',
'66_3' => 'on',
);
$new_array = array();
foreach($array as $ind=>$val){
//breaks string at '_' and gets 31 and 1 separately
$key_val = explode('_',$ind);
if(array_key_exists($key_val[0],$new_array)){
//this is to append if key exists, eg. 31 => 1,2,3
$new_array[$key_val[0]] = $new_array[$key_val[0]].",".$key_val[1];
}
else
{
$val = $key_val[1];
$new_array[$key_val[0]] = $val;
}
}
print_r($new_array);
?>
Fiddle
I believe you only wanted to insert values for author_id whose is set to ON
unset all the index set to OFF
Try something similar:
$books=array();
foreach($array_name as $key=> $value){
if($value==='on'){
//prepare the array
list($author_id,$books[$author_id][])=explode("_",$key)
}
}
foreach($temp as $k=>$v){
$q->query("INSERT INTO author_book(author_id,books_id) VALUES($k,".implode(',',$v)));
}
Thanks
and keep asking questions :)

Algorithm to dynamically merge arrays [duplicate]

This question already has answers here:
Two arrays in foreach loop
(24 answers)
Closed 6 months ago.
I'm trying to create a INSERT statement for every row in a PHPExcel object. As I've struggled to iterate across the column (ie. go B1 C1 D1, get the values, and put them into an array), I've opted to get all the values for each column and put them into a multi-dimensional array that looks like this:
Array
(
[foo] => Array
(
[0] => 250
[1] => 247
[2] => 279
[3] => 249
)
[bar] => Array
(
[0] => AM PROV
[1] => AM PROV
[2] => AM PENS
[3] => AM PROV
)
[schoo] => Array
(
[0] => xxxx
[1] => yyy
[2] => zzz
[3] => aaa
)
)
I want to merge each of the arrays so that all the data at index 0 is in one array, etc. I've built a generic tool to allow you to select the columns you want from an uploaded spreadsheet. It needs to first merge the column data into a single array and then it should generate INSERT statements for each of the arrays. So the final deliverable is this:
INSERT INTO (foo, bar, schoo) VALUES (250, "AM PROV", "xxxx");
All help appreciated.
UPDATE: Hey all, thank you very much for your answers. I finally managed to get it working using row and cell iterators as per Mark's suggestion and it's working. I have a separate issue with it now, but I think it's something I can solve. Thanks again.
<?php
$uberArray = array(
"foo" => array(
0 => 250,
1 => 247,
2 => 279,
3 => 249,
),
"bar" => array(
0 => "AM PROV",
1 => "AM PROV",
2 => "AM PENS",
3 => "AM PROV",
),
"schoo" => array(
0 => "xxxx",
1 => "yyy",
2 => "zzz",
3 => "aaa",
)
);
$yourMysqlLink = mysql_connect('localhost', 'user', 'pass');
mysql_query('SET NAMES utf8'); // Adjust according to your encoding
$colNames = array_keys($uberArray);
$stringCols = array('bar', 'schoo');
$sqlInsertStr = 'INSERT INTO `your_table` (`'.implode('`, `', $colNames)."`) VALUES \n";
$rows = array();
// Not really for iterating the first array, we just need a loop
foreach ($uberArray[$colNames[0]] as $k => $v) {
$vals = array();
foreach ($colNames as $v2) {
$val = $uberArray[$v2][$k];
if (in_array($v2, $stringCols)) {
$val = "'".mysql_real_escape_string($val, $yourMysqlLink)."'";
}
$vals[] = $val;
}
$rows[] = "\t(".implode(', ', $vals).")";
}
$sqlInsertStr .= implode(",\n", $rows).';';
echo '<pre style="clear:both;">'.$sqlInsertStr.'</pre>'; ;
Note that you may need to do a few adjustments for performance reasons, if $uberArray is big (e.g. splitting the insert string into chunks). Or you can convert the data to CSV and use MySQL LOAD DATA INFILE method, which is real fast.
Not sure if this is what you were after but...
<?php
# Given this array
$arrays = array(
'foo' => array(
0 => 250,
1 => 247,
2 => 279,
3 => 249
),
'bar' => array(
0 => 'AM PROV',
1 => 'AM PROV',
2 => 'AM PENS',
3 => 'AM PROV'
),
'schoo' => array(
0 => 'xxxx',
1 => 'yyy',
2 => 'zzz',
3 => 'aaa'
)
);
# This code generates...
$fields = array();
$inserts = array();
foreach ($arrays as $k => $v) {
$fields[] = $k;
}
for ($i = 0; $i < count($arrays[$fields[0]]); $i++) {
$vals = array();
foreach ($fields as $field) {
$vals[] = $arrays[$field][$i];
}
$inserts[] = 'INSERT INTO (' . implode(',', $fields) . ') VALUES ("' . implode('","', $vals) . '")';
}
# This array
/* $inserts = array(
'INSERT INTO (foo, bar, schoo) VALUES ("250", "AM PROV", "xxxx")',
'INSERT INTO (foo, bar, schoo) VALUES ("247", "AM PROV", "yyy")',
'INSERT INTO (foo, bar, schoo) VALUES ("279", "AM PENS", "zzz")',
'INSERT INTO (foo, bar, schoo) VALUES ("249", "AM PROV", "aaa")'
); */
var_dump($inserts);
Edit: Though I think you're missing a table name from your INSERT statements.
Edit2: You could shorten the code using array_keys like Frosty Z does and skip the first foreach.
$inputArray = array('a' => array(1, 2, 3), 'b' => array("X'", 'Y', 'Z'));
$finalArray = array();
// build array with appropriate data rows
$finalIndex = 0;
foreach($inputArray as $key => $row)
{
foreach($row as $value)
$finalArray[$finalIndex][] = $value;
$finalIndex++;
}
// format it as SQL insert queries
$fields = array_keys($inputArray);
foreach($finalArray as $row)
{
echo "INSERT INTO table (".implode(", ", $fields).") "
. " VALUES (".implode(", ", array_map("format_data", $row)).");\n";
}
function format_data($value)
{
// assuming you're using MySQL. Replace the escape function by
// the appropriate one
if (is_string($value))
return "'".mysql_real_escape_string($value)."'";
else
return $value;
}
You can use one of those strange spl iterators for this :)
$iter = new MultipleIterator(MultipleIterator::MIT_KEYS_ASSOC);
foreach ($uberArray as $colName => $colValues) {
$iter->attachIterator(new ArrayIterator($colValues), $colName);
}
foreach ($iter as $vals) {
print_r($vals);
//or $pdoStmt->execute($vals);
}
But really, a simple for loop is the tool to use here.
I see no reason to merge the array unless you feel like wasting memory. You've already probably made a copy of the data. This just inserts the data row by row.
$data = array('foo' => array(...), ... );
$fields = array('foo', 'bar', 'schoo');
$c = count($data[$fields[0]));
$base_sql = 'INSERT INTO tbl ('.implode(',', $fields).') VALUES ';
for ($i = 0; $i < $c; ++$i)
{
$row_data = array();
foreach ($fields as $field)
$row_data[] = "'".escape_func($data[$field][$i])."'";
$sql = $base_sql . '(' . implode(',', $row_data). ')';
db_query($sql);
}
I would actually use prepared statements.
And you really should try to figure out how to iterate through the original dataset in one pass.

Categories