我在我的一个PDO类中有一个函数,当我在WHERE子句中写两个条件时,它执行不正确的查询。
我曾尝试在数组中编写WHERE,但它给我一个未知的列错误,所以我用字符串格式编写了条件。如果我编写单个条件但是如果我写了多个条件则生成问题,则查询工作正常。
我的函数中有以下代码:
public function getNewsByDate($date, $lastdate){
$args = array(
'fields' => array(
'news.id',
'news.title',
'news.summary',
'news.story',
'news.image',
'news.added_by',
'news.status',
'news.added_date',
'news.news_category',
'(SELECT users.full_name FROM users WHERE id = news.added_by) as author',
),
'where' => (' date BETWEEN "'.$date.'" AND "'.$lastdate.'"') AND (' archieveCategory = "magazine" '),
);
return $this->select($args, true);
}
当我调试上面的代码时,我得到的sql如下所示:
SELECT news.id, news.title, news.summary, news.story, news.image,
news.added_by, news.status, news.added_date, news.news_category,
(SELECT users.full_name FROM users WHERE id = news.added_by) as author
FROM news
WHERE 1
ORDER BY news.id DESC
而且,我在选择查询中有以下代码:
final protected function select($args = array(), $is_die = false){
try {
$this->sql = "SELECT ";
if (isset($args['fields'])) {
if (is_array($args['fields'])) {
$this->sql .= implode(', ', $args['fields']);
} else {
$this->sql .= $args['fields'];
}
} else {
$this->sql .= " * ";
}
$this->sql .= " FROM ";
if (!isset($this->table) || empty($this->table)) {
throw new Exception("Table not set");
}
$this->sql .= $this->table;
/*Join Query*/
if (isset($args['join']) && !empty($args['join'])) {
$this->sql .= " ".$args['join'];
}
/*Join Query*/
if (isset($args['where']) && !empty($args['where'])) {
if (is_array($args['where'])) {
$temp = array();
foreach ($args['where'] as $column_name => $data) {
if (!is_array($data)) {
$data = array(
'value' => $data,
'operator' => '=',
);
}
$str = $column_name.' '.$data['operator'].' :'.str_replace('.', '_', $column_name);
$temp[] = $str;
}
$this->sql .= " WHERE ".implode(' AND ', $temp);
} else {
$this->sql .= " WHERE ".$args['where'];
}
}
/*Group*/
if (isset($args['group_by']) && !empty($args['group_by'])) {
$this->sql .= " GROUP BY ".$args['group_by'];
}
/*Group*/
/*Order*/
if (isset($args['order_by']) && !empty($args['order_by'])) {
$this->sql .= " ORDER BY ".$args['order_by'];
} else {
$this->sql .= " ORDER BY ".$this->table.".id DESC";
}
/*Order*/
/*Limit*/
if (isset($args['limit']) && !empty($args['limit'])) {
if (is_array($args['limit'])) {
$this->sql .= " LIMIT ".$args['limit'][0].",".$args['limit'][1];
} else {
$this->sql .= " LIMIT ".$args['limit'];
}
}
/*Limit*/
$this->stmt = $this->conn->prepare($this->sql);
if (is_array($args['where']) || is_object($args['where'])){
foreach ($args['where'] as $column_name => $data) {
$value = is_array($data) ? $data['value'] : $data; //check if passed where statement was an array, fetch value if so
if (is_int($value)) {
$param = PDO::PARAM_INT;
}elseif (is_bool($value)) {
$param = PDO::PARAM_BOOL;
}elseif (is_null($value)) {
$param = PDO::PARAM_NULL;
}else {
$param = PDO::PARAM_STR;
}
if ($param) {
$this->stmt->bindValue(":".str_replace('.', '_', $column_name), $value, $param);
}
}
}
if ($is_die) {
echo $this->sql;
}
$this->stmt->execute();
$data = $this->stmt->fetchAll(PDO::FETCH_OBJ);
return $data;
} catch (PDOException $e) {
error_log(
date('Y-m-d h:i:s A').", Select Query: ".$e->getMessage()."\r\n"
, 3, ERROR_PATH.'/error.log');
return false;
} catch (Exception $e) {
error_log(
date('Y-m-d h:i:s A').", General: ".$e->getMessage()."\r\n"
, 3, ERROR_PATH.'/error.log');
return false;
}
}
我的预期结果是这样的:
SELECT news.id, news.title, news.summary, news.story, news.image,
news.added_by, news.status, news.added_date, news.news_category,
(SELECT users.full_name FROM users WHERE id = news.added_by) as author
FROM news WHERE date BETWEEN "2019-03-01" AND "2019-03-31" AND archeiveCategory = "magazine"
ORDER BY news.id DESC
在数组的where
元素中,引号应该是......
'where' => '( date BETWEEN "'.$date.'" AND "'.$lastdate.'") AND ( archieveCategory = "magazine" )',
在你的版本中
'where' => (' date BETWEEN "'.$date.'" AND "'.$lastdate.'"') AND (' archieveCategory = "magazine" '),
你可以看到引号在开盘后(和收盘前)开始,这意味着(我认为)你得到的逻辑相当于
'where' => ('some string') AND ('another string'),
这是1
在输出中的来源。