Inserting multiple $_Post arrays into a database - php

how can I add $_POST['wmeet'] into the auto INSERT or should I do a separate UPDATE. I want all 6 $_POST['wmeet'] values to go into m_wmeet in format "ce1 sf1 sm1" a single space in between each value
if (is_array($_POST['add']))
foreach ($_POST['add'] as $key => $value)
$_POST['add'][$key] = mysql_real_escape_string(stripslashes($value));
if (is_array($_POST['wmeet']))
foreach ($_POST['wmeet'] as $key => $value)
$_POST['wmeet'][$key] = mysql_real_escape_string(stripslashes($value));
function dbSet($fields, $source = array()) {
$set='';
if (!source) $source = &$_POST;
foreach ($fields as $field) {
if (isset($source[$field])) {
$set.="`$field`='".mysql_real_escape_string($source[$field])."', ";
}
}
return substr($set, 0, -2);
}
$fields = explode(" ", "m_user m_pass m_email m_date m_ip m_type m_country m_place");
$query_mem = "INSERT INTO social_members SET ".dbSet($fields, $_POST['add']);
mysql_query($query_mem);

One way to try to take advantage of similar syntax between INSERT and UPDATE is to use the implode method mentioned by #KristerAndersson combined with REPLACE INTO. You'll have to have a primary key that is part of your insert or else a unique key for this to work. Since REPLACE INTO shares the same column syntax as INSERT INTO you can just use it and get your UPDATES along with your INSERTS. Keep in mind that REPLACE INTO deletes the old row and inserts a new one so the record key will change.

Try something like this:
if (is_array($_POST['add']))
foreach ($_POST['add'] as $key => $value)
$_POST['add'][$key] = mysql_real_escape_string(stripslashes($value));
if (is_array($_POST['wmeet']))
$_POST['add']['m_wmeet'] = mysql_real_escape_string(stripslashes(implode(' ',$_POST['wmeet'])));
function dbSet($fields, $source = array()) {
$set='';
if (!source) $source = &$_POST;
foreach ($fields as $field) {
if (isset($source[$field])) {
$set.="`$field`='".mysql_real_escape_string($source[$field])."', ";
}
}
return substr($set, 0, -2);
}
$fields = explode(" ", "m_user m_pass m_email m_date m_ip m_type m_country m_place m_wmeet");
$query_mem = "INSERT INTO social_members SET ".dbSet($fields, $_POST['add']);
mysql_query($query_mem);

this is what i've put together from the comments/answers ... which one would work?
if (is_array($_POST['wmeet']))
foreach ($_POST['wmeet'] as $key => $value)
$_POST['wmeet'][$key] = mysql_real_escape_string(stripslashes($value));
$wmeet = implode(" ",$_POST['wmeet']);
or does it need to be something like
$_POST['wmeet'][$key] =
mysql_real_escape_string(stripslashes($value = implode(" ",$_POST['wmeet'])));
and then the insert code... would something like this work?
$query_mem = "INSERT INTO social_members
SET ".dbSet($fields, $_POST['add']. ", m_wmeet=".$wmeet);

Related

Multi input & multi column for each loop PHP

Currently taking all get request through foreach function. Looking if column called season contains them. Next step is adding 1 more column to check if any get request is LIKE any of the next column values. The second column has to be an AND and not and OR, which means if the first column season contains any of the get requests AND the second column contains any of the GET requests.
Currently:
$array_name = array();
foreach ($_GET as $key => $value) {
$array_name[] = "'%" . escape_string($value) . "%'";
};
$string = implode(' OR season LIKE ', $array_name);
$tank = "SELECT * FROM shrubs2 WHERE season LIKE {$string}";
echo $tank;
First edit:
function searchByColumn($values, $columnName) {
$string = implode(" OR $columnName LIKE ", $values);
return "SELECT * FROM shrubs2 WHERE $columnName LIKE $string";
}
$array_name = array();
foreach ($_GET as $key => $value) {
$array_name[] = "'%".escape_string($value)."%'";
}
$colNames = array("season", "日照"); // can add here more column names
foreach($colNames as $colName) {
$str = searchByColumn($array_name, $colName);
}
echo $str;
///// creating the query with the variable $str
You can define function to search for each column:
function searchByColumn($values, $columnName) {
$string = implode(" OR $columnName LIKE ", $values);
return "SELECT * FROM shrubs2 WHERE $columnName LIKE $string";
}
Then use it as:
$array_name = array();
foreach ($_GET as $key => $value) {
$array_name[] = "'%".escape_string($value)."%'";
}
$colNames = array("season"); // can add here more column names
foreach($colNames as $colName) {
$str = searchByColumn($array_name, $colName);
echo $str; // or run it
}

Updating via PDO and automatic function

I'm preparing my own function due to hurry the updates automatically.
I have that code:
$allowededitablefields = array('mail');
$userid = $_GET['uid'];
$query = 'UPDATE users SET ';
foreach ($_POST as $key => $value) {
if(!in_array($key,$allowededitablefields)) {
unset($_POST[$key]);
}
else {
$query .= $key.' = :'.$key.',';
}
}
$query = substr($query, 0, -1);
$query .= ' WHERE id='.$userid;
$statement = $this->_db->prepare($query);
foreach ($_POST as $key => $value) {
$statement->bindParam(':'.$key,$value);
}
$statement->execute();
If in $allowededitablefields array, I have only a value, it works properly, but if I push some values to the array, for example $allowededitablefields = array('mail','country',...); the fields in the table take the same values.
$value holds the value of the last iteration when the foreach loop ends.
change the bindParam to this.
$statement->bindParam(':'.$key,$_POST[$key]);
This should work, but your approach is fundamentally flawed. It undermines the whole purpose of prepared statements.

Nested foreach loops - anything more efficient?

So I've got nested foreach loops, and I'm wondering if there's a more efficient way to do this, code-wise:
foreach ($arraykey as $columnname => $value) {
foreach ($records as $field_entity_id) {
$fieldinsertloop = "('registration', 'reg_type', 0,".$field_entity_id.",".$field_entity_id.", 'und', 0,'".$value."','".$value."')";
}
$sql = "INSERT INTO " .str_replace("multi_reg", "field_data", $columnname);
$sql .= " (entity_type, bundle, deleted, revision_id, entity_id, language, delta, ".str_replace("multi_reg_", "", $columnname)."_value, ".str_replace("multi_reg_", "", $columnname)."_format)";
$sql .= " VALUES ";
$sql .= $fieldinsertloop;
db_query($sql);
}
Basically, I'm wanting to optimize for either speed and then less code written - in that order or optimally both.
You can squeeze a bit more performance from your loops by using the values by reference:
foreach ($arraykey as $columnname => &$value) {
Hence the &$value, but beware, every time you do something to $value after that, it will affect the original $arraykey[$columnname] value. Also, not sure you're nesting the foreach correctly. I would move the ending bracket for the nested foreach down:
// $value passed by reference
foreach ($arraykey as $columnname => &$value) {
// Pass $field_entity_id by reference
foreach ($records as &$field_entity_id) {
$fieldinsertloop = "('registration', 'reg_type', 0,".$field_entity_id.",".$field_entity_id.", 'und', 0,'".$value."','".$value."')";
$sql = "INSERT INTO " .str_replace("multi_reg", "field_data", $columnname);
$sql .= " (entity_type, bundle, deleted, revision_id, entity_id, language, delta, ".str_replace("multi_reg_", "", $columnname)."_value, ".str_replace("multi_reg_", "", $columnname)."_format)";
$sql .= " VALUES ";
$sql .= $fieldinsertloop;
db_query($sql);
} // End of nested foreach moved here
}
Another issue with your code, it appears you are using Drupal db_query() which has a much better way for inserting values. If you are, you could change your code to this:
foreach ($arraykey as $columnname => &$value) {
$table = str_replace("multi_reg", "field_data", $columnname);
$columns = array('entity_type', 'bundle', 'deleted', 'revision_id', 'entity_id', 'language', 'delta', str_replace("multi_reg_", "", $columnname).'_value', str_replace("multi_reg_", "", $columnname).'_format');
foreach ($records as &$field_entity_id) {
$values = array('registration', 'reg_type', 0, $field_entity_id, $field_entity_id, 'und', 0, $value, $value);
//Build Associative Array for Insert
for( $x = 0, $max = count($values); $x < $max; $x++ ) {
$sqlValues[$columns[$x]] = $values[$x];
}
db_insert($table)->fields($columns)->values($sqlValues)->execute();
}
}
OR
foreach ($arraykey as $columnname => &$value) {
$table = str_replace("multi_reg", "field_data", $columnname);
$columns = array('entity_type', 'bundle', 'deleted', 'revision_id', 'entity_id', 'language', 'delta', str_replace("multi_reg_", "", $columnname).'_value', str_replace("multi_reg_", "", $columnname).'_format');
$query = db_insert($table)->fields($columns);
foreach ($records as &$field_entity_id) {
$values = array('registration', 'reg_type', 0, $field_entity_id, $field_entity_id, 'und', 0, $value, $value);
//Build Associative Array for Insert
for( $x = 0, $max = count($values); $x < $max; $x++ ) {
$sqlValues[$columns[$x]] = $values[$x];
}
$query->values($sqlValues);
}
$query->execute();
}
The second example should be faster, but with more lines. It waits until all the values have been added before executing. Using db_insert() requires that the values be in an associative array, with the column names as keys.
How's that for clean?

MySql "WHERE" builder

I was thinking of implementing a function to "build" the WHERE clause in an SQL request like so:
"SELECT * FROM table $where"
Building $where with a cycle that would look like this:
$arr=array("Id"=>"1","Time"=>"12:00");
function whereBuild($arr){
foreach ($arr as $key => $val){
$result.=$key.'="'.$val.'" AND ';
}
$result = substr($result, 0, -5); // removes last AND and spaces
return $result
}
$where = whereBuild($arr);
What do you think? Does it make any sense? Could it be achieved in a simpler/better way?
Thank's!
If you are always using AND in your query you can build an array and implode it on return.
$arr = array("Id"=>"1","Time"=>"12:00");
function whereBuild($arr){
$result = array();
foreach ($arr as $key => $val){
$result[] = $key.'="'.$val.'"';
}
return implode(" AND ", $result);
}
$where = whereBuild($arr);

Concatenation of string with a specific array elements

the given code below insert data from an array to the mysql table.as its not the full code but what i want to know is available in this code. my question is that there is a field in table named "image_url" but the data in that field only have image name and i want to append http://www.xxxxxx.com at the start of every image name and the replace it with the image name in the field but i dont know how to do that plz help me out
thanks in advance
function putTest($t) {
//$c = connect();
foreach ($t as $k => $v) {
$query = "INSERT INTO test (".implode(',',array_keys($v)).") VALUES ('".implode("','",$v)."')";
//echo "<pre>";
// echo $query;
$r = mysql_query($query);
}
//mysql_close($c);
}
This snippet should do what you want:
if (isset($v['image_url'])) {
$v['image_url'] = 'http://www.xxxxxx.com/' . $v['image_url'];
}
You can concatenate strings with the dot "."!
At first... Is your application protected against SQL injection? If not you should build two methods/functions like this using mysql_real_escape_string():
function sqlSafeKey( $key){
return '`' . mysql_real_escape_string( $key) . `'`;
}
function sqlSafeValue( $value){
return "'" . mysql_real_escape_string( $value) . "'";
}
And than use array_map() to escape your values like this:
$keys = array_map( 'sqlSafeKey', array_keys( $v));
$values = array_map( 'sqlSafeValue', $v);
About your question... The matzino's answer is correct and whole loop should look like this:
function putTest($t) {
//$c = connect();
foreach ($t as $k => $v) {
$v['image_url'] = 'http://www.xxxxxx.com/' . $v['image_url'];
$keys = array_map( 'sqlSafeKey', array_keys( $v));
$values = array_map( 'sqlSafeValue', $v);
$query = "INSERT INTO test (".implode(',', $keys).
") VALUES ('".implode("','",$values)."')";
//echo "<pre>";
// echo $query;
$r = mysql_query($query);
}
//mysql_close($c);
}

Categories