问题描述
我正在执行PDO更新语句,但是它在空值上输入0。
- 我想要一个空值输入null
- 我希望零值输入零
这是我的代码:
include 'dbconfig.PHP';
$id = $_POST['id'];
$data = $_POST['data'];
try {
$options = [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,\PDO::ATTR_EMULATE_PREPARES => false,];
$pdo = new PDO("MysqL:charset=utf8mb4;host=$servername;dbname=$dbname",$username,$password);
$setStr = "";
$values = array();
foreach($data as $field => $value) {
$setStr .= "$field=:$field,";
$values[$field] = $value;
}
$setStr = rtrim($setStr,",");
$values['id'] = $id;
$stmt = $pdo->prepare("UPDATE products SET $setStr WHERE id = :id");
$stmt->execute($values);
$count = $stmt->rowCount();
if ($count > 0) {
echo json_encode(array('response'=>'success','message'=>'Product ID # '.$id." successfully updated."));
}else{
echo json_encode(array('response'=>'danger','message'=>'Product not successfully updated'));
}
}catch(PDOException $e){
echo json_encode(array('response'=>'danger','message'=>$e->getMessage()));
}
$conn = null;
做到这一点的最佳方法是什么?谢谢
解决方法
检查循环中是否有空字符串,并将其转换为null
。
foreach($data as $field => $value) {
$setStr .= "$field=:$field,";
$values[$field] = $value === "" ? null : $value;
}
,
PDOStatement :: execute认为每个参数都是一个字符串。在某些数据库中,驱动程序可以毫无问题地进行处理,但是,如果要专门键入值,则需要使用bindValue。通过这种键入,我们可以将null(或空)值键入到database-null类型(而不是列的默认值)-请参见我的bindEmptyAsNull
函数。
此外,由于我使用的是 trusted 列名称,因此可以安全地使用您的$setStr
模式来构建更新参数,但是请注意,您可能不想更新$dangerData
关联数组中未包含的列(按原样,如果未提交,则该列将被清除)。
<?php
//... your setup code,including $pdo
// List all the names of the columns in the products table here - you havent' provided enough info so I'm guessing
$keys=["name","cost","weight_grams"];
$dangerId = $_POST['id'];
$dangerData = $_POST['data'];
/**
* Convert null values into PARAM_NULL types,not
* @param $type Should be one of the [PDO::PARAM_*](https://www.php.net/manual/en/pdo.constants.php) constants
*/
function bindEmptyAsNull($stmt,$name,$value,$type=PDO::PARAM_STR) {
//If you want empty string to be considered null too:
//if ($value===null || $value==="") {
if ($value===null) {
//Note the column needs to support null types
$stmt->Value($name,null,PDO::PARAM_NULL);
} else {
$stmt->bindValue($name,$type);
}
}
//Build the set string
$setStr='';
foreach($keys as $col) {
$setStr.=$col.'=:'.$col.',';
}
$setStr=substr($set,-1);//Remove the trailing comma
//Create the statement
$stmt=$pdo->prepare("UPDATE products SET $setStr WHERE id=:id");
//Bind the danger values
// NOTE: The only way you could automate this (re-read the keys array) is to also have an
// associative array of key:type mapping too
$stmt->bindValue(":id",$dangerId,PDO::PARAM_INT);
bindEmptyAsNull($stmt,":name",$dangerData["name"]);
bindEmptyAsNull($stmt,":cost",$dangerData["cost"]);
bindEmptyAsNull($stmt,":weight_grams",$dangerData["weight_grams"],PDO::PARAM_INT);
$stmt->execute();
// .. Further processing