[英]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.