Nested foreach loops - anything more efficient? - php

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?

Related

How to generate a WHERE clause from an array with multiple AND-conditions

I have an HTML-table, where various selections can be made. The selected variables that contain the respective values, build the array $data[]. Now, with this array I would like to make an SQL request where all selected criteria should be met. This means, that I need the following request:
SELECT * FROM fruitgroups
WHERE $selection[1] = $value[1]
AND $selection[2] = $value[2]
AND $selection[3] = $value[3]
etc ...
Can anybody please help me with the loop that generates exactly the string:
...
$selection[1] = $value[1]
AND $selection[2] = $value[2]
AND $selection[3] = $value[3]
... etc ...
...that I need for the request?
Thank you in advance!
You can make a SQL request like this:
$selection = array("one", "two", "three");
$value = array("Tone", "Ttwo", "Tthree");
$concat = array();
foreach($selection as $key => $var){
$new = $selection[$key] . " = " . $value[$key];
array_push($concat, $new);
}
$concat = implode(" AND ", $concat);
$request = 'SELECT * FROM fruitgroups WHERE ' . $concat . ';';
echo $request;
Run example
Similar to the answer above, but keep it simple and don't forget the single quotes around the values:
$clauses = [];
foreach ($values as $i => $value) {
$conditions[] = "{$selection[$i]} = '$value'";
}
$query = "SELECT * FROM fruitgroups WHERE " . implode(' AND ', $conditions);
Even better, use an ORM like Eloquent:
$conditions = [];
foreach ($values as $i => $value) {
$conditions[$i] = $value;
}
$result = App\FruitGroups::where($conditions)->get();
I'm assuming you are sanitizing your inputs first, of course.

How to insert an array into a Mysql table

I want to insert an array ($array) into a Mysql table (notification), I tried this but nothing is entering. How do I solve this?
$select = "SELECT * FROM addclique WHERE adder_id = :session_id";
$param1 = array ('session_id' => $_SESSION['id']);
$cliques = $db->query($select, $param1);
foreach($cliques as $key)
{
$array[] = $key['clique_id'];
}
$array[] = $key['clique_id'];
$notijfy = new Notification();
$notijfy->addCircle($array);
function addCircle($id_involve){
$escaped_values = array_map('mysql_real_escape_string', array_values($array));
$sql2 = "INSERT INTO notification(id_involve) VALUES (:id_involve)";
$param2 = array ('id_involve' => implode(", ", $escaped_values));
$result2 = $this->db->query ($sql2, $param2);
}
There are several ways.
I would just do something simple like this:
foreach($cliques as $key){
$array[] = $key['clique_id'];
}
$notijfy = new Notification();
$notijfy->addCircle($array);
function addCircle($array){
$insert_string = '';
$count = 0;
foreach ($array as $k => $v){
$count++;
${$k} = mysqli_real_escape_string($this->db, $v);
$insert_string .= "(" . ${$k} . ")";
if ($count < sizeof($array)){
$insert_string .= ",";
}
}
$sql2 = "INSERT INTO notification(id_involve) VALUES $insert_string;";
$result2= $this->db->query ($sql2, $param2);
}
Your major error is that you are trying to pass ($passing an array when calling the function, but in the function itself your argument is listed as $id_involve, when you obviously need an $array variable that you are using in the function itself. I also can't understand why are you trying to add an element to the $array variable outside of foreach loop in the beginning. Doesn't make any sense.
Instead of $this->db just use your connection variable.

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.

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);
}

Inserting multiple $_Post arrays into a database

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);

Categories