我遇到的情况是我想构建一个以这种格式获取$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刷新了这个错误:
警告:mysqli_stmt :: bind_param():变量数量与第23行D:\ PHP \ tr.php中预准备语句中的参数数量不匹配
我知道PDO支持如here at the end of the page.所述,但也许正如您所料,我不是PDO的粉丝所以;)
我的另一个选择是使用php中提供的eval()
变通办法,但这可能是我想到的。
还有其他办法吗?
答案 0 :(得分:9)
我遇到了同样的问题,并且找到了一个更简单的答案:
$array_of_values = array( "Brasil", "Argentina" );
$types = "ss";
$mysqli_stmt->bind_param( $types, ...$array_of_values );
这称为"参数解包",自PHP 5.6起可用
答案 1 :(得分:8)
可悲的是mysqli
不支持这一点。一遍又一遍地调用函数会覆盖这些值,所以当你有更多时,你只能绑定一个参数。
有几种方法可以解决这个问题
$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);
答案 2 :(得分:1)
我使用类似的东西来进行动态过程调用。
呼叫示例:
$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 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();
}
}