使用PHP OOP向mysql插入数据时出现问题。
那么,这是我的代码:
public function insert($setType, $setTable, $setRow, $setValues) {
$change = function($values) {
return "?";
};
$row = join(",", $setRow);
$done = join(",", array_map($change, $setValues));
$values[] = join(",", $setValues);
function SqlArrayReferenceValues($arr){
if (strnatcmp(phpversion(),'5.3') >= 0) {
$refs = array();
foreach($arr as $key => $value)
$refs[$key] = &$arr[$key];
return $refs;
}
return $arr;
}
$insert = $this->connect->prepare("INSERT INTO $setTable ($row) VALUES ($done)");
$mergedValues = array_merge(array($setType), $values);
call_user_func_array(array($insert, "bind_param"), SqlArrayReferenceValues($mergedValues));
$insert->execute();
$insert->close();
return $insert;
}
if (empty($_SESSION['transaction'])) :
$idt = date("ymdhis");
$_SESSION['transaction'] = $idt;
endif;
$st = $_SESSION['transaction'];
if (isset($_SESSION['email'])) :
$se = $_SESSION['email'];
$user = $objMysql->query(array("*"), "user", "email = '$se'");
$dataUser = $objMysql->fetch($user);
$ide = $dataUser['id_user'];
else :
$ide = 0;
endif;
$currentLink = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$objMysql->insert("sis", "url", array("id_transaction", "id_user", "url"), array("$st", "$ide", "$currentLink"));
这是我的mysql表:Id_transaction行类型varchar。id_user行类型INTUrl行类型文本
i got 1 errors,
- mysqli_stmt::bind_param():类型定义字符串中的元素数量与
中的绑定变量数量不匹配
我的代码有什么问题?
FINAL SOLUTION BY MARTIN
public function SqlArrayReferenceValues($arr){
if (strnatcmp(phpversion(),'5.3') >= 0) {
$refs = array();
foreach($arr as $key => $value)
$refs[$key] = &$arr[$key];
return $refs;
}
return $arr;
}
public function insert($setType, $setTable, $setRow, $setValues) {
$change = function($values) {
return "?";
};
$row = join(",", $setRow);
$done = join(",", array_map($change, $setValues));
$insert = $this->connect->prepare("INSERT INTO $setTable ($row) VALUES ($done)");
$params = $setValues;
$ww = array_merge(array($setType), $params);
call_user_func_array(array($insert, "bind_param"), $this->SqlArrayReferenceValues($ww));
$insert->execute();
$insert->close();
return $insert;
}
正如Mark Baker和bub在注释中正确指出的那样,您正在传递string
值来代替array
值。
您拥有的是一个值数组,然后将其转换为字符串,然后再尝试将其用作数组。在$values
变量上不需要使用join
。
//$values = join(",", $setValues); // comment out this line,
call_user_func_array(array($insert, "bind_param"), array_unshift(array($setType), $setValues));
在这里,您使用array_unshift
将传递给函数的数组TYPES插入到数组的开头处。这将给你一个正确的数组插入到bind_param:
array("sis", $st, $side, $currentLink);
期望通过引用的问题:
上面有一个问题,MySQLi OOP代码期望对象作为引用,以及上面的-值需要通过一个单独的进程运行,以将它们的"真"值提供给call_user_func_array()
函数。
在class/script中添加:
private function SqlArrayReferenceValues($arr){
if (strnatcmp(phpversion(),'5.3') >= 0) {
$refs = array();
foreach($arr as $key => $value)
$refs[$key] = &$arr[$key];
return $refs;
}
return $arr;
}
这个函数接受这些值,并将正确的值类型返回给call_user_array_function。
:
$mergedValues = array_unshift($setValues, $setType);
call_user_func_array(array($insert, "bind_param"), $this->SqlArrayReferenceValues($mergedValues));
我从Stack Overflow的某个地方得到了这个代码,它多年来一直非常有用!这是链接:https://stackoverflow.com/a/16120923/3536236
更新3:代码应该如何:
private function SqlArrayReferenceValues($arr){
if (strnatcmp(phpversion(),'5.3') >= 0) {
$refs = array();
foreach($arr as $key => $value)
$refs[$key] = &$arr[$key];
return $refs;
}
return $arr;
}
public function insert($setType, $setTable, $setRow, $setValues) {
$change = function($values) {
return "?";
};
$row = join(",", $setRow);
$setValuesCopy = $setValues;
$done = join(",", array_map($change, $setValuesCopy));
$insert = $this->connect->prepare("INSERT INTO ".$setTable." (".$row.") VALUES (".$done.")");
$mergedValues = array_unshift($setValues, $setType);
//probably not needed but resetting array numerical indexing:
$mergedValues = array_values($mergedValues);
call_user_func_array(array($insert, "bind_param"), $this->SqlArrayReferenceValues($mergedValues));
$insert->execute();
$insert->close();
return $insert;
}
$currentLink = "http://".$_SERVER[HTTP_HOST].$_SERVER[REQUEST_URI]";
$objMysql->insert("sis", "url", array("id_transaction", "id_user", "url"), array($st, $ide, $currentLink));