我需要一个很好的结构来构建查询,其中搜索参数是使用 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';
}
?>
答案 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;
}