多次调用 $stmt->bind_param
multiple calls to $stmt->bind_param
我正处于一种情况,我想构建一个代码,它以这种格式获取 $bindParam
变量:
$bindParams = [$type1 => $param1, $type2 => $param2, ... ]
我想构建一些代码,将这些参数动态添加到准备好的语句中。
这是我到目前为止构建的代码:
$mysql = new mysqli("localhost", "root", "", "db1");
$stmt = $mysql->prepare($sql);
foreach($bindParams as $type => $data) {
$stmt->bind_param($type, $data);
}
$stmt->execute();
$result = $stmt->get_result();
// and after perhaps twiddling with the result set, but this is not the case .....
以你为例
$sql = "INSERT INTO table1 (name, age) VALUES (?,?);"
和
$bindParams = ["s" => "hello", "i" => 15]
这并不总是这种结构,它可以更改为例如 $bindParams = ["s" => "hello", "i" => 15, "d" => 22.5]
等 $sql
分别更改。
在编译器第一次前往 $stmt->bind_param($type, $data);
firefox 后刷新此错误:
Warning: mysqli_stmt::bind_param(): Number of variables doesn't match number of parameters in prepared statement in D:\PHP\tr.php on line 23
我知道 PDO 支持,如前所述 here at the end of the page. 但也许如您所料,我不是 PDO 的粉丝,所以 ;)
我的另一个选择是使用 php 中可用的 eval()
解决方法,但这超出了我的想法。
还有其他方法吗?
我使用类似这样的东西来进行动态过程调用。
调用示例:
$mapi = new MySQLIAPI($con);
$mapi->BeginProc();
$mapi->AddParameter("user", $usern, "s");
$mapi->AddParameter("email", $email, "s");
$mapi->AddParameter("passwd", $pwd, "s");
$id = $mapi->CallProc("ij_create_user");
$id = $id[0];
if(isset($id['mysql_error']) || isset($id["error"])){
return "error";
}
return $id["id"];
示例Class:
class MySQLIAPI
{
private $con = null;
private $Variables = null;
private $values = null;
private $types = null;
private $vQu = null;
private $stmt = null;
function __construct($dbc)
{
$this->con = $dbc;
$this->Variables = [];
$this->values = [];
$this->types = [];
$this->vQu = [];
}
function BeginProc()
{
$this->stmt = $this->con->stmt_init(); // initialize statement
}
function AddParameter($key, $val, $type)
{
$this->Variables[] = "@" . $key;
$this->values[] = $val;
$this->types[] = $type;
$this->vQu[] = "?";
}
//KeyPair is v = the value, t = the type s or d
function CallProc($Proc) {
$out_var = null;
$call = "";
if(sizeof($this->values) > 0)
$call = "CALL ".$Proc."(".implode(",", (array)$this->vQu).")";
else
$call = "CALL ".$Proc."()";
if($this->stmt->prepare($call));//call stored procedure with database server session variable
{
if(sizeof($this->values) > 0) {
$params = array_merge(array(implode("", $this->types)), $this->values);
call_user_func_array(array($this->stmt, 'bind_param'), $this->refValues($params));
}
$this->stmt->execute();
$result = $this->stmt->get_result();
/* Error Checking */
$mySQLiError = mysqli_stmt_error($this->stmt);
if ($mySQLiError != "") {
$this->resetStmt();
$this->stmt->close();
$this->stmt = null;
return array('mysql_error' => $mySQLiError);
}
while ($row = $result->fetch_array(MYSQLI_ASSOC))
{
$out_var[] = $row;
}
$result->free();
while($this->stmt->more_results())
{
$this->stmt->next_result();
}
$this->resetStmt();
$this->stmt->close();
$this->stmt = null;
}
return $out_var;
}
private 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;
}
private function resetStmt()
{
//Reset Params
$this->Variables = array();
$this->values = array();
$this->types = array();
$this->vQu = array();
}
}
遗憾的是 mysqli
不支持此功能。一遍又一遍地调用该函数会覆盖这些值,因此当您显然拥有更多参数时,您只能绑定一个参数。
有几种方法可以解决这个问题
- 切换到 PDO。您可以使用
对每个函数调用进行一次绑定
- 将参数绑定为一个聚合
$sqltype = '';
$sqldata = [];
foreach($bindParams as $type => $data) {
$sqltype .= $type;
$sqldata[] = &$data; // MUST be a reference
}
array_unshift($sqldata, $sqltype); // prepend the types
call_user_func_array([$stmt, 'bind_param'], $sqldata);
我遇到了同样的问题,找到了一个更简单的答案:
$array_of_values = array( "Brasil", "Argentina" );
$types = "ss";
$mysqli_stmt->bind_param( $types, ...$array_of_values );
这称为 "argument unpacking",从 PHP 5.6
开始可用
我正处于一种情况,我想构建一个代码,它以这种格式获取 $bindParam
变量:
$bindParams = [$type1 => $param1, $type2 => $param2, ... ]
我想构建一些代码,将这些参数动态添加到准备好的语句中。
这是我到目前为止构建的代码:
$mysql = new mysqli("localhost", "root", "", "db1");
$stmt = $mysql->prepare($sql);
foreach($bindParams as $type => $data) {
$stmt->bind_param($type, $data);
}
$stmt->execute();
$result = $stmt->get_result();
// and after perhaps twiddling with the result set, but this is not the case .....
以你为例
$sql = "INSERT INTO table1 (name, age) VALUES (?,?);"
和
$bindParams = ["s" => "hello", "i" => 15]
这并不总是这种结构,它可以更改为例如 $bindParams = ["s" => "hello", "i" => 15, "d" => 22.5]
等 $sql
分别更改。
在编译器第一次前往 $stmt->bind_param($type, $data);
firefox 后刷新此错误:
Warning: mysqli_stmt::bind_param(): Number of variables doesn't match number of parameters in prepared statement in D:\PHP\tr.php on line 23
我知道 PDO 支持,如前所述 here at the end of the page. 但也许如您所料,我不是 PDO 的粉丝,所以 ;)
我的另一个选择是使用 php 中可用的 eval()
解决方法,但这超出了我的想法。
还有其他方法吗?
我使用类似这样的东西来进行动态过程调用。
调用示例:
$mapi = new MySQLIAPI($con);
$mapi->BeginProc();
$mapi->AddParameter("user", $usern, "s");
$mapi->AddParameter("email", $email, "s");
$mapi->AddParameter("passwd", $pwd, "s");
$id = $mapi->CallProc("ij_create_user");
$id = $id[0];
if(isset($id['mysql_error']) || isset($id["error"])){
return "error";
}
return $id["id"];
示例Class:
class MySQLIAPI
{
private $con = null;
private $Variables = null;
private $values = null;
private $types = null;
private $vQu = null;
private $stmt = null;
function __construct($dbc)
{
$this->con = $dbc;
$this->Variables = [];
$this->values = [];
$this->types = [];
$this->vQu = [];
}
function BeginProc()
{
$this->stmt = $this->con->stmt_init(); // initialize statement
}
function AddParameter($key, $val, $type)
{
$this->Variables[] = "@" . $key;
$this->values[] = $val;
$this->types[] = $type;
$this->vQu[] = "?";
}
//KeyPair is v = the value, t = the type s or d
function CallProc($Proc) {
$out_var = null;
$call = "";
if(sizeof($this->values) > 0)
$call = "CALL ".$Proc."(".implode(",", (array)$this->vQu).")";
else
$call = "CALL ".$Proc."()";
if($this->stmt->prepare($call));//call stored procedure with database server session variable
{
if(sizeof($this->values) > 0) {
$params = array_merge(array(implode("", $this->types)), $this->values);
call_user_func_array(array($this->stmt, 'bind_param'), $this->refValues($params));
}
$this->stmt->execute();
$result = $this->stmt->get_result();
/* Error Checking */
$mySQLiError = mysqli_stmt_error($this->stmt);
if ($mySQLiError != "") {
$this->resetStmt();
$this->stmt->close();
$this->stmt = null;
return array('mysql_error' => $mySQLiError);
}
while ($row = $result->fetch_array(MYSQLI_ASSOC))
{
$out_var[] = $row;
}
$result->free();
while($this->stmt->more_results())
{
$this->stmt->next_result();
}
$this->resetStmt();
$this->stmt->close();
$this->stmt = null;
}
return $out_var;
}
private 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;
}
private function resetStmt()
{
//Reset Params
$this->Variables = array();
$this->values = array();
$this->types = array();
$this->vQu = array();
}
}
遗憾的是 mysqli
不支持此功能。一遍又一遍地调用该函数会覆盖这些值,因此当您显然拥有更多参数时,您只能绑定一个参数。
有几种方法可以解决这个问题
- 切换到 PDO。您可以使用 对每个函数调用进行一次绑定
- 将参数绑定为一个聚合
$sqltype = ''; $sqldata = []; foreach($bindParams as $type => $data) { $sqltype .= $type; $sqldata[] = &$data; // MUST be a reference } array_unshift($sqldata, $sqltype); // prepend the types call_user_func_array([$stmt, 'bind_param'], $sqldata);
我遇到了同样的问题,找到了一个更简单的答案:
$array_of_values = array( "Brasil", "Argentina" );
$types = "ss";
$mysqli_stmt->bind_param( $types, ...$array_of_values );
这称为 "argument unpacking",从 PHP 5.6
开始可用