简体   繁体   English

PHP MariaDB插入NULL值不起作用

[英]PHP MariaDB Insert NULL Value Not Working

Using PHP Version 7.1.9, MariaDB 10.1.26. 使用PHP版本7.1.9,MariaDB 10.1.26。

I'm submitting form data to a MySQL database, one of my values is NULL however in the database it's empty. 我将表单数据提交到MySQL数据库,我的一个值是NULL但是在数据库中它是空的。

I have ensured that my database table is set to; 我确保我的数据库表设置为;

  • allow null = yes 允许null =是
  • default - null 默认 - null

My code is below (please ignore any security vulnerabilities this is simplified code) ; 我的代码如下(请忽略任何安全漏洞,这是简化代码) ;

$id = $_POST['id '];
$name = $_POST['name'] ? $_POST['name'] : NULL ;
$sql = "INSERT INTO staff (id, name) VALUES ('".$id."', '".$name."')
// query runs and inserts successfully

When I var_dump($name) I get NULL , although the name value in my database is empty (ie not null ) 当我var_dump($name)我得到NULL ,虽然我的数据库中的name值为空(即非null

Any ideas what i'm doing wrong? 我有什么想法吗?

Edit 编辑

The original poster said 原来的海报说

My code is below (please ignore any security vulnerabilities this is simplified code) 我的代码如下(请忽略任何安全漏洞,这是简化代码)

I interpret that as "I know about SQL injection and I am taking measures to prevent it in my code. I've simplified my post to make it easier to get an answer." 我将其解释为“我知道SQL注入,我正在采取措施在我的代码中阻止它。我已经简化了我的帖子,以便更容易得到答案。”

My response below is following their format. 我在下面的回答是遵循他们的格式。 That's why I did not use PDO, mysqli, prepared statements/escape measures in my post. 这就是为什么我没有在我的帖子中使用PDO,mysqli,预备语句/逃避措施。 If I were personally writing code to insert data into a database, I would make sure my data is sanitized and I would use an ORM like Doctrine (which is a wrapper for PDO) to interact directly with the database. 如果我亲自编写代码将数据插入数据库,我会确保我的数据被清理,并且我将使用像Doctrine(它是PDO的包装器)之类的ORM直接与数据库交互。

My Answer 我的答案

Referencing the code in the original post: 引用原始帖子中的代码:

$id = $_POST['id '];
$name = $_POST['name'] ? $_POST['name'] : NULL ;
$sql = "INSERT INTO staff (id, name) VALUES ('".$id."', '".$name."')
// query runs and inserts successfully

Your query is behaving the way you've written your code. 您的查询的行为与您编写代码的方式相同。 If you echo/print a PHP variable to standard output after it has been set to NULL you won't see a value at all. 如果在将PHP变量设置为NULL后将其回显/打印到标准输出,则根本不会看到值。 Null is the absence of value. Null是没有价值的。 Since you've wrapped the absence of value (no value, null) in single quotes, you're telling MySQL that you want to insert an empty string into the name column. 由于您在单引号中包含缺少值(无值,null),因此您告诉MySQL您要在名称列中插入空字符串。

I would rewrite the code as follows: 我会重写代码如下:

$id = $_POST['id '];
$name = $_POST['name'] ? "'$_POST[name]'" : 'NULL';
$sql = "INSERT INTO staff (id, name) VALUES ('$id', $name)";

Notice how I put NULL in a string for the name variable. 请注意我如何在名称变量的字符串中放置NULL。 When I include the name variable in the query I don't wrap it with quotes. 当我在查询中包含name变量时,我不会用引号将其包装起来。 This is the proper way to explicitly add a null value to a column in MySQL. 这是向MySQL中的列显式添加空值的正确方法。

PHP's double quotes allows variable interpolation. PHP的双引号允许变量插值。 This means you don't have to break your strings down into individual parts and concatenate string values together. 这意味着您不必将字符串分解为单个部分并将字符串值连接在一起。 This makes the code cleaner and easier to read. 这使代码更清晰,更易于阅读。

First, you're obviously not using prepared statements. 首先,您显然没有使用预准备语句。 I strongly advice you to use prepared statements in the name of security and stability. 我强烈建议您以安全性和稳定性的名义使用预准备语句。

Then, on to the issue at hand. 然后,谈到手头的问题。 The database doesn't know what a PHP null is and will only see an empty string to be inserted in your code. 数据库不知道PHP null是什么,只会在代码中看到一个空字符串。

"" . null . "" === ""

Keeping your (very dangerous and vulnerable) example code, and modifing the place where you add the "quotes" around the to be inserted string. 保留你的(非常危险和易受攻击的)示例代码,并修改在要插入的字符串周围添加“引号”的位置。 If the name is null just insert NULL without quotes around it. 如果名称为null,则只插入NULL不带引号。 the databse server will interpret that as having to inserta null value 数据库服务器将其解释为必须插入空值

$name = $_POST['name'] ? "'".$_POST['name']."'" : 'NULL';
$sql = "INSERT INTO staff (id, name) VALUES ('".$id."', ".$name.")";

Now really, investigate how to do prepared queries to prevent SQL injections or at least use mysqli_real_escape_string or something equivalent. 现在,真的,研究如何做准备查询以防止SQL注入或至少使用mysqli_real_escape_string或等效的东西。

this is the more secure version, using PDO. 这是使用PDO更安全的版本。

$sql = "INSERT INTO staff (id,name) VALUES (:id,:name)";
$stmt= $dpo->prepare($sql);
$stmnt->bindParam(':id', $id, PDO::PARAM_INT);

if(!$POST['name']) {
    $stmnt->bindParam(':name', null, PDO::PARAM_NULL);
}
else {
   $stmnt->bindParam(':name', $POST['name'], PDO::PARAM_STR);
}
$stmt->execute();

I would instead use PDO prepared statements. 我会改用PDO准备好的语句。 That should set the value to NULL instead of an empty string. 这应该将值设置为NULL而不是空字符串。 Because you are wrapping '".$name"' it is making the query '') - ie an empty string. 因为你正在包装'".$name"'它正在进行查询'') - 即一个空字符串。

I'd do like this: 我这样做:

$id = $_POST['id '];
if(isset($_POST['name'])){
    $sql = "INSERT INTO staff (id, name) VALUES ('".$id."', '".$name."')
}else{
    $sql = "INSERT INTO staff (id) VALUES ('".$id."')
}

discriminating the query if I receive the name from the form or not. 如果我从表单中收到名称,则区分查询。 You should use prepared statements to pass variables (user inputs) to a mysql query. 您应该使用预准备语句将变量(用户输入)传递给mysql查询。 Otherwise you are widely open to SQL injections. 否则,您对SQL注入持开放态度。

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

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