簡體   English   中英

如何回顯 MySQLi 准備好的語句?

[英]How to echo a MySQLi prepared statement?

我現在正在玩 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 對數據做了什么。 但是我想通過這種方式我可以快速查看所有數據是否都存在並且位於正確的位置,並且與手動將變量擬合到查詢中相比,它可以為我節省一些時間 - 對於許多變量來說這可能會很痛苦。

我不認為你可以 - 至少不是你希望的方式。 您要么必須自己構建查詢字符串並執行它(即不使用語句),要么尋找或創建支持該功能的包裝器。 我使用的是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')

過去我一直在努力解決這個問題。 所以為了解決這個問題,我寫了一個小函數來根據 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 准備語句檢查器

我最近更新了這個項目以包含 Composer 集成、單元測試並更好地處理通過引用接受參數(這需要更新到 php 5.6)。


為了響應我在使用PDO創建的項目中收到的解決相同問題的請求,我在 github 上創建了mysqli的擴展,它似乎解決了您的問題:

https://github.com/noahheck/E_mysqli

這是一組擴展本機mysqlimysqli_stmt類的類,允許您通過將綁定參數插入到准備好的查詢中來查看要在數據庫服務器上執行的查詢示例,然后讓您訪問結果查詢字符串作為stmt對象的新屬性:

$mysqli  = new E_mysqli($dbHost, $dbUser, $dbPass, $dbName);

$query = "UPDATE registration SET name = ?, email = ? WHERE entryId = ?";

$stmt = $mysqli->prepare($query);

$stmt->bindParam("ssi", $_POST['name'], $_POST['email'], $_POST['entryId']);

$stmt->execute();

echo $stmt->fullQuery;

會導致:

UPDATE registration SET name = 'Sue O\'reilly', email = 'sue.o@example.com' WHERE entryId = 5569

請注意,考慮到 db 服務器上的字符集,fullQuery 中的值被適當地轉義,這應該使此功能適用於例如日志文件、備份等。

使用它有一些注意事項,在 github 項目的自述文件中概述,但是,特別是對於開發、學習和測試,這應該提供一些有用的功能。

正如我在 github 項目中概述的那樣,我沒有使用mysqli擴展的任何實踐經驗,並且該項目是應其姊妹項目用戶的要求創建的,因此可以從使用此擴展的開發人員提供的任何反饋生產將不勝感激。

免責聲明- 正如我所說,我做了這個擴展。

只需將其設置為 die 並輸出最后執行的查詢。 錯誤處理應該為您提供有意義的信息,您可以使用這些信息來修復您的查詢。

您可以在 mysql 服務器上打開日志查詢。 只需執行命令:

sql> SHOW VARIABLES LIKE "general_log%";
sql> SET GLOBAL general_log = 'ON';

並觀察日志文件中的查詢。 測試后關閉注銷:

sql> SET GLOBAL general_log = 'OFF';

我能夠使用var_dump()至少獲得有關 mysqli_stmt 的更多信息:

  $postmeta_sql = "INSERT INTO $db_new.wp_postmeta (post_id, meta_key, meta_value) VALUES (?, ?, ?)";
  $stmt = $new_conn->prepare($postmeta_sql);
  $stmt->bind_param("sss", $post_id, $meta_key, $meta_value);
  echo var_dump($stmt);
  $stmt->execute();
  $stmt->close();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM