問題描述
背景
我正在嘗試編寫函數查詢
I'm trying to write a function query
query('type', 'parameters', 'bind_types')
我可以調用它來進行簡單的查詢.所有的mySQL查詢都在函數
which I can call to make simple queries. All the mySQL queries are in the function
grab_sql()
所有的綁定都發生在函數bind()
All the binding takes place in the function bind()
call_user_func_array
需要引用才能正常運行,所以我寫了 ref_arr
來適應.
call_user_func_array
needs references to function correctly so I wrote ref_arr
to accomodate.
問題是我沒有得到我需要的結果 - 它們發布在結果下方.我認為問題在于結果的綁定,正如我在這部分猜測的那樣.
Problem is that I'm not getting the results back that I need - they are posted below under results. I think the issue is in the binding of the reuslts as I kind of guessed on that part.
研究
- 關于預處理語句的信息此處
- 有關
call_user_func_array
的信息此處 莉> - 關于
call_user_func_array
引用必要性的信息這里
- Info on prepared statements here
- Info on
call_user_func_array
here - Info on the neccessity of references for
call_user_func_array
here
問題:如何修改此代碼以正確獲得正確的結果?
QUESTION: How can I modify this code to correctly get the correct results?
代碼
function ref_arr(&$arr)
{
$refs = array();
foreach($arr as $key => $value)
{
$refs[$key] = &$arr[$key];
}
return $refs;}
public function bind($query, $input_param, $btypes)
{
$a="test_var1";$b="test_var2";
$output_arr=array($a,$b);
$input_ref = $this->ref_arr($input_param);
$output_ref = $this->ref_arr($output_arr);
if($statement=mysqli_prepare(one::$db, $query))
{
array_unshift($input_ref, $statement, $btypes);
call_user_func_array("mysqli_stmt_bind_param", $input_ref);
mysqli_stmt_execute($statement);
array_unshift($output_ref, $statement);
call_user_func_array("mysqli_stmt_bind_result", $output_ref);
mysqli_stmt_fetch($statement);
var_dump($output_ref);
mysqli_stmt_close($statement);
}
}
public function grab($type)
{
switch($type)
{
case "validate_user":
$query="SELECT email,pass FROM cr WHERE email=? AND pass=?";
break;
case "another_query_type":
break;
}
return $query;
}
public function query($qtype, $arg_arr, $btypes)
{
return self::bind(self::grab_sql($qtype), $arg_arr, $btypes);
}
}
測試用例
<?php
require_once 'p0.php';
$db_ = new database();
$db_->query('validate_user',array('joe@gmail.com','Password'), 'ss');
?>
結果
值結果似乎是(最后兩個值)&NULL 和 &NULL.
The values result appears to be(last two values) &NULL and &NULL.
array(3) { [0]=> object(mysqli_stmt)#2 (9) {
["affected_rows"]=> int(-1) ["insert_id"]=> int(0) ["num_rows"]=> int(0) ["param_count"]=> int(2) ["field_count"]=> int(2) ["errno"]=> int(0) ["error"]=> string(0) "" ["sqlstate"]=> string(5) "00000" ["id"]=> int(1) } [1]=> &NULL [2]=> &NULL
}
推薦答案
是的,在 Mysqli 中編寫通用的 bind-this-array-into-a-query 是一個皇家 PITA.當我編寫 Zend Framework 的 mysqli 適配器時,我最終讓它工作了,但這需要大量的工作.歡迎您查看代碼.我看到了一個主要區別,這是我如何做參考的:
Yes, writing a generic bind-this-array-into-a-query in Mysqli is a royal PITA. I eventually got it to work when I was coding Zend Framework's mysqli adapter, but it took a lot of work. You're welcome to take a look at the code. I see one chief difference, here's how I did the refs:
$stmtParams = array();
foreach ($params as $k => &$value) {
$stmtParams[$k] = &$value;
}
call_user_func_array(
array($this->_stmt, 'bind_param'), // mysqli OO callback
$stmtParams
);
這與您的略有不同.我想知道在您的代碼中,引用運算符 &
是否比數組索引 []
運算符綁定得更緊密.
This is slightly different than yours. I wonder if in your code the ref operator &
binds more tightly than the array index []
operator.
注意我還必須在 foreach
和賦值中使用 ref 運算符.我一直不明白為什么,但這是唯一可行的方法.PHP 引用非常神秘且難以理解.
Note I also had to use the ref operator both in the foreach
and in the assignment. I never quite understood why, but this was the only way it would work. PHP refs are pretty mysterious and hard to understand.
如果您堅持使用啟用了 Mysqli 但未啟用 PDO 的環境,這可能不是一個可行的建議,但您確實應該考慮改用 PDO.PDO 會為您處理很多工作;您可以簡單地將一組值傳遞給 PDOStatement::execute()
用于帶參數的準備好的查詢.對我來說,將 PDO 用于這種特殊用途比使用 mysqli 要容易得多.
This may not be a viable suggestion if you're stuck with an environment that has Mysqli enabled but not PDO, but you should really consider using PDO instead. PDO takes care of a lot of that work for you; you can simply pass an array of values to PDOStatement::execute()
for a prepared query with parameters. For me, it was far easier to use PDO for this particular use than mysqli.
$pdoStmt->execute( array('joe@gmail.com','Password') ); // it's that easy
PS:我希望你 不是以明文形式存儲密碼.
這篇關于mysqli_prepare 與 PDO的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!