简体   繁体   English

PDO 语句更新 0 值而不是 null 或空

[英]PDO statement updates 0 values instead of null or empty

I am making a PDO update statement but it is entering 0's on empty values.我正在制作 PDO 更新语句,但它在空值上输入 0。

  • I want a empty value to enter null我想要一个空值输入 null
  • I want a zero value to enter zero我想要一个零值输入零

Here is my code:这是我的代码:

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;

What is the best way to do this?做这个的最好方式是什么? Thank you谢谢

Check for an empty string in your loop, and convert it to null .检查循环中的空字符串,并将其转换为null

    foreach($data as $field => $value) {
        $setStr .= "$field=:$field,";
        $values[$field] = $value === "" ? null : $value;
    }

PDOStatement:: execute considers every parameter to be a string. PDOStatement:: execute认为每个参数都是一个字符串。 In some databases the driver deals with this without issue, but if you want to specifically type values you need instead to use bindValue .在某些数据库中,驱动程序可以毫无问题地处理此问题,但如果您想专门键入值,则需要使用bindValue With this typing, we can type null (or empty) values to the database-null type (instead of whatever the column default is) - see my bindEmptyAsNull function.通过这种输入,我们可以将 null(或空)值输入到数据库空类型(而不是列默认值) - 请参阅我的bindEmptyAsNull function。

Also, since I'm using a trusted source for the column names, I can safely use your $setStr pattern for building the update params, but note you might not want to update a column that isn't included in the $dangerData associative array (as it is, if it isn't submitted, the column will be cleared).此外,由于我对列名使用了受信任的来源,因此我可以安全地使用您的$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,$value,$type);
    }
}

//Build the set string
$setStr='';
foreach($keys as $col) {
    $setStr.=$col.'=:'.$col.',';
}
$setStr=substr($set,0,-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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM