如何回应MySQLi准备的声明?

2022-08-30 10:17:06

我目前正在玩MySQLi,试图弄清楚它是如何工作的。在我当前的项目中,我总是喜欢在编码时回显查询字符串,只是为了确保一切都是正确的,并快速调试我的代码。但。。。我如何使用准备好的MySQLi声明来做到这一点?

例:

$id = 1;
$baz = 'something';

if ($stmt = $mysqli->prepare("SELECT foo FROM bar WHERE id=? AND baz=?")) {
  $stmt->bind_param('is',$id,$baz);
  // how to preview this prepared query before acutally executing it?
  // $stmt->execute();
}

我一直在浏览这个列表(http://www.php.net/mysqli),但没有任何运气。


编辑

好吧,如果从MySQLi内部无法做到这一点,也许我会坚持这样的事情:

function preparedQuery($sql,$params) {
  for ($i=0; $i<count($params); $i++) {
    $sql = preg_replace('/\?/',$params[$i],$sql,1);
  }
  return $sql;
}

$id = 1;
$baz = 'something';

$sql = "SELECT foo FROM bar WHERE id=? AND baz=?";

echo preparedQuery($sql,array($id,$baz));

// outputs: SELECT foo FROM bar WHERE id=1 AND baz=something

显然远非完美,因为它仍然是多余的 - 我想防止的事情 - 它也没有让我了解MySQLi正在如何处理数据。但我想通过这种方式,我可以快速查看所有数据是否存在并且位于正确的位置,与手动将变量放入查询中相比,这将为我节省一些时间 - 这对许多var来说可能是一种痛苦。


答案 1

我不认为你可以 - 至少不是以你所希望的方式。您必须自己构建查询字符串并执行它(即不使用语句),或者查找或创建支持该功能的包装器。我使用的那个是Zend_Db,这就是我这样做的方式:

$id = 5;
$baz = 'shazam';
$select = $db->select()->from('bar','foo')
                       ->where('id = ?', $id)
                       ->where('baz = ?', $baz); // Zend_Db_Select will properly quote stuff for you
print_r($select->__toString()); // prints SELECT `bar`.`foo` FROM `bar` WHERE (id = 5) AND (baz = 'shazam')

答案 2

我过去曾与这个斗争过。因此,为了解决这个问题,我写了一个小函数,根据SQL,标志和变量为我构建SQL。

//////////// Test Data //////////////
$_GET['filmID'] = 232;
$_GET['filmName'] = "Titanic";
$_GET['filmPrice'] = 10.99;

//////////// Helper Function //////////////
function debug_bind_param(){
    $numargs = func_num_args();
    $numVars = $numargs - 2;
    $arg2 = func_get_arg(1);
    $flagsAr = str_split($arg2);
    $showAr = array();
    for($i=0;$i<$numargs;$i++){
        switch($flagsAr[$i]){
        case 's' :  $showAr[] = "'".func_get_arg($i+2)."'";
        break;
        case 'i' :  $showAr[] = func_get_arg($i+2);
        break;  
        case 'd' :  $showAr[] = func_get_arg($i+2);
        break;  
        case 'b' :  $showAr[] = "'".func_get_arg($i+2)."'";
        break;  
        }
    }
    $query = func_get_arg(0);
    $querysAr = str_split($query);
    $lengthQuery = count($querysAr);
    $j = 0;
    $display = "";
    for($i=0;$i<$lengthQuery;$i++){
        if($querysAr[$i] === '?'){
            $display .= $showAr[$j];
            $j++;   
        }else{
            $display .= $querysAr[$i];
        }
    }
    if($j != $numVars){
        $display = "Mismatch on Variables to Placeholders (?)"; 
    }
    return $display;
}

//////////// Test and echo return //////////////

echo debug_bind_param("SELECT filmName FROM movies WHERE filmID = ? AND filmName = ? AND price = ?", "isd", $_GET['filmID'], $_GET['filmName'], $_GET['filmPrice']);

我还构建了一个小的在线工具来提供帮助。

Mysqli Prepare Statement Checker


推荐