使用变量选项构建PHP / MySQL搜索查询

时间:2015-01-21 16:29:40

标签: php mysql

我正在尝试做什么

我有一个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();

问题

在纸面上这个方法应该有效,但我更愿意使用预备语句。执行此操作的唯一方法似乎是在每个mysql_real_escape_string()变量上使用$_GET,因为当我不知道有多少变量时,我无法弄清楚如何使用execute(array($val1,$val2...))使用

如果可能,我如何利用预准备语句来清理$_GET变量?

3 个答案:

答案 0 :(得分:2)

您可以传递execute()关联数组。您只需在$_GET中为每个值添加占位符,然后将整个数组传递给execute()

因此,首先创建查询字符串,准备它,然后调用execute()

P.S。你忘记了WHERE。没有AND,您无法使用WHERE。我建议像这样构建查询:

// 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'];

答案 1 :(得分:1)

您可以使用bindParam

处理可变数量的查询参数
  

将PHP变量绑定到用于准备语句的SQL语句中的相应命名或问号占位符。

文档here

修改 要使用LIKEHow do I create a PDO parameterized query with a LIKE statement?

答案 2 :(得分:1)

不是连接,这是冗长且容易出错的,而是填充两个数组 - 占位符和参数 - 然后在最后插入所有占位符:

$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);