我想做什么
我有一个SQL表,其中包含客户网站的工作机会列表。
我正在尝试创建一个搜索表单,但并非所有字段都必须填写。
可能的值为:
title
= 职位名称
location
= 作业的位置
sal1
= 所需薪水的底部括号
sal2
= 所需薪水的最高括号
《守则》
$query = 'SELECT * FROM `jobs`';
if($_GET['title']!='') $query.= ' AND `title` LIKE %'.$_GET['title'];
if($_GET['location']!='') $query.= ' AND `location`='.$_GET['location'];
if($_GET['sal1']!='') $query.= ' AND `sal1`>='.$_GET['sal1'];
if($_GET['sal2']!='') $query.= ' AND `sal2`<='.$_GET['sal2'];
$stmt=$dbh->prepare($query.' ORDER BY `date` DESC');
$stmt->execute();
问题
在纸面上,这种方法应该有效,但我更喜欢使用预准备的语句。执行此操作的唯一方法似乎是在每个$_GET
变量上使用mysql_real_escape_string()
,因为当我不知道正在使用多少变量时,我无法弄清楚如何使用execute(array($val1,$val2...))
。
如果可能,如何使用预准备语句来清理$_GET
变量?
您可以传递execute()
关联数组。 您只需为所需的$_GET
中的每个值添加占位符,然后将整个数组传递给execute()
因此,首先创建查询字符串,准备它,然后调用 execute()
。
附言你忘了WHERE
. 没有WHERE
就无法使用AND
。 我建议像这样构建查询:
// Base query
$query = 'SELECT * FROM `jobs`';
// WHERE clauses
$where = array();
// Don't concat GET values, use placeholders
if($_GET['title'] != '') $where[] = '`title` LIKE CONCAT("%", :title)';
if($_GET['location'] != '') $where[] = '`location` = :location';
if($_GET['sal1'] != '') $where[] = '`sal1`>= :sal1';
if($_GET['sal2'] != '') $where[] = '`sal2`<= :sal2';
// Combine the WHERE clauses
if(count($where) > 0) $query .= " WHERE ".implode(' AND ', $where);
// Prepare the query
$stmt = $dbh->prepare($query.' ORDER BY `date` DESC');
// Run it with the entered parameters
$stmt->execute($_GET);
注意:我在第一句中CONCAT("%", :title)
。 这是因为LIKE
需要一个字符串。 它想要类似'%test'
的东西(注意%
是字符串的一部分)。 我在MySQL中使用了CONCAT
,而不是在PHP中使用$_GET['title'] = '%'.$_GET['title'];
。
您可以使用bindParam
处理可变数量的查询参数:
将 PHP 变量绑定到用于准备语句的 SQL 语句中的相应命名或问号占位符。
文档在这里。
编辑使用 LIKE
: 如何使用 LIKE 语句创建 PDO 参数化查询?
不要连接,这是冗长且容易出错的,而是随时填充两个数组 - 占位符和参数 - 并在末尾一次插入所有占位符:
$where = array();
$params = array();
if(!empty($_GET['title'])) {
$where []= '`title` LIKE ?';
$params []= '%' . $_GET['title'];
}
if(!empty($_GET['location'])) {
$where []= '`location` = ?';
$params []= $_GET['location'];
}
// etc
if(!count($where))
// error
$where = implode(' AND ', $where);
$query = "SELECT * FROM `jobs` WHERE $where ORDER BY `date` DESC";
$stmt=$dbh->prepare($query);
$stmt->execute($params);