摘要
我目前使用"$search_field LIKE '$this->db->escape_like_str($search_string)%'";
來轉義動態創建的搜索查詢。生成的SQL語句不會產生任何錯誤,但也不會產生任何結果。以下是我正在做的事情的詳細描述。如何正確地轉義mysql「search/like」查詢?
詳細
我使用的jqGrid和搜索功能。當用戶輸入搜索條件時,它將$filters
json對象發佈到我的服務器。然後我解析它並創建一個SQL語句來獲取請求的數據。
這裏是逃避傳入搜索數據的代碼(這也是問題區域):
$search_string_like = $this->CI->db->escape_like_str($search_string);
$operator['bw'] = "$search_field LIKE '$search_string_like%'"; //begins with
下面是導致SQL語句:
SELECT *
FROM player_data_temp_table
WHERE first_name LIKE '\'zech\'%' AND last_name LIKE '\'camp\'%'
ORDER BY date_won desc
LIMIT 0 , 15
此查詢不丟任何錯誤,但它也不起作用。當我在phpmyadmin中直接運行類似的查詢時,我得到了MySQL returned an empty result set (i.e. zero rows).
,即使我知道有結果可以找到。如果我只是從first_name LIKE '\'zech\'%'
中刪除反斜槓和單引號使其成爲first_name LIKE 'zech%'
,那麼我會得到預期的結果。我的擔心是,這不再適當逃脫,對吧?
用於構建查詢
摘要
一種可變,$filters
,與如本{"groupOp":"AND","rules":[{"field":"first_name","op":"bw","data":"zech"}]}
數據代碼被傳遞到build_where_clause($filters)
。 build_where_clause
返回完整的$where
聲明,然後在模型中用於創建最終的SQL搜索語句。
jqgrid_lib.php
class jqgrid_lib
{
private $CI;
public function __construct()
{
$this->CI =& get_instance();
}
/**
* Function takes a json string with search rules and turns it into an sql statement.
*
* To use this function make sure you set stringResult: true, see example below:
* $("#list").jqGrid('filterToolbar',{stringResult: true});
* @param json string
* @author zechdc
*/
public function build_where_clause($filters)
{
$sql_fragments = array();
$filters = json_decode($filters);
$rules = $filters->rules;
$group_op = $filters->groupOp;
//loop through each rule and create an sql statement
foreach($rules as $rule)
{
$temp_sql = $this->create_search_field($rule->field, $rule->data, $rule->op);
array_push($sql_fragments, $temp_sql);
}
//combine all sql fragments with the group_operator
$data['sql'] = implode(' ' . $group_op . ' ', $sql_fragments);
return $data;
}
/**
* Takes a field, string and search condition and turns it into a sql search statement
*
* To use this function make sure you set stringResult: true, see example below:
* $("#list").jqGrid('filterToolbar',{stringResult: true});
* @param json string
* @return string
* @author zechdc
*/
public function create_search_field($search_field, $search_string, $search_operator)
{
//$search_field = $this->CI->db->escape($search_field); //escaping the column breaks it.
$search_string = $this->CI->db->escape($search_string);
$search_string_like = $this->CI->db->escape_like_str($search_string);
//$search_string_like = $search_string;
$operator['eq'] = "$search_field=$search_string"; //equal to
$operator['ne'] = "$search_field<>$search_string"; //not equal to
$operator['lt'] = "$search_field < $search_string"; //less than
$operator['le'] = "$search_field <= $search_string "; //less than or equal to
$operator['gt'] = "$search_field > $search_string"; //less than
$operator['ge'] = "$search_field >= $search_string "; //less than or equal to
$operator['bw'] = "$search_field LIKE '$search_string_like%'"; //begins with
$operator['bn'] = "$search_field NOT LIKE '$search_string_like%'"; //not begins with
$operator['in'] = "$search_field IN ($search_string)"; //in
$operator['ni'] = "$search_field NOT IN ($search_string)"; //not in
$operator['ew'] = "$search_field LIKE '%$search_string_like'"; //ends with
$operator['en'] = "$search_field NOT LIKE '%$search_string_like%'"; //not ends with
$operator['cn'] = "$search_field LIKE '%$search_string_like%'"; //in
$operator['nc'] = "$search_field NOT LIKE '%$search_string_like%'"; //not in
$operator['nu'] = "$search_field IS NULL"; //is null
$operator['nn'] = "$search_field IS NOT NULL"; //is not null
if(isset($operator[$search_operator]))
{
//set the sql search statement
return $operator[$search_operator];
}
}
}
型號
/*
* Gets all columns from table with limit and sort order set dynamically
*/
function get_specific($sidx, $sord, $start, $limit, $where = NULL)
{
$result = FALSE;
if($where)
{
$where = ' WHERE ' . $where;
}
// usually I dont do select all but since this whole table is temp and only holds the needed data
// then just do select all.
$sql = "SELECT *
FROM player_data_temp_table
$where
ORDER BY $sidx $sord
LIMIT $start , $limit";
$q = $this->db->query($sql);
if($this->db->affected_rows() > 0)
{
$result = $q->result();
}
return $result;
}
UPDATE /答:
它看起來像我固定的問題。在這個模型中我去掉了手工製作$ sql語句,並與
if($where)
{
$this->db->where($where);
}
$this->db->order_by($sidx, $sord);
$q = $this->db->get('player_data_temp_table', $limit, $start);
這似乎正確轉義所有的變量包括在$我的列名where語句替換它。
這個子句有個問題:「我只是從'first_name LIKE'\'zech \'%''刪除斜槓,使它成爲'first_name LIKE'zech%''」。我想你的意思是「我只是刪除反斜槓**和單引號**」? – ruakh 2011-12-20 23:08:00
只是爲了澄清,您在escape_like_str()函數調用之前或之後提供的查詢字符串? – 2011-12-20 23:09:45
@ruakh是的你是對的,我會更新我的文章。 – zechdc 2011-12-20 23:10:22