mysqli:绑定参数,其中搜索参数是有条件的

时间:2013-07-04 23:08:30

标签: php mysqli

我需要一个很好的结构来构建查询,其中搜索参数是使用 mysqli prepared statement 条件的。 $query -> bind_param('sss',$date,$time,$place);

我不知道如何在以后按顺序应用'sss''$date,$time,$place'参数。你能把它们作为变量传递吗?

旧MySQL方式:

<?php

// date is obligatory

$date = mysql_real_escape_string($_GET["date"]);

$query="SELECT * FROM dbase WHERE date='$date'"; 

// time field is custom

if(!empty($_GET["time"])) {

    $time= mysql_real_escape_string($_GET["time"]);
    $buildQuery[] = "time='$time'";

}

// place field is also custom

if(!empty($_GET["place"])) {

    $place= mysql_real_escape_string($_GET["place"]);
    $buildQuery[] = "place='$place'";

}

// building query

if(!empty($build)) {

    $query .= ' AND '.implode(' AND ',$build).' ORDER BY date';

}

?>

3 个答案:

答案 0 :(得分:1)

这是一个很好的案例,PDO比MySQLi容易得多:

$query="SELECT * FROM dbase";
$terms = array("date" => $date);
$params = array();

// time field is custom

if(isset($_GET["time"])) {
    $terms["sType"] = $time;
}

// place field is also custom

if(isset($_GET["place"])) {
    $terms["place"] = $place;  
}

// building query

if(!empty($terms)) {
    $query .= "WHERE " . implode(" AND ", 
        array_map(function($term) { return "$term = ?"; }, array_keys($terms));
    $params = array_values($terms);
}
$query .= "ORDER BY date";

$stmt = $pdo->pepare($query);
$stmt->execute($params);

PS:我不得不质疑您的sType列是否包含时间地点。您似乎正在打破关系数据库最佳实践。除非它只是一个错字。

答案 1 :(得分:0)

未经测试,但你应该可以做这样的事情

$types = array();
$vals = array();

if(isset($_GET["time"])) {
    $types[] = 's';
    $vals[] = $_GET["time"];
    $buildQuery[] = "sType = ?";
}

//...etc...

$args = array_merge(array(join($types)), $vals);
$callable = array($mysqli, 'bind_param');
call_user_func_array($callable, $args));

http://php.net/manual/en/language.types.callable.php

但是,还有另一种方法。只需在sql中使用逻辑:

select *
from tbl
where (date = ? or ? = '')
  and (time = ? or ? = '')
  and (place = ? or ? = '')

以上假设您将每个arg绑定两次,并将它们绑定为字符串,但如果查询字符串参数未设置则绑定空字符串...如果需要,可以通过类似{{1 }}

(date = ? or ? is null)

ps,mysql优化器将简化这个简单的逻辑。

答案 2 :(得分:0)

根据山羊的回复,这里有一个完整且经过测试的答案,其中包含UPDATE语句,其中要更新的字段是有条件的。我使用了一个非常简单的表结构,包含3个字段:ID(自动增量),Varchar1(varchar255)和Varchar2(varchar255)。在此脚本中,我想更新前三个记录的两个varchar字段。根据此脚本,有条件地添加或删除要更新的字段非常容易。

$mysqli = new mysqli(...);

$types = array();
$vals = array();
$query = array();

// varchar1
$types[] = 's';
$vals[] = 'foo1';
$query[] = "varchar1=?";

// varchar2
$types[] = 's';
$vals[] = 'foo2';
$query[] = "varchar2=?";

$sql = "UPDATE test SET ".implode(",", $query)." WHERE id IN (1,2,3)";
$stmt = $mysqli->prepare($sql);

$args = array_merge(array(implode($types)), $vals);

$callable = array($stmt, 'bind_param');
call_user_func_array($callable, refValues($args));

$stmt->execute();

function refValues($arr) {
    if (strnatcmp(phpversion(),'5.3') >= 0) //Reference is required for PHP 5.3+ 
    { 
        $refs = array(); 
        foreach($arr as $key => $value) 
            $refs[$key] = &$arr[$key]; 
        return $refs; 
    } 
    return $arr; 
}