I am using below function ( i got this from internet) to fetch data from DB and its working fine. If i use where and search condition is not working properly or i have missed some thing. Can any one help me to fix this issue.
public function getRows($table,$conditions = array()){
$sql = 'SELECT ';
$sql .= array_key_exists("select",$conditions)?$conditions['select']:'*';
$sql .= ' FROM '.$table;
if(array_key_exists("where",$conditions)){
$sql .= ' WHERE ';
$i = 0;
foreach($conditions['where'] as $key => $value){
$pre = ($i > 0)?' AND ':'';
echo $sql .= $pre.$key." = '".$value."'";
$i++;
}
}
if(array_key_exists("search",$conditions)){
$sql .= (strpos($sql, 'WHERE') !== false)?'':' WHERE ';
$i = 0;
foreach($conditions['search'] as $key => $value){
$pre = ($i > 0)?' OR ':'';
$sql .= $pre.$key." = '".$value."'";
$i++;
}
}
if(array_key_exists("order_by",$conditions)){
$sql .= ' ORDER BY '.$conditions['order_by'];
}
if(array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){
$sql .= ' LIMIT '.$conditions['start'].','.$conditions['limit'];
}elseif(!array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){
echo $sql .= ' LIMIT '.$conditions['limit'];
}
$query = $this->conn->prepare($sql);
$query->execute();
if(array_key_exists("return_type",$conditions) && $conditions['return_type'] != 'all'){
switch($conditions['return_type']){
case 'count':
$data = $query->rowCount();
break;
case 'single':
$data = $query->fetch(PDO::FETCH_ASSOC);
break;
default:
$data = '';
}
}else{
if($query->rowCount() > 0){
$data = $query->fetchAll();
}
}
return !empty($data)?$data:false;
}
Function used with where and Search condition
if(!empty($_POST['customer_number'])) {
$ajaxData = $auth_user->getRows(
'tablename',
array('where' => array('fieldName'=>$doc)),
array('search'=> array('fieldname1'=>$_POST['customer_number'], 'fieldname2'=>$_POST['customer_number']))
);
}
Result of the above code is
SELECT * FROM tablename WHERE cust_consum_type = '1'
Expected Result is.
select * from tablename where fieldName='somevalue' and fieldname1='somevalue' OR fieldname2='somevalue'
Help me to fix this issue.
This function is so wrong on so many levels, being critically insecure in the first place.
Instead, use vanilla PDO. Make your function this way
public function getRows($sql,$input = array()){
$stmt = $this->conn->prepare($sql);
$stmt->execute($input);
return $stmt;
}
Then just write your query right away with placeholders, pass the data in pparameters and have the result:
$sql = "select * from tablename where fieldName=:fieldName
and (fieldname1=:fieldName1 OR fieldname2=:fieldName2)";
$input = ['fieldName'=>$doc,
'fieldname1'=>$_POST['customer_number'],
'fieldname2'=>$_POST['customer_number']];
$data = $db->getRows($sql, $input)->fetchAll();
it will be safe, clean, always working, safe, flexible, safe from SQL injections and syntax errors.
Related
How do I add a where clause in the following query using the CI? E.g. WHERE name = 'Joe'
<?php
include 'dbclass.php';
$db = new DB();
$users = $db->getRows('users',array('order_by'=>'id DESC'));
if(!empty($users)):
$count = 0;
foreach($users as $user):
$count++;
?>
dbclass.php
snippet:
public function getRows($table,$conditions = array()){
$sql = 'SELECT ';
$sql .= array_key_exists("select",$conditions)?$conditions['select']:'*';
$sql .= ' FROM '.$table;
if(array_key_exists("where",$conditions)){
$sql .= ' WHERE ';
$i = 0;
foreach($conditions['where'] as $key => $value){
$pre = ($i > 0)?' AND ':'';
$sql .= $pre.$key." = '".$value."'";
$i++;
}
}
if(array_key_exists("order_by",$conditions)){
$sql .= ' ORDER BY '.$conditions['order_by'];
}
if(array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){
$sql .= ' LIMIT '.$conditions['start'].','.$conditions['limit'];
}elseif(!array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){
$sql .= ' LIMIT '.$conditions['limit'];
}
$result = $this->db->query($sql);
I want help in passing the Where clause condition.
I am using Codeignitor 4.
Not sure where the codeigniter parts are in this, that looks like code you have written, so just add a where key to the array you are passing like this
$users = $db->getRows('users',array('where' => ["name => 'Joe']",
'order_by'=>'id DESC'));
I've got below snippet where $filter_xx values are extracted from a dropdown basis user choice.
I'm trying to query the mySQL database with what the user chose to query the database with via dropdown selection.
You will see that there are 4 $filter_xx variables and how many of them are set in a given instance is completely random.
The issue is when I use && in the query it checks if all four parameters are true and then throws and output. (Well I know && is suppose to work that way!). I tried replacing all && operators with || and had no luck.
How do I search the database with only options selected by the user?
if(isset($filter_brand) || isset($filter_year) || isset($filter_month) || isset($filter_status))
{
$query = "SELECT * FROM targets WHERE brand='$filter_brand' && startyear='$filter_year' && startmonth='$filter_month' && status='$filter_status' ORDER BY createdon DESC";
} else {
$query = "SELECT * FROM targets ORDER BY createdon DESC";
}
When you have several values that must work in a similar manner, use an array together with loop. I am supposing, you are using mysqli, change quoting for PDO if needed.
$mysqli = new mysqli("localhost", "user", "pass", "test");
//...
//SQL attr name => name of POST parameter
$filter = array('brand' => 'brand', 'startyear' => 'year',
'startmonth' => 'month', 'status' => 'status');
//here we'll store SQL conditions
$sql_filter = array();
foreach($filter as $key => $value)
{
if (isset($_POST[$value]))
{
//use your library function to quote the variable before using it in SQL
$sql_filter[] = $key . '="'. $mysqli->escape_string($_POST[$value]) . '"';
}
}
$query = "SELECT * FROM targets ";
if(isset($sql_filter[0]))
{
$query .= 'WHERE ' . implode(' AND ', $sql_filter) . ' ';
}
$query .= 'ORDER BY createdon DESC';
Try By This
$join = "";
//TAKE ONE BLANK VARIBLE THAT JOIN IF VALUE IS SET
if(isset($filter_brand)){
//IF VALUE ISSET THAN IT ADDED TO QUERY
$join .= " AND brand='$filter_brand'";
}
if(isset($filter_year){
$join .= " AND startyear='$filter_year'";
}
$query = "SELECT * FROM targets WHERE id != '' $join ORDER BY createdon DESC";
You can do something like this:
$query = 'SELECT * FROM targets';
$flag = 0;
if(isset($filter_brand) )
{
$query = "SELECT * FROM targets WHERE brand='$filter_brand'";
$flag = 1;
}
if(isset($filter_year)) {
if($flag==1)
$query .= " &&";
$query .= " startyear='$filter_year'";
$flag = 1;
}
if(isset($filter_month)) {
if($flag==1)
$query .= " &&";
$query = " startmonth='$filter_month'";
$flag = 1;
}
if(isset($filter_status)){
if($flag==1)
$query .= " &&";
$query = " status='$filter_status'";
$flag = 1;
}
if($flag == 1){
$query .= " ORDER BY createdon DESC";
} else {
$query = "SELECT * FROM targets ORDER BY createdon DESC";
}
Try this:
$query = "SELECT * FROM targets WHERE 1 ";
$query = isset($filter_brand) ? $query . " AND brand = '".$filter_brand."'" : $query;
$query = isset($filter_year) ? $query . " AND startyear = '".$filter_year."'" : $query;
$query = isset($filter_month) ? $query . " AND startmonth = '".$filter_month."'" : $query;
$query = isset($filter_status) ? $query . " AND status = '".$filter_status."'" : $query;
$query .= " ORDER BY createdon DESC";
I am new to php language. I just copy a database connection function from another sample project. The code is below.
public function getRows($conditions = array()){
$sql = 'SELECT ';
$sql .= array_key_exists("select",$conditions)?$conditions['select']:'*';
$sql .= ' FROM '.$this->table;
if(array_key_exists("where",$conditions)){
$sql .= ' WHERE ';
$i = 0;
foreach($conditions['where'] as $key => $value){
$pre = ($i > 0)?' AND ':'';
$sql .= $pre.$key." = '".$value."'";
$i++;
}
}
if(array_key_exists("order_by",$conditions)){
$sql .= ' ORDER BY '.$conditions['order_by'];
}
if(array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){
$sql .= ' LIMIT '.$conditions['start'].','.$conditions['limit'];
}elseif(!array_key_exists("start",$conditions) && array_key_exists("limit",$conditions)){
$sql .= ' LIMIT '.$conditions['limit'];
}
$query = $this->db->prepare($sql);
$query->execute();
if(array_key_exists("return_type",$conditions) && $conditions['return_type'] != 'all'){
switch($conditions['return_type']){
case 'count':
$data = $query->rowCount();
break;
case 'single':
$data = $query->fetch(PDO::FETCH_ASSOC);
break;
default:
$data = '';
}
}else{
if($query->rowCount() > 0){
$data = $query->fetchAll();
}
}
return !empty($data)?$data:false;
}
Can anyone show me example how to use this function?I want to use WHERE,LIMIT,GROUP_BY and SELECT clauses. When I put in an array like this, I got error message " Invalid argument supplied for foreach()"
$conditions = array('where' => "user_name = '$username'");
$data = $userMo -> getRows($conditions);
you are making a mistake, as its said Invalid argument supplied for foreach()
that means its not getting an array, and think if there are multiple WHERE then??
so try this
$conditions = array('where' => array('user_name' => $username));
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to prevent SQL injection in PHP?
I have this code
$where = '';
if (isset($_POST['lvl']) && $vals = $_POST['lvl']) {
$where = 'WHERE ';
$first = false;
if ($vals[0] === '0') {
$where .= 'team = "neutral"';
unset($vals[0]);
$first = true;
}
if (count($vals)) {
if ($first) $where .= ' OR ';
$where .= 'lvl IN (\'' . implode('\',\'', $vals) . '\')';
}}
$sql = "SELECT * FROM $table $where";
$res = $DBH->prepare($sql);
$res->execute();
$num = $res->rowCount();
echo "<h2>".$num."</h2>";
It works, but if someone did something, then this happens. How to fix this?
UPD: added PDO code
You need to use PDO::quote() for all string values.
Also you should never select all the records when you need only to count them. Ask a database to do it for you
$where = '';
if (!empty($_POST['lvl'])) {
$vals = $_POST['lvl'];
$where = 'WHERE ';
if ($vals[0] === '0') {
$where .= "team = 'neutral'";
unset($vals[0]);
if ($vals) {
$where .= " OR ";
}
}
if ($vals) {
foreach ($vals as $i => $val) {
$vals[$i] = $DBH->quote($val);
}
$where .= "lvl IN (".implode(',', $vals).")";
}
}
$sql = "SELECT count(*) as cnt FROM $table $where";
$res = $DBH->query($sql);
$res->execute();
$row = $res->fetch();
echo "<h2>".$row['num']."</h2>";
By the way, with my own class the code would be slightly less complex, because it makes manual escaping unnecessary (it is using mysqli, not PDO though).
$where = '';
if (!empty($_POST['lvl'])) {
$vals = $_POST['lvl'];
$where = 'WHERE ';
if ($vals[0] === '0') {
$where .= "team = 'neutral'";
unset($vals[0]);
if ($vals) {
$where .= " OR ";
}
}
if ($vals) {
$where .= $db->parse("lvl IN (?a)",$vals);
}
}
$num = $db->getOne("SELECT count(*) as cnt FROM ?n ?p",$table, $where);
echo "<h2>".$num."</h2>";
Use PHP's mysqli_real_escape_string() in order to escape values. Note that it is mysqli because mysql functions have been depreciated.
Use PDO with named parameters
http://php.net/manual/en/pdo.prepared-statements.php
I'm attempting the modify this Modx Snippet so that it will accept multiple values being returned from the db instead of the default one.
tvTags, by default, was only meant to be set to one variable. I modified it a bit so that it's exploded into a list of variables. I'd like to query the database for each of these variables and return the tags associated with each. However, I'm having difficulty as I'm fairly new to SQL and PHP.
I plugged in $region and it works, but I'm not really sure how to add in more WHERE clauses for the $countries variable.
Thanks for your help!
if (!function_exists('getTags')) {
function getTags($cIDs, $tvTags, $days) {
global $modx, $parent;
$docTags = array ();
$baspath= $modx->config["base_path"] . "manager/includes";
include_once $baspath . "/tmplvars.format.inc.php";
include_once $baspath . "/tmplvars.commands.inc.php";
if ($days > 0) {
$pub_date = mktime() - $days*24*60*60;
} else {
$pub_date = 0;
}
list($region, $countries) = explode(",", $tvTags);
$tb1 = $modx->getFullTableName("site_tmplvar_contentvalues");
$tb2 = $modx->getFullTableName("site_tmplvars");
$tb_content = $modx->getFullTableName("site_content");
$query = "SELECT stv.name,stc.tmplvarid,stc.contentid,stv.type,stv.display,stv.display_params,stc.value";
$query .= " FROM ".$tb1." stc LEFT JOIN ".$tb2." stv ON stv.id=stc.tmplvarid ";
$query .= " LEFT JOIN $tb_content tb_content ON stc.contentid=tb_content.id ";
$query .= " WHERE stv.name='".$region."' AND stc.contentid IN (".implode($cIDs,",").") ";
$query .= " AND tb_content.pub_date >= '$pub_date' ";
$query .= " AND tb_content.published = 1 ";
$query .= " ORDER BY stc.contentid ASC;";
$rs = $modx->db->query($query);
$tot = $modx->db->getRecordCount($rs);
$resourceArray = array();
for($i=0;$i<$tot;$i++) {
$row = #$modx->fetchRow($rs);
$docTags[$row['contentid']]['tags'] = getTVDisplayFormat($row['name'], $row['value'], $row['display'], $row['display_params'], $row['type'],$row['contentid']);
}
if ($tot != count($cIDs)) {
$query = "SELECT name,type,display,display_params,default_text";
$query .= " FROM $tb2";
$query .= " WHERE name='".$region."' LIMIT 1";
$rs = $modx->db->query($query);
$row = #$modx->fetchRow($rs);
$defaultOutput = getTVDisplayFormat($row['name'], $row['default_text'], $row['display'], $row['display_params'], $row['type'],$row['contentid']);
foreach ($cIDs as $id) {
if (!isset($docTags[$id]['tags'])) {
$docTags[$id]['tags'] = $defaultOutput;
}
}
}
return $docTags;
}
}
You don't add in more WHERE clauses, you use ANDs and ORs in the already existing where clause. I would say after the line $query .= " WHERE stv.name = '".$region... you put in
foreach ($countries as $country)
{
$query .= "OR stv.name = '{$country}', ";
}
but I don't know how you want the query to work.