簡體   English   中英

json_decode 在發布請求時返回 null 而不是 NULL,阻止我在 DB 中設置 NULL

[英]json_decode returns null instead of NULL on post request, prevents me to set NULL in the DB

我遇到的問題是我需要能夠將 NULL 值放入 mysql 數據庫中。 所以從前端我發送一個基本的 javascript object:

{
 "Info": {
  "Name": "Michelangelo",
  "Date" : null
  }
}

在我的 PHP 文件中,我確實正確獲取了請求並對其進行了解碼:

if(isset($postdata) && !empty($postdata)) {
  // Extract the data.
  $request = json_decode($postdata);
}

它適用於字符串、布爾值、整數,但不適用於null值。 在像null而不是NULL解碼后,它將在 PHP 中的 output As far as I know the only correct value in PHP is NULL: https://www.php.net/manual/en/language.types.null.php

我把這樣的值放在數據庫中。 日期列是日期類型,它接受NULL值。 但是對於null它將被轉換為 0000-00-00;

  $sql = "UPDATE `users` SET 
  `Username`='$request->Info->Name',
  `Date`='$request->Info->Date' //DB accepts NULL but not null (tested)
  WHERE `id` = '{$id}' LIMIT 1";

那么為什么它不能正確轉換呢? 我知道我可以遍歷 object 並將所有null替換為NULL值,但由於 ZA8CFDE63311149EB266ZB 嵌套將是一個主要的頭痛問題。 我該如何解決這個問題,為什么會這樣? 我更願意使用 PHP 而不是在 sql 查詢中執行此操作。

問題是因為您將“null”放在單引號之間!

`Date`='$request->Info->Date'

解決方案:在准備好的語句中使用綁定參數。 https://www.php.net/manual/en/pdo.prepare.php

$pdo = new PDO($dsn, $user, $pass, $options);
$sth = $pdo->prepare("UPDATE `users` SET
  `Username`=:username, `Date`=:date
  WHERE `id` = :id LIMIT 1");
$sth->bindParam(':username', $request->Info->Name, PDO::PARAM_STR);
$sth->bindParam(':date', $request->Info->Date);
$sth->bindParam(':id', $id);
$sth->execute();

您應該構建一些驗證 class ,它將從您將在查詢中使用的請求中返回正確的(經過清理的)值。

考慮創建一些類/邏輯,例如

final class InfoRequest
{
    /** @var array */
    private $info;

    public function __construct($request)
    {
        $this->info = $request->Info;
    }

    public function date(): ?string
    {
        $date = $this->info['Date'];
        if (!$this->isValidDate($date)) {
            throw NotValidDateException();
        }
        if (!$date) {
            return null;
        }
        $dateTime = new \DateTime($this->info['Date']);

        return $dateTime->format('Y-m-d');
    }

    private function isValidDate($date): bool
    {
        return true; // TODO: Not implemented yet
    }

    public function name(): string
    {
        $name = $this->info['Name'];
        if (!$this->isValidName($name)) {
            throw NotValidNameException();
        }

        return $name;
    }

    private function isValidName($name): bool
    {
        return true; // TODO: Not implemented yet
    }
}

用法:

$info = new InfoRequest($request);
$sth->bindParam(':username', $info->name(), PDO::PARAM_STR);

除此之外,您永遠不應該將請求中的直接輸入傳遞給數據庫的原始查詢。

通常最好不要直接從用戶輸入中獲取值(無論您認為應該多么信任來源)。 另請參閱強制性 xkcd

由於您現在在構建查詢時映射和清理數據(可能使用准備好的語句),因此對於 map 將值null到字符串"NULL" (或者只讓准備好的語句庫處理它)應該是微不足道的。

該問題與 NULL 或 null 的變體無關。 在 PHP 中,它們是相同的。

您可能在 MySQL NO_ZERO_DATE 模式下運行,該模式用零填充 null 日期。 下面的命令改變了 null 日期由 MySQL 處理的方式。

SET sql_mode = 'NO_ZERO_DATE';

更多信息在這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM