I would like to add " AND " in between the key and value pair arguments for my sql query but I don't know how. I have tried search the net but unable to find a solution.
$cdatahome = fetchCategory(array("status"=>"1","home"=>"1"));
function fetchCategory(array $conditions){
$db = Core::getInstance();
$sql = "SELECT id, title FROM ruj_category WHERE ";
$params = array();
foreach ($conditions as $column => $value) {
if (preg_match('/^[a-z-.]+$/', $column)) {
$sql .= "$column = ?";
$params[] = $value;
}
}
$sql .= " order by title asc";
$res = $db->dbh->prepare($sql);
$res->execute(array_values($params));
$res = $res->fetchAll(PDO::FETCH_ASSOC);
return $res;
$where = array();
foreach ($conditions as $column => $value) {
if (preg_match('/^[a-z-.]+$/', $column)) {
$where[] = "$column = ?";
$params[] = $value;
}
}
$sql .= implode(' AND ', $where);
$cdatahome = fetchCategory(array("status"=>"1","home"=>"1"));
function fetchCategory(array $conditions){
$db = Core::getInstance();
$sql = "SELECT id, title FROM ruj_category WHERE ";
$params = array();
$i = 0;
foreach ($conditions as $column => $value) {
if (preg_match('/^[a-z-.]+$/', $column)) {
if($i != 0){
$sql .= ' AND ';
}
$sql .= "$column = ?";
$params[] = $value;
$i++;
}
}
$sql .= " order by title asc";
$res = $db->dbh->prepare($sql);
$res->execute(array_values($params));
$res = $res->fetchAll(PDO::FETCH_ASSOC);
return $res;
Usually, when I want to put something like AND or & (in the case of URLs), I create an array and implode it on the string I want in the middle. For example:
$items = array("a", "b", "c");
$output = implode(" AND ", $items);
Outputs:
"a AND b AND c"
In your case, you can do your foreach loop to build the string pieces and then use AND as glue in the implode() function as listed out by the second answer.
First, you could put the conditions into an array, as you do with the values to $params. Like $cond[]="$column = ?" and then $sql.=implode(' AND ',$cond);
To have it solved in your foreach: before the loop set $first=false; and in the loop do $sql.=($first?'':' AND ')."$column = ?"; $first=false;
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 want to do a search in a table with search words defined by a user.
I'm doing this by splitting the string an constructing the sql.
But i can't seem to make it work. It works fine, if only one word is entered, but with two or more words it's crashing.
$q = $_GET['q']; //Search word
$q = htmlspecialchars($q);
$q_exploded = explode ( " ", $q );
foreach( $q_exploded as $search_each ) {
$where .= "content LIKE ? OR ";
$bind .= "s";
$param .= "%$search_each%, ";
}
$where = rtrim($where,'OR ');
$param = rtrim($param,', ');
$sql = "SELECT ads_id FROM search_index WHERE ".$where."";
echo $sql . "<br>".$param."<br>".$bind."<br>";
$stmt = $dbconn->prepare($sql);
$stmt->bind_param($bind, $param);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo $row['ads_id'];
}
This is my error
SELECT ads_id FROM search_index WHERE content LIKE ? OR content LIKE ?
%word1%, %word2%
ss
Warning: mysqli_stmt::bind_param(): Number of elements in type
definition string doesn't match number of bind variables
You issue is here:
$stmt->bind_param($bind, $param);
What you're doing is:
$stmt->bind_param("ss", $param);
While you may intend param to satisfy both of the strings it doesn't you need to pass a variable for each one. I would try looking into explode for this.
Someone posted an answer earlier, but deleted it again. That answer actually worked, i just needed to change from mySQLi to DPO.
Solution:
$q = htmlspecialchars($q);
$q_exploded = explode ( " ", $q );
$where = [];
$bind = [];
foreach ($q_exploded as $idx => $search_each) {
$key = ':val' . $idx;
$where[] = "content LIKE " . $key;
$bind[$key] = "%$search_each%";
}
$sql = "SELECT ads_id FROM search_index WHERE " . implode(" OR ", $where);
$stmt = $pdo_conn->prepare($sql);
$stmt->execute($bind);
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
while ($row = $stmt->fetch()) {
echo $row['ads_id'] . "<br>";
}
When I try to update a table with the following query string using PHP:
UPDATE card_designs SET `card_price` = '6180',
`annual` = '257.3',
`initial_payment` = '6512.3'
WHERE card_id = '1'
It does not update correctly. card_price value is put in correctly. However annual comes in as 0 and initial_payment comes in as 6255.00.
It doesn't matter if the fields are a VARCHAR, DECIMAL, or DOUBLE. If the value has a decimal it's all messed up.
Also, if I run the above query in a SQL client, the query works fine.
Here is the PHP code that constructs the query. I'm using mysqli:
$sql = "UPDATE ". $table ." SET ";
$updates = array();
foreach ($variables as $field => $value) {
array_push($updates, "`$field` = '$value'");
}
$sql .= implode(', ', $updates);
//Add the $where clauses as needed
if (!empty($where)) {
foreach ($where as $field => $value) {
$value = $value;
$clause[] = "$field = '$value'";
}
$sql .= ' WHERE '. implode(' AND ', $clause);
}
if (!empty( $limit)) {
$sql .= ' LIMIT '. $limit;
}
$query = $this->mysqli->query($sql);
I assume your database table fields datatype is Decimal(9,2)
// Prepare query
$table = "card_designs";
$variables = array(
"card_price" => "6180.00",
"annual" => "257.3",
"initial_payment" => "6512.3"
);
$where = array(
"id" => "1"
);
$sql = "UPDATE ". $table ." SET ";
$updates = array();
foreach ($variables as $field => $value)
{
array_push($updates, "$field = $value");
}
$sql .= implode(', ', $updates);
//Add the $where clauses as needed
if (!empty($where))
{
foreach ($where as $field => $value)
{
$value = $value;
$clause[] = "$field = $value";
}
$sql .= ' WHERE '. implode(' AND ', $clause);
}
if (!empty( $limit))
{
$sql .= ' LIMIT '. $limit;
}
// Run query
if ($mysqli->query($sql))
{
echo "Record updated successfully";
}
Below is my query:
$key = array(1,2);
$in = join(',', array_fill(0, count($key), '?'));
$statement = $pdo->prepare("SELECT * FROM posts WHERE posts.subid IN (".$in.") AND posts.pricing=? AND posts.Poscode=? ORDER BY posts.Poscode DESC LIMIT 60");
$result = array_merge($key, array($rate,$postcode));
$statement->execute($result);
When I replace $key = array(1,2); with $key = array($key); the query only fetches data for the first ID whereby I assume it converts the array into string.
$key also holds the value 1,2 in an array shown below:
$a=$data['sub'];
$key0=array();
foreach($a as $v=>$k)
{
$key0[]=$v;
}
$key2=implode(',',$key0);
$key = array($key2);
How do I make the PDO understand $key holds an array value and not a string?
I solve this problem always using named placeholders. I personally don't like the ? stuff. You need a placeholder for every value of your in.
See the sample code:
$key = array(1,2);
$pricing = "somePricing";
$postcode = "somePostcode";
$bindings = array();
$bindings[] = array(":pricing", $pricing, PDO::PARAM_STR);
$bindings[] = array(":postcode", $postcode, PDO::PARAM_STR);
$key_placeholders = array();
foreach($key as $k => $v) {
$placeholder = ":subid".$k;
$bindings[] = array($placeholder, $v, PDO::PARAM_INT);
$key_placeholders[] = $placeholder;
}
$sql = "SELECT * FROM posts "
. "WHERE posts.subid IN (". implode(",",$key_placeholders).") "
. "AND posts.pricing=:pricing "
. "AND posts.Poscode=:postcode "
. "ORDER BY posts.Poscode "
. "DESC LIMIT 60";
$statement = $pdo->prepare($sql);
foreach($bindings as $b) {
$statement->bindValue($b[0],$b[1],$b[2]);
}
$statement->execute();
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.