The following code is supposed to check for the column names of a table. Then check to see if a corresponding variable has been $_POST and if it has add it to the $SQL. I believe there is a problem with the array that contains a series of arrays but I don't know how to dix it.
$where = $_POST['where'];
$is = $_POST['is'];
$table = $_POST['table'];
$sql = "UPDATE $table SET";
$array = array();
$columnnames = columnnames('blog');
foreach ($columnnames as $columnname){
if($_POST[$columnname]){
$sql .= " $columnname = :$columnname,";
$array .= array(':$columnname' => $_POST[$columnname],);
}
}
$sql = rtrim($sql,',');
$array = rtrim($array,',');
$sql .= " WHERE $where = '$is'";
$q = $rikdb->prepare($sql);
$q->execute($array);
For the sake of comprehension please except that $columnnames = columnnames('blog'); works as it does.
Change this:
$array .= array(':$columnname' => $_POST[$columnname],);
to this:
$array[':$columnname'] = $_POST[$columnname];
and after that use rtrim only on $sql.
the problem is here $array .= array(':$columnname' => $_POST[$columnname],);
you have a , part of the value which is not literal. change it to be like
$array .= array(':$columnname' => $_POST[$columnname] . ",");
You can also add your column names and values to an array and implode(",", $array) so you don't have to use rtrim
Instead of using
$array .= array(':$columnname' => $_POST[$columnname],);
and applying rtrim on results, I'd suggest the easier and failsafe method:
$array[':$columnname'] = $_POST[$columnname];
Related
I'm trying to make a function that creates a sql statement to insert data into a database and this is a snippet. It works fine except for the last foreach loop. For some reason it won't iterate to the last element in the array it'll stay stuck on the second last one. The issue is that the first foreach loop is the same code and it works fine, but the second is giving me trouble.
*note:The if statements in the foreach loops are supposed to catch the last element in the array and make sure that a ',' isn't inserted. And this is where the problem is. If I take the if statement out of the second loop the loop will iterate to the last element but without the if block it places a comma at the end and creates a SQL syntax error.
output of the first loop
INSERT INTO gardyloo.users (joe,bob,joe#hotmail.com,8de,154927,2014-12-18,2014-12-18 7:02:11)
output of second loop without if
VALUES (:firstName,:lastName,:emailAddress,:password,:userid,:date_joined,:timestamp,)
output of second loop with if
VALUES (:firstName,:lastName,:emailAddress,:password,:userid,:date_joined)
foreach( $values as $a => $b ){
if(next($values) == null){
$sql .= $b."";
break;
}
$sql .= $b.",";
}
$sql .= ") ";
$sql .= "VALUES (";
foreach( $values as $a => $b ){
if(next($values) == null){
$sql .= ":".$a;
break;
}
$sql .= ":".$a.",";
}
$sql .= ")";
*Edit, this code seems to work fine:
$sql .= implode(', ', array_keys($values));
$sql .= ") ";
$sql .= "VALUES (:";
$sql .= implode(", :", array_keys($values));
$sql .= ")";
Instead of break you need to use continue; Break interrupts the loop, while continue only move to next iteration.
Try this:
foreach( $values as $a => $b ){
if($b == null){
continue;
}
$sql .= ":".$a.",";
}
Do something like this:
//Your data
$values = array(
'firstName' => 'Joe',
'lastName' => 'bob',
'emailAddress' => 'joe#hotmail.com',
'password' => '8de',
'userid' => 154927,
'date_joined' => '2014-12-18',
'timestamp' => '2014-12-18 7:02:11'
);
//Begins the sentence
$sql = 'INSERT INTO gardyloo.users(';
/**
* Begins example code.
* - array_keys shows the key as a value
* example: $values[0] = firstName
*/
foreach(array_keys($values) as $k => $v)
{
//when the array arrives at the end, doesn't show ','
if($k != count($values)-1)
$sql .= $v.",";
else
$sql .= $v;
}
$sql .= ") ";
$sql .= "VALUES (";
$k = 0;//the new count initialized
foreach($values as $v)
{
//when the array arrives at the end, doesn't show ','
if($k != count($values)-1)
$sql .= $v.",";
else
$sql .= $v;
//increments the counter
$k++;
}
$sql .= ");";
Notes:
Separate the code in functions since both foreachs are very similar.
You can play with the foreach values to return the value that you want.
Ask me if you have more questions about it.
I'll do it otherwise. Instead of concat a string $sql create 2 variables, $columns and $values, both are arrays. And you don't need a loop to do this.
So here is how i would do it :
$columns = array_keys($values);
$sql = "INSERT INTO table (". implode(" ,", $columns) . ") VALUES (". implode(" ,", $values);
Here you don't need to test if it's the last element of the array to make a break;
Hope it helps ;)
This question already has answers here:
How can I bind an array of strings with a mysqli prepared statement?
(7 answers)
Closed 6 months ago.
I have a string like this 'dubai,sharjah,' and I want to make it like this 'dubai','sharja',
I am passing the value dubai,sharjah, in the URL using ajax and my code
$city=$_GET['city'];
$sql = "SELECT * FROM filter where isdeleted = 0 ";
if ($city !="" && $city !="Empty" ){
$sql.=" and twon in ('".$citydata."')";
}
when I print the query, it's like this
SELECT * FROM filter where isdeleted = 0 and twon in ('dubai,sharjah,')
but I want it like this
SELECT * FROM filter where isdeleted = 0 and twon in ('dubai','sharja')
Can anyone guide me on how to do this using PHP?
Here's how I would approach it. I'm going to use PDO instead of mysqli because trying to get an array into mysqli_stmt::bind_param is just a pain.
First, create an array of cities, removing any empty values
$params = array_filter(explode(',', $city), function($c) {
return !empty($c) && $c !== 'Empty';
});
$paramCount = count($params);
$query = 'SELECT * FROM filter where isdeleted = 0';
Now generate a placeholder string for your prepared statement.
if ($paramCount) {
$placeholders = implode(',', array_fill(0, $paramCount, '?');
// looks something like '?,?'
$query .= " AND twon IN ($placeholders)";
}
Now, prepare a statement
// assuming you have a PDO instance in $pdo created with something like
// $pdo = new PDO('mysql:host=localhost;dbname=your_db;charset=utf8', 'username', 'password', [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$stmt = $pdo->prepare($query);
Execute and fetch values :)
$stmt->execute($params);
$filters = $stmt->fetchAll(PDO::FETCH_ASSOC);
$cities = explode(",", $_GET['city']);
//escape!
foreach ($cities as $citykey => $city) {
$cities[$citykey] = "'" . mysql_real_escape_string($city) . "'";
}
$sql = "SELECT * FROM `filter` where `isdeleted` = 0";
if (!empty($cities)) {
$sql .= ' and `twon` in (' . implode(',', $cities) . ')';
}
An alternative is to use FIND_IN_SET(). No PHP code change needed.
$sql.=" and FIND_IN_SET(town, '".$citydata."')";
you can try to explode the string
$cityparts = explode(",",$city);
and you can use
$cityparts[0] and $cityparts[1] in your query
array explode ( string $delimiter , string $string [, int $limit ] )
you can find more information on [http://www.php.net/explode]
hope this helps!!
You just have to explode and implode here. Rest is the problem with extra , in your string at the end.
$str = "dubai,sharjah,";
$citydata = implode("','",explode(',',rtrim($str,',')));
echo "'$citydata'";
test
After 6 answers I gotta add a 7th:
$sql.=" and twon in ('".str_replace(",","','",$citydata)."')";
You can do this.
$string = 'dubai,sharjah';
$cities = explode(',', $string);
echo $cities[0]; //dubai
echo $cities[1]; //sharjah
try this
$str = "dubai,sharjah,";
$arr = explode(",", $str);
$arr_temp = array()
foreach($arr as $s)
{
if($s!="")
{
$arr_temp[] = "'".$s."'";
}
}
$new_str = implode(",", $arr_temp);
echo $new_str; // output 'dubai','sharjah'
Now your Sql will be
$sql = "SELECT * FROM filter where isdeleted = 0 and twon in ($new_str) ";
You can use it
in $city I fix two values with, you can use here by $_GET ;
$city = "dubai,sharjah,";
$query_string ="";
$words = explode(",",$city);
for($i=0;$i<count($words);$i++){$query_string .= "'".$words[$i]."',";}
$query_string = substr($query_string,0,strlen($query_string)-4);
then use your query
SELECT * FROM filter where isdeleted = 0 and twon in ($query_string)
if ($city !="" && $city !="Empty" )
{
$city_exp = explode(',' $city);
$sql .= " and twon in ('".implode("', '", $city_exp)."')";
}
What we are basically doing here is putting the two values in an array by using explode and then separating each item in that array by using implode
DEMO
I want to create an associative array in php with dynamic key and also a dynamic value from a particular mysql table.
The table name is monthly_salary with a two column named month and salary respectively.
I get the data inside it:
$sql = mysql_query('SELECT * FROM monthly_salary');
$sql2 = mysql_query('SELECT * FROM monthly_salary');
Then assigned and concatenated the collected data to $mon and $sal:
$mon = "";
$sal = "";
while($row = mysql_fetch_array($sql)){
$mon .= $row['month'].", ";
}
while($row = mysql_fetch_array($sql2)){
$sal .= $row['salary'].", ";
}
After that I've converted it to array and concatenate it until it became and associative array:
$monArray = array(substr(trim($mon), 0, -1));
$salArray = array(substr(trim($sal), 0, -1));
$key = "";
$keyWithVal = "";
foreach($monArray as $k){
$key .= $k." => ";
}
foreach($salArray as $k){
$keyWithVal .= $key.$k.",";
}
$associativeArray = array(substr(trim($keyWithVal), 0, -1));
My Problem is that when I've echo it the result is always like this
3500=>Jan=>3500:
foreach($associativeArray as $k => $id){
echo $k."=>".$id;
}
So how can I fix it and with the correct output Jan=>3500?
You are way over-complicating this problem. This can be done simply, with fewer loops.
First, you only need to run the SQL once. Second, build the array in the 1st loop.
$sql = mysql_query('SELECT * FROM monthly_salary');
$associativeArray = array();
while($row = mysql_fetch_array($sql)){
// Put the values into the array, no other variables needed
$associativeArray[$row['month']] = $row['salary'];
}
foreach($associativeArray as $k => $id){
echo $k."=>".$id;
}
Why don't you just do:
$associativeArray = array();
while($row = mysql_fetch_array($sql)){
$associativeArray[$row['month']] = $row['salary'];
}
Following worked for me for creating associative array. array_push don't work on associative array but using unary operator does work:
$associativeArray += [$key => $value];
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
remove element from array based on its value?
I have this array
$arr = array(
'key1'=>'value1',
'key2'=>NULL,
'key3'=>'value2'
);
if I do implode(',',$arr); I get: value1,,value2 (notice the empty space)
Is there a way to skip that NULL values? To get something like this:
value1,value2
I could traverse all the array and unset manually the key where the value is NULL, but it's a bit an overkill doens't it?
Edit:
To save time Maybe I could do just one loop to iterate over the array, and in the same loop I check for null values and if isn't null I append it the ','
like this:
foreach($arr as $k=>$v) {
if ($v !== NULL) {
echo $v.',';
}
}
The problem here is that I have a final ',' at the end.
Edit
As gordon asked, it ran this test (1000000 iterations)
First using array_filter:
$pairsCache = array('key1'=>'value1','key2'=>NULL,'key3'=>'value3',
'key4'=>'value4','key5'=>'value5');
for($i=0;$i<1000000;$i++) {
$query = "INSERT INTO tbl (";
$keys='';
$values='';
$pairs = array_filter($pairsCache,function($v){return $v !== NULL;});
$keys = array_keys($pairs);
//> keys
$query .= implode(',',$keys ) . ") VALUES ( '";
//> values
$query .= implode("','",$pairs) . "')";
}
Time: 7.5949399471283
Query: "INSERT INTO tbl (key1,key3,key4,key5) VALUES ( 'value1','value3','value4','value5')"
Second using only one loop:
for($i=0;$i<1000000;$i++) {
$query = "INSERT INTO tbl (";
$keys='';
$values='';
foreach($pairsCache as $k=>$v) {
if ($v!==NULL) {
$keys .= $k.',';
$values .= "'{$v}',";
}
}
$keys=rtrim($keys,',');
$values=rtrim($values,',');
$query = $query . $keys . ') VALUES ( ' . $values . ')';
}
Time: 4.1640941333771
Query: INSERT INTO tbl (key1,key3,key4,key5,) VALUES ( 'value1','value3','value4','value5')
$arr = array_filter($arr);
array_filter() removes every value, that evaluates to false from $arr.
If you need finer control, you can pass a callback as second argument
arr = array_filter($arr, function ($item) { return !is_null($item);});
At last of course you can iterate over the array yourself
foreach (array_keys($arr) $key) {
if (is_null($arr[$key])) unset($arr[$key]);
}
Note, that there is no downside, if you filter and output in two separate steps
You can use array_filter():
If no callback is supplied, all entries of input equal to FALSE (see converting to boolean) will be removed.
implode(',', array_filter($arr));
There is no possibility to do this using only implode().
You can traverse all the array (as you said) maybe in a wrapper my_implode() function, or you can use something less elegant such as:
trim(preg_replace('/[,]+/', ',', implode(',', $arr)), ',');
You can simply use bellow code.
Edited.
function nullFilter($val)
{
return $val !== NULL;
}
$arr = array( 'key1'=>'value1', 'key2'=>NULL, 'key3'=>'value2' );
$filteredArray = array_filter($arr,"nullFilter");
echo implode(',', $filteredArray);
Cheers!
Prasad.
I'm trying to save some code with the following. I've an object with variables named the same as table rows so I could create an insert like this one:
$query = "INSERT INTO table ";
$columns = '(';
$values = 'VALUES (';
foreach ($this as $var => $value){
if ($value){
$columns .= $var.', ';
if (!is_int($value))
$value = '\''.$value.'\'';
$values .= $value.', ';
}
}
$columns .= ')';
$values .= ')';
$columns = str_replace (', )', ')', $columns);
$values = str_replace (', )', ')', $values);
$query .= $columns." ".$values;
But every single variable is detected as string and that's not true in all fields as you may imagine.
Does anyone have a solution?
Here's how I would write it:
<?php
$canonical_columns = array_flip(array("column1", "column2", "column3"));
$columns = array_keys(array_intersect_key($canonical_columns, (array) $this));
$params = join(",", array_fill(0, count($columns), "?"));
$columns = join(",", $columns);
$query = "INSERT INTO table ($columns) VALUES ($params)";
$stmt = $pdo->prepare($query);
$stmt->execute(array_values($this));
Stop concatenating fragments of strings to form SQL.
Use PDO, and use parameters for values.
Allowlist column names by comparing inputs to known, valid column names.
It appears as if you numbers are in fact strings. Try to use is_numeric() instead of is_int().
If this ain't enough you can cast the string to an integer and then check for != 0.
You may insert numbers in quotes too, as strings. This will not create an error.