0

我需要一个好的结构来构建查询,其中搜索参数是使用mysqli 准备好的语句有条件的。$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';

}

?>
4

3 回答 3

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专栏同时包含时间地点。似乎您正在破坏关系数据库的最佳实践。除非它只是一个错字。

于 2013-07-04T23:17:10.563 回答
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 绑定两次,并将它们绑定为字符串,但如果未设置查询字符串参数,则绑定一个空字符串...如果需要,您也可以通过类似(date = ? or ? is null).

$mysqli->bind_param('ssssss', $date,$date, $time,$time, $place,$place);

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

于 2013-07-04T23:58:21.333 回答
0

根据 goat 的回复,这是一个完整且经过测试的答案,其中包含 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; 
}
于 2016-03-14T13:33:33.820 回答