将mysql_动态查询转换为PDO Prepared语句

时间:2015-04-26 12:07:54

标签: php pdo prepared-statement

我正在使用预设语句将之前使用mysql_的脚本转换为 PDO ,无论是否可行。使用旧学校mysql_,使用mysql_real_escape_string进行此类动态查询很容易,并将所有查询连接成一个长查询。

似乎PDO的预备声明要困难得多。我在下面这个脚本中对这个动态查询感到不满。

<?php
$filter_day=$_GET['filter_day'];
$filter_month=$_GET['filter_month'];
$filter_year=$_GET['filter_year'];
$search=$_GET['search'];

try{
  $db=new PDO("mysql:host=localhost;dbname=dbname;charset=utf8", 'dbuser', 'dbpassword');
  $db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
}catch(PDOException $pe){
  die("Could not connect to the database dbname :" . $pe->getMessage());
}

$datecondition='';
if(strlen($filter_day)>0){ $datecondition.=" AND DAY(registration_date)=:filter_day ";}
if(strlen($filter_month)>0){ $datecondition.=" AND MONTH(registration_date)=:filter_month ";}
if(strlen($filter_year)>0){ $datecondition.=" AND YEAR(registration_date)=:filter_year ";}

$searchcondition='';
if(strlen($search)>2){ $searchcondition.=" AND (first_name LIKE :search OR last_name LIKE :search OR department LIKE :search OR position LIKE :search) "; }

$param=array('filter_day'=>$filter_day, 'filter_month'=>$filter_month, 'filter_year'=>$filter_year, 'search'=>"%$search%");
$q=$db->prepare("SELECT * FROM Users WHERE user_status='ENABLED' $datecondition $searchcondition LIMIT 0,30");
$q->execute($param);

?>

案例1:所有参数都包含在最终查询中。

:search参数只会被绑定一次,其余的:search仍会出现在最终查询中。

SELECT * 
FROM Users 
WHERE user_status='ENABLED' 
AND DAY(registration_date)=:filter_day AND MONTH(registration_date)=:filter_month AND YEAR(registration_date)=:filter_year 
AND (first_name LIKE :search OR last_name LIKE :search OR department LIKE :search OR position LIKE :search) 
LIMIT 0,30

案例2:并非所有参数都包含在最终查询中。

SELECT * 
FROM Users 
WHERE user_status='ENABLED' 
AND (first_name LIKE :search OR last_name LIKE :search OR department LIKE :search OR position LIKE :search) 
LIMIT 0,30

以上查询仅搜索某些字符串,但不过滤任何日期。但是,未使用的:filter_day :filter_month:filter_year包含在绑定数组中。它无法执行并返回此错误消息:

  

警告:PDOStatement :: execute()[pdostatement.execute]:   SQLSTATE [HY093]:参数号无效:绑定变量数   与令牌数量不匹配

我可能会在代码中添加更多if / elses以逃避这一点,但我意识到只有1个查询才会有太多代码。

这不是最佳的流程/查询,但我不知道如何解决它。请帮我优化它或提供一些例子。非常感谢!

0 个答案:

没有答案