我是一个PHP新手,所以请对我宽容一点。
我收到此错误“SQLSTATE[HY 093]:无效参数...”。
我有一个函数,它有三个参数:$表格,$数据,$标识
其中$table只是数据库中要更新的表。
$id是我试图更新的表中的项的ID。
$data是一个关联数组,其中$data[$key]与数据库中的列名相匹配。
public function update_database($table, $data, $id)
{
$sql_statement = "'UPDATE `" . $table . "` SET ";
foreach ($data as $key => $value) {
if ($key === array_key_last($data)) {
$sql_statement .= $key . " = :" . $key . " WHERE id = :id '";
} else {
$sql_statement .= $key . " = :" . $key . ", ";
}
}
$this->db->query($sql_statement);
foreach ($data as $key => $value) {
$this->db->bind(':' . $key, $data[$key]);
}
$this->db->bind(':id', $id);
if($this->db->execute()){
//it worked!
return true;
}else{
//something did not work
return false;
}
我知道这个错误只是告诉我没有绑定正确数量的值。
在我的SQL语句中,我绑定了17个值。关联数组中的每一项都有16个值。我在语句末尾的第17个值上进行了标记。下面是使用第一个foreach循环生成的SQL语句:
string(594) "'UPDATE `clan-info-static` SET tag = :tag, name = :name, location_id = :location_id, location_name = :location_name, location_iscountry = :location_iscountry, location_countrycode = :location_countrycode, badgeUrls_small = :badgeUrls_small, badgeUrls_medium = :badgeUrls_medium, badgeUrls_large = :badgeUrls_large, requiredTrophies = :requiredTrophies, warFrequency = :warFrequency, isWarLogPublic = :isWarLogPublic, warLeague_id = :warLeague_id, warLeague_name = :warLeague_name, requiredVersusTrophies = :requiredVersusTrophies, requiredTownhallLevel = :requiredTownhallLevel WHERE id = :id '"
第二个foreach循环绑定SQL语句中所需的值。它使用的数据集与第一个foreach循环相同。
我修改了代码,在每次绑定值时添加了一个计数器。计数器计数到16,这是预期的。这使得我用foreach循环绑定了16次值,第17次是手动完成的。
由于两个foreach循环都使用相同的数据集,我不知道为什么会出现这个错误。
EDIT:包含我的数据库类。
class Database{
private $host = DB_HOST;
private $user = DB_USER;
private $pass = DB_PASS;
private $dbname = DB_NAME;
private $dbh;
private $stmt;
private $error;
public function __construct(){
$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
);
try{
$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
}catch(PDOException $e){
$this->error = $e->getMessage();
echo $this->error;
}
}
public function query($sql){
$this->stmt = $this->dbh->prepare($sql);
}
public function bind($param, $value, $type = null){
if(is_null($type)){
switch(true){
case is_int($value):
$type = PDO::PARAM_INT;
break;
case is_bool($value):
$type = PDO::PARAM_BOOL;
break;
case is_null($value):
$type = PDO::PARAM_NULL;
break;
default:
$type = PDO::PARAM_STR;
}
}
$this->stmt->bindValue($param, $value, $type);
}
public function execute(){
return $this->stmt->execute();
}
}
2条答案
按热度按时间6yjfywim1#
把这个包含到函数中,这是我在我的项目中经常做的。请清理输入的值以防止不愉快的事件。如果发生错误,你可以使用
beginTransaction
方法来处理rollBack
。wz3gfoph2#
好了,我修好了。
问题出在
$this->db->query($sql_statement);
上,由于某种原因,它不喜欢我简单地传递一个预制语句。当我这样构建语句时:$this->db->query('UPDATE ' . $table . ' SET ' . $items . ' WHERE id = :id');
.它按预期工作。我编辑了我的第一个foreach循环以获取项目,而不是构建整个语句:
旧版:
新功能:
我确实让它工作了,但我不知道为什么第一种方法不起作用。我会深入研究文档,试图找到答案。当我找到答案时,我会向你报告。