using implode for array inside mysql where in clause - php

im trying to use array for mysql where in clause
$result= $myDB->query("SELECT sum(total) as total FROM ".$myDB->prefix("mydata")." WHERE categoryname IN ('".$categoryname."') AND year='$year' AND stat_id='$stat_id'");
current ouput for the categoryname is
('Cat1,Cat2,Cat3')
desired output
('Cat1','Cat2','Cat3')
i tried it like so far but its not working
$categoryname_new = implode(',',$categoryname);
$result= $myDB->query("SELECT sum(total) as total FROM ".$myDB->prefix("mydata")." WHERE categoryname IN ('".$categoryname_new."') AND year='$year' AND stat_id='$stat_id'");

the naive solution will be:
$array = ['Cat1', 'Cat2', 'Cat3'];
echo "'" . implode("','", $array) . "'";
but it could introduce sql injection, so you need properly escape data in array first
sample one-line with escaping:
echo "'" . implode("','", array_map('mysql_escape_string', $array)) . "'";
note: mysql_* functions are deprecated, you need to use mysqli_* which require connection link

I did something similar a while ago using array_map, hope it helps:
$args = array_map(function($a) {
return sprintf("'%s'", $a);
}, $args);
$args = join(",", $args);
The above code will iterate over the array and modifies every single element to surround it with ''. Finally, I join the array with ,.

Related

Using implode() to separate an array and then use that in an SQL statement [duplicate]

im trying to use array for mysql where in clause
$result= $myDB->query("SELECT sum(total) as total FROM ".$myDB->prefix("mydata")." WHERE categoryname IN ('".$categoryname."') AND year='$year' AND stat_id='$stat_id'");
current ouput for the categoryname is
('Cat1,Cat2,Cat3')
desired output
('Cat1','Cat2','Cat3')
i tried it like so far but its not working
$categoryname_new = implode(',',$categoryname);
$result= $myDB->query("SELECT sum(total) as total FROM ".$myDB->prefix("mydata")." WHERE categoryname IN ('".$categoryname_new."') AND year='$year' AND stat_id='$stat_id'");
the naive solution will be:
$array = ['Cat1', 'Cat2', 'Cat3'];
echo "'" . implode("','", $array) . "'";
but it could introduce sql injection, so you need properly escape data in array first
sample one-line with escaping:
echo "'" . implode("','", array_map('mysql_escape_string', $array)) . "'";
note: mysql_* functions are deprecated, you need to use mysqli_* which require connection link
I did something similar a while ago using array_map, hope it helps:
$args = array_map(function($a) {
return sprintf("'%s'", $a);
}, $args);
$args = join(",", $args);
The above code will iterate over the array and modifies every single element to surround it with ''. Finally, I join the array with ,.

Creating an INSERT statement for all $_POST variables in an array

We are all familiar with traditional form processing i.e.
$email = $_POST['email']; $name = $_POST['name'];
etc.. and then we go ahead and get all the variables from a post.
and then we would create a compound statement like
$qry = "INSERT INTO $tableName (email,name) values ('$email','$name')";
Now what if you had like 18-20 questions? most people would just write lines and lines of code 99.9% of everyone online does it the same way over and over again.
Let's try something different shall we?
I realized there must be a better way using arrays.
For years I've been looking for a simple routine and looked everywhere for it that will CRAFT an insert statement FROM all the $_POST variables.
It dawned on me that $_POST is actually an array so I wrote this little script:
$vars = $_POST;
print_r($vars);
exit;
After working thru this for a few hours with people on this forum here is the resulting code. I believe that by creating a checksum of the hash of all the array keys will solve the fears of SQL attacks, since the server isn't called unless it gets an exact match. If anyone adds a field it will fail. Does everyone agree?
$predefinedChecksum = "84e602bbec8124f298e353171fb7f5b2"; // this is the hash value of all the array keys
$keys = array_keys($_POST);
$values = array_values($_POST);
$sql = "INSERT INTO $tableName (" . join(',', $keys) . ") VALUES ('" . join("',", $values) . "');";
$checksum = md5(join(',',$keys));
if ($checksum<>$predefinedChecksum) exit;
else $res = mysql_query($qry, $conn);
Thanks to all who contributed... I think we've got the workings of a great script.
Someone mentioned to unset the 'button' - how do you do that?
unset( $_POST['button'] );
This did not work - the output of the script still shows 'button' as one of the variables. So the output of the script still has a field called 'button' in the end.
I'm not sure how you could remove it from the series of $values
Anyone have ideas?
Also the output
INSERT INTO (nameFirst,nameLast,emailPref,emailAlt,phoneDay,phoneMobile,ethnicity,yob,income,marital,kids<18,Education,employment,company,title,industry,department,revAnnual,numemps,street,city,state,zip,Type_Mobile,tablet,computer,laptop) VALUES ('Vik',Grant',viktor#eml.cc',',',',african',',19',single',',Some_HS',student',',',Finance_Accntg',Admin',',',',',',',Android',',',');
is missing the ' quote mark on the beginning of the value - can a join exist as join (a,b,c)?
Just loop it with foreach http://nl1.php.net/manual/en/control-structures.foreach.php be careful as this allows any column to be overwritten.
It is safer to specify which columns are allowed to be inserted.
And plz use something like PDO to use prepared statements
You don't really want to do this since you generate queries which can be altered by the client.
But to answer your question, you can do something like:
$columns = array("email", "name", "etc.."); // Array with the "good" columns.
// Unset the columns you do not want in your query.
foreach($_POST as $key=>$value){
if(!in_array($key, $columns)){
unset($_POST[$key]);
}
}
$qry = "INSERT INTO " . $tableName . " (" . implode(", ", array_keys($_POST)) . ") values (" . implode("', '", array_values($_POST)) . ")";
Although the normal way is to use a loop for producing the string containing your values, i sometimes do the following when i know the exact order of keys in my array:
$arr = array(
"email"=>"foo#bar.gr",
"name"=>"vlzvl"
);
$sql = "INSERT INTO mytable (email,name) VALUES ('".implode("','",$arr)."')";
you shouldn't do this since its huge security issue.
But if you really want to do this: (untested, you can still inject SQL so this ain't secure!)
$keys = array_keys($_POST);
$values = array_values($_POST);
$sql = "INSERT INTO $tableName (" . join(',', $keys) . ") VALUES ('" . join("',", $values) . "');";
Edit:
If you are using PDO, you could do it like this:
$keys = array_keys($_POST);
$values = array_values($_POST);
$valuePlaceholders = "";
for ($i=0; $i < count($_POST); $i++) {
$valuePlaceholders .= $i === 0 ? '?' : ', ?';
}
$sql = "INSERT INTO $tableName (" . join(',', $keys) . ") VALUES ($valuePlaceholders);";
And when executing $pdo->execute($values);

Array to string conversion error

I have a query that's pulling a list of IDs. Those IDs are in an array and I need to search another table with those IDs. I tried using implode to make those IDs a string that I could use in a where clause but I keep getting this error.
My current code is:
$query = $this->db->query('
SELECT *
FROM system_scoperights
WHERE user = '. $this->session->userdata('username') .'
');
foreach ($query->result() as $row) {
$scope = $row->site;
$data[] = $scope;
}
$dataScope[] = $data;
$idList = implode(',', $dataScope); <---- Error Line
$where = 'WHERE scope_scopes.sc_ID IN '. $idList .'';
I've tried different things I found on forums like:
$idList = implode(',', array_values($dataScope));
and
$idList = implode(',', join($dataScope));
but none of those work. (I've never even heard of the join function)
Thanks in advance for the help.
$dataScope[] = $data;
but
$data[] = $scope;
therefore $dataScope has an array inside it's array. implode only work on one level, so that why you're getting this error.
You should note that this is actually possible in SQL:
SELECT * FROM some_table WHERE id IN (SELECT site FROM another_table WHERE ... )
which would eliminate the entire need for this code.
That is:
$where = 'WHERE scope_scopes.sc_ID IN (SELECT site
FROM system_scoperights
WHERE user = '. $this->session->userdata('username') . ')';
I partially agree with Jay's answer...just remove the line:
$dataScope[] = $data
and use the $data variable directly since it's already an array:
$idList = implode(',', $data);
However you also should use ( and ) in your where clause:
$where = 'WHERE scope_scopes.sc_ID IN (' . $idList . ')';
Using sub-queries in your where clauses, although they do have their place at times, can cost a lot of overhead, especially using 'SELECT *'. Never ask for more than you need from your db tables :)

Passing a Non-Value in a mySQL WHERE clause

The following is the query that I'm trying to get to work.
$array = array();
SELECT * FROM ENTRIES
WHERE
entry_id = '12'
OR
entry_id_extra IN ('$array')
This is of course simplified. The problem is that it works great if the array has items and it returns everything fine. But if the array has no item it fails to work.
What is the correct way to construct this statement that doesn't break if there are no items in the array? I tried IN ('NULL','$array') but that didnt work.
Any help is appreciated.
You can make the OR portion of the where clause go through a conditional check:
$sql = "SELECT * FROM entries WHERE entry_id = 12"
if (count($array) > 0) {
$sql .= ' OR entry_id_extra IN ($array)';
}
$array = array(...);
$array = array_map('mysql_escape_string', $array); // make sure it's safe
$query = "SELECT *
FROM entries
WHERE entry_id = '12'"
. (count($array) > 0
? " OR entry_id_extra IN ('" . implode("','", $array) . "')"
: "");
// echo the query to see what it looks like (optional)
echo "<pre>{$query}</pre>";
You can use implode, but also make sure you escape the values so quotes don't set the query off.

PHP array_sum function in codeigniter

The following code is a simple select statement that should use the array_sum function to return a value. The result should be getting stored in an array and then getting added up in the SUM function:
$this->db->select('period')
->from('calcdata');
$query = $this->db->get()->result_array();
$query = array_sum($query);
echo "SUM " . $query . "\n" ;
return $query;
the result of this is "SUM 0" but it should be 147 after adding all values up in the period column.
The following code works so i don't understand why the array would be any different from this:
$a = array(2, 4, 6, 8);
echo "sum(a) = " . array_sum($a) . "\n";
I am using codeigniter to create the arrays, does anyone know what is wrong here?
Thanks
Try calling the content of the field instead, not of the whole result array:
$this->db->select('period')->from('calcdata');
$query = $this->db->get();
$period_array = array();
foreach ($query->result_array() as $row)
{
$period_array[] = intval($row['period']); //can it be float also?
}
$total = array_sum($period_array);
UPDATE:
#uzsolt is right, I almost forgot there's a dedicated function in the Active Record class, select_sum(); you might want to try that out also, something like
$this->db->select_sum('period')->get('calcdata');
Quoting from the docs:
$this->db->select_sum();
Writes a "SELECT SUM(field)" portion for your query. As with
select_max(), You can optionally include a second parameter to rename
the resulting field.
$this->db->select_sum('age'); $query = $this->db->get('members');
//> Produces: SELECT SUM(age) as age FROM members

Categories