I wish to create a piece of dynamic SQL where the values from string variables are used as variables in the SQL string:
"INSERT INTO `product` (`id`,`number`) VALUES (NULL,'1234');"
This works.
What I need to do however, is to have "variable variables"?
So earlier on in the code:
foreach($array as $val)
{
$s .= ',"$val"[$i]';
}
This creates the string:
s = ,'$val[0]','$val[1]'
When inserted as the SQL string:
"INSERT INTO `product` (`id`,`number`) VALUES (NULL,$s);"
It returns:
"INSERT INTO `product` (`id`,`number`) VALUES (NULL,'$val[0]','$val[1]');"
Whereas it should return:
"INSERT INTO `product` (`id`,`number`) VALUES (NULL,'12','34');"
This is being very literal as the MySQL insertion is on a loop where by $val is the array value and [0] is the key.
I'm not sure if this makes sense to anybody as I'm struggling to wrap my head around it, please let me know if my question is to vague or just doesn't make any sense at all.
Thanks
Nick
You are using single quotes, so no string interpolation is done, if you want strings interpolated you have to use double quotes"$var":
$arr = array( 1,2,3);
$i = 0;
echo '$arr[0]'; // prints: $arr[0] <== Your error is here
echo "$arr[0]"; // prints: 1
A better approach
Anyways, you may like to do it this way:
$array = array(12, 34);
$s = implode("', '", $array); // $s is: 12', '34
$s = ", '$s'"; // $s is: '12', '34'
echo $s; // prints: , '12', '34'
From what I could understand from your question, this might help you to achieve what you are looking for.
On your foreach loop you are using
$s .= ',"$val"[$i]';
$val is not concatenated in correct way
try this one
$s .= ','.$val[$i];
You can split values in array by , with implode function
For example:
$array[] = 12;
$array[] = 31;
implode(','$array) returns 12,31
so you could use $s = ','.implode(','$array); to achieve same result
Using your code I think this is what you are trying to do but as I said you are missing attributes.
$s="";
$array = array("12","34");
for($i =0; $i < count($array); $i++)
{
$s .= ",'" . $array[$i] . "'";
}
$sql = "INSERT INTO `product` (`id`,`number`) VALUES (NULL$s);";
Related
I need to sum the result set values separated by "|" inside the loop eg. set of values 10|2, 6|2, 8|1 should result in 24|5.
here is my code:
<?php
$fromdate="2016-03-31";
$todate="2016-03-31";
$TAG="1";
$con = mysqli_connect("XXXXX","XX","XXX","XXX");
$query = mysqli_query($con, "CALL sp_Android_Online_Dashboard('$fromdate', '$todate','$TAG')") or die("Query fail: " . mysqli_error());
$Totfiles = 0;
$file_minutes = 0;
$Tot_minutes=0;
$Pending=0;
while(($row = mysqli_fetch_array($query)))
{
$Totfiles +=$row["Totfiles"];
$file_minutes +=$row["file_minutes"];
$Pending =str_replace(array("/"),"|",$row["Pending"]); //need to sum all the values separated by "|"
$Tot_minutes +=$row["Tot_minutes"];
}
$response["Details"]['Totfiles'] = $Totfiles;
$response["Details"]['file_minutes'] = $file_minutes;
$response["Details"]['Pending'] = $Pending;
$response["Details"]['Tot_minutes'] = $Tot_minutes;
echo json_encode($response);
?>
$row["Pending"] contains the values which are to be summed
result am getting now,
"Pending":"16|9"
"Pending":"11|3"
"Pending":"6|2"
my expected result,
"Pending":"33|14"
This is what you are aiming at i think, you make an array first containing 2 values, on each iteration through the loop you add the new values to them and at the end you can implode it into a string again
// Start with an array containing 0 twice
$Totalpending = [0,0];
while(($row = mysqli_fetch_array($query)))
{
// On each loop we add the left value to the first value in the array and the right value to the second value in the array
$tmp = explode("|", $row['Pending']);
$Totalpending[0] += $tmp[0];
$Totalpending[1] += $tmp[1];
$Totfiles +=$row["Totfiles"];
$file_minutes +=$row["file_minutes"];
$Pending =str_replace(array("/"),"|",$row["Pending"]); //need to sum all the values separated by "|"
$Tot_minutes +=$row["Tot_minutes"];
}
// if you want to format the values in the same way again, although an array is much easier to handle, but it's up to you.
$stringTotalpending = implode('|',$Totalpending);
the string value you want will then be in $stringTotalpending
So Firstly, we need to explode the values from $row["Pending"].
$arr = explode("|", $row["Pending"]);
Now use a loop to add those two numbers:
$temp = 0;
for($i = 0; $i < count($arr); $i++){
$temp += (int) $arr[$i];
}
Now the $temp would contain the result.
As simple as that.
And also as a side note, your code is vulnerable to SQL-Injection attacks.
What about evaling the same string with '|' replaced by '+' ?
eval('$result = ' . str_replace('|', '+', preg_replace('/[^0-9|]/', '', $row["Pending"])) . ';');
echo "$result\n";
Note preg_replace() to sanitize input. Can be avoided if input is already sanitized
In a form, multiple Checkbox values to be inserted into database:
My Code:
Array: ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 )
$a = $_POST['id']; // data from form
$query = "INSERT INTO abc(`x`,`y`,`z`) VALUES " . implode (",","(NULL,$a,'1')");
mysqli_query($dbc,$query);
There seems to be a problem with implode function. How do you concat array using implode?
// Expected output
INSERT INTO abc(`x`,`y`,`z`) VALUES (NULL,1,'1'),(NULL,2,'1'),(NULL,3,'1'),(NULL,4,'1'),
Column y of table abc needs to loop with $a.
If you want to create a batch multiple insertions, first build the batches first, then implode those batches:
$multiple = array_map(function($e) use($dbc) {
$e = $dbc->real_escape_string($e);
return "(NULL, $e, '1')";
}, $a);
$query = "INSERT INTO abc(`x`,`y`,`z`) VALUES " . implode (',', $multiple);
mysqli_query($dbc,$query);
Sidenotes: Its not VALUE, Its VALUES. And remember to use the correct quotes on identifiers. Its supposed to be backticks not single quotes.
INSERT INTO abc('x','y','z') // NOT OK
INSERT INTO abc(`x`,`y`,`z`) // OK
Here you do implode concate.
$query = "INSERT INTO abc('x','y','z') VALUE " . "('" . implode("','", $a) . "')";
Youre using wrong arguments in implode implode() and check your insert query you must use values instead of value
$query = "INSERT INTO abc('x','y','z') VALUES (".implode(",",$a).")";
$a = array(1,2,3,4);
$string = '';
foreach($a as $v){
$string .= "(NULL, $v, 1),";
}
$string = substr($string,0,-1);
$query = "INSERT INTO abc('x','y','z') VALUES $string";
As per your comments in question, This should be your code:
foreach($a as $item)
{
$str[] = "(NULL, '$item', 1)";
}
$query = "INSERT INTO abc(x,y,z) VALUES ".implode(',', $str);
So, you were doing two mistakes:
VALUE should be VALUES
Using implode at wrong place
When I need to loop over something while generating a query from each element, I would use something like
$queryStr = "INSERT INTO tableName (x,y) VALUES ";
for ($i = 0 ; $i < $len ; $i++)
{
$queryStr .= "( ".$thing[$i]['x'].", ".$thing[$i]['b']."), ";
}
//extra code to remove the last comma from string
Would there be an alternative?
I don't mind performance too much (knowing the length of the array is not too big), just something that looks nicer.
Using a prepared statement:
$sql = 'INSERT INTO tableName (x, y) VALUES (:x, :y)';
$sth = $dbh->prepare($sql);
for ($i = 0 ; $i < $len ; $i++)
{
$sth->execute(array(
':x' => $thing[$i]['x'],
':y' => $thing[$i]['b']));
}
More examples: http://www.php.net/manual/en/pdo.prepare.php
A slight improvement to get rid of last part (removing latest comma). You can first create an array of values, then use implode function like:
$queryStr = "INSERT INTO tableName (x,y) VALUES ";
for ($i = 0 ; $i < $len ; $i++)
{
$values[] = "( ".$thing[$i]['x'].", ".$thing[$i]['b'].")";
}
$queryStr .= implode(',', $values);
I like using array_walk and implode for things like this:
$values = array(
array(1, 2, 3),
array(4, 5, 6),
. . .
);
// an array to hold the values to insert
$query = array();
// walk the values and build the query array
array_walk($values, function($v) use(&$query) {
$query[] = "(" . implode(", ", $v) . ")";
});
// dump the output
echo implode(", ", $query);
The result looks like this:
(1, 2, 3), (4, 5, 6), ...
Maybe not much cleaner, but at least it gets rid of the for loop :-)
You could use implode() with array_map():
implode(', ', array_map(function($v) { return '(' . $v['x'] . ', ' . $v['b'] . ')'; }, $things));
Demo
$strCols = '`'.implode('`, `',array_keys($arrValues)).'`'; //Sets the array keys passed in $arrValues up as column names
if ($bolEscape){ //Checks if $bolEscape is true
$arrValues = $this->escape($arrValues); //Calls the escape function
$strValues = '"'.implode('","',array_values($arrValues)).'"'; //Sets the array values passed in $arrValues up as data for the columns
}else{
$strValues = '"'.implode('","',array_values($arrValues)).'"'; //Sets the array values passed in $arrValues up as data for the columns WITHOUT escaping
}
//Creates the SQL statement for the query
$strSQL = 'INSERT INTO `' . $strTable . '` (' . $strCols . ') VALUES (' . $strValues . ')';
Thats part of the database class I have written... I pass in the arrValues ('ColumnName'=>'Value')
I have an array holding this data:
Array (
[1402377] => 7
[1562441] => 7
[1639491] => 9
[1256074] => 10
)
How can create a string that contains the keys of the above array?
Essentially, I need to create a comma separated string that consists of an array's keys
The string would look like: 'key','key','key'
Do I need to create a new array consisting of the keys from an existing array?
The reason I need to do this is because I will be querying a MySQL database using a WHERE in () statement. I would rather not have to query the database using a foreach statement. Am I approaching this problem correctly?
I've tried using a while statement, and I'm able to print the array keys that I need, but I need those keys to be an array in order to send to my model.
The code that allowed me to print the array keys looks like this:
while($element = current($array)) {
$x = key($array)."\n";
echo $x;
next($array);
}
$string = implode(',', array_keys($array));
By the way, for looping over an array consider not using current and next but use foreach:
foreach ($array as $key => $value) {
//do something
}
This will automatically iterate over the array until all records have been visited (or not at all if there are no records.
$keys = array_keys($array);
$string = implode(' ',$keys);
In your case, were you are using the result in a IN clause you should do:
$string = implode(',', $keys);
$yourString = '';
foreach($yourArr as $key => $val) {
$yourString .=$key.",";
}
echo rtrim($yourString, ",");
//OR
$yourString = implode(",", array_keys($yourArray));
See : array_keys
implode(', ', array_keys($array));
Use php array_keys and implode methods
print implode(PHP_EOL, array_keys($element))
The string would look like: 'key','key','key'
$string = '\'' . implode('\',\'', array_keys($array)) . '\'';
Imploding the arguments and interpolating the result into the query can cause an injection vulnerability. Instead, create a prepared statement by repeating a string of parameter placeholders.
$paramList = '(' . str_repeat('?, ', count($array) - 1) . '?)'
$args = array_keys($array);
$statement = 'SELECT ... WHERE column IN ' . $paramList;
$query = $db->prepare($statement);
$query->execute($args);
I have a table "groupdentlink" where I want to delete all the rows that weren't checked in a form.
In essence I want to perform a query like:
DELETE * FROM groupdentlink
WHERE group_id = 'a'
AND dentist_id IS NOT IN ARRAY 'b'
I think I could set a variable with a foreach loop and then keep adding the array values to it so I end up with:
DELETE * FROM groupdentlink
WHERE group_id = 'a'
AND dentist_id != 'D1'
AND dentist_id != 'D5'
AND dentist_id != 'D8'
...and so on.
But is this really the right/best way to do this?
Thanks in advance!
DELETE FROM groupdentlink
WHERE group_id = 'a'
AND dentist_id NOT IN ('D1','D5','D8')
More info here http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_not-in
If you want to execute this query from a Zend Framework driven application please take in consideration the followings :
$where = sprintf('dentist_id NOT IN ("%s")', implode('", "',array_map('mysql_escape_string', $array)));
$this->sqlMapper->delete($where);
If you try . operator for concatenation purposes the query will result in a fatal error because of the quotes. So from my experience using htmlspecialchars or htmlencode along with . operator will only consume your time and patience. The use of sprintf is elegant, helps you keep your code clean.
And I think these observations apply to any application that makes use of php objects.
New user to Stack Exchange, please forgive and instruct if I'm committing a faux pas.
The preceeding answer is incredibly dangerous, because it opens you up to SQL injection attacks.
Always use bind params.
Always use bind params.
Always use bind params.
Hint: if your query does not resemble "DELETE * FROM groupdentlink WHERE group_id = 'a' AND dentist_id IS NOT IN (?, ?, ?);" you are doing it wrong.
An elegant, fully parametrized solution (using PDO):
$dentistIds = ['D1', 'D5', 'D8'];
$query = sprintf(
"DELETE FROM online_order_shipping
WHERE group_id = 'a'
AND dentist_id NOT IN (%s)",
implode(',', array_fill(0, count($dentistIds), '?'))
);
$stmtDelete = $pdo->prepare($query);
$stmtDelete->execute($dentistIds);
The implode function strings ? together with , without adding a comma in the end (source). You could turn that into a function to make it more readable, otherwise the sprintf keeps it nice and tidy without ugly string concatenation.
I found the statement $str = rtrim($str, ",");
didnt remove the trailing comma giving rise to an
error
I came up with this work around:
// string without quotes
$str = array_shift($array);
// string with quotes
$str = "'" . array_shift($array) . "'";
foreach ($array as $item)
{
$str .= ", '" . $item . "'";
}
Here How I do it :
assuming you have an array called $csvstocknumbers = ['0','1'];
$stocknumbers = implode(",",$csvstocknumbers) ; // make the content of the array in one string seprated by ,
$deleteoldvehicles = "DELETE FROM table_name WHERE column_name NOT IN
($stocknumbers ) ;";
mysqli_query($con, $deleteoldvehicles);
You just need to join the ids with a comma:
$myarray = new array('D1', 'D5', 'D8');
$str = "";
foreach ($myarray as $item)
{
$str .= $item . ",";
}
$str = rtrim($str, ",");
$query = "DELETE * FROM groupdentlink
WHERE group_id = 'a'
AND dentist_id NOT IN ($str)";
This will give you a query like this:
DELETE * FROM groupdentlink
WHERE group_id = 'a'
AND dentist_id IS NOT IN (D1, D5, D8);
If you need the quotes around the ids, then change the loop like this:
foreach ($myarray as $item)
{
$str .= "'".$item . "',";
}