PHP MariaDB插入空值无效
使用PHP版本7.1.9、10.1.26 我正在向MySQL数据库提交表单数据,其中一个值是PHP MariaDB插入空值无效,php,mysql,null,Php,Mysql,Null,使用PHP版本7.1.9、10.1.26 我正在向MySQL数据库提交表单数据,其中一个值是NULL,但在数据库中它是空的 我已确保我的数据库表设置为 允许null=是 默认值-空 我的代码如下(请忽略任何安全漏洞,这是简化代码) 当我var\u dump($name)时,我得到NULL,尽管数据库中的name值为空(即非NULL) 知道我做错了什么吗?我会使用PDO准备的语句。它应该将值设置为NULL,而不是空字符串。因为您正在包装““$name”它正在进行查询”——即一个空字符串。首先,
NULL
,但在数据库中它是空的
我已确保我的数据库表设置为
- 允许null=是
- 默认值-空
var\u dump($name)
时,我得到NULL
,尽管数据库中的name
值为空(即非NULL)
知道我做错了什么吗?我会使用PDO准备的语句。它应该将值设置为NULL,而不是空字符串。因为您正在包装
““$name”
它正在进行查询”
——即一个空字符串。首先,您显然没有使用准备好的语句。我强烈建议你以安全和稳定的名义使用事先准备好的声明
然后,我们开始讨论手头的问题。数据库不知道PHP null是什么,只会在代码中插入一个空字符串
"" . null . "" === ""
保留(非常危险且易受攻击的)示例代码,并修改在要插入的字符串周围添加“引号”的位置。如果名称为空,只需插入null
,不带引号。数据库服务器将解释为必须插入空值
$name = $_POST['name'] ? "'".$_POST['name']."'" : 'NULL';
$sql = "INSERT INTO staff (id, name) VALUES ('".$id."', ".$name.")";
现在,请真正研究如何执行准备好的查询以防止SQL注入
或者至少使用mysqli\u real\u escape\u字符串或类似的东西
这是更安全的版本,使用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();
我想这样做:
$id = $_POST['id '];
if(isset($_POST['name'])){
$sql = "INSERT INTO staff (id, name) VALUES ('".$id."', '".$name."')
}else{
$sql = "INSERT INTO staff (id) VALUES ('".$id."')
}
区分是否从表单中收到名称的查询。
您应该使用准备好的语句将变量(用户输入)传递给mysql查询。否则,您将广泛接受SQL注入 编辑
原来的海报上写着
我的代码如下(请忽略任何安全漏洞,这是简化代码)
我将其解释为“我知道SQL注入,我正在采取措施在我的代码中防止它。我简化了我的帖子,以便更容易得到答案。”
我下面的回答是按照他们的格式。这就是为什么我没有在我的帖子中使用PDO、mysqli、prepared语句/转义度量。如果我个人编写代码将数据插入数据库,我会确保我的数据经过清理,并使用类似ORM的原则(PDO的包装器)直接与数据库交互
我的答案
参考原始帖子中的代码:
$id = $_POST['id '];
$name = $_POST['name'] ? $_POST['name'] : NULL ;
$sql = "INSERT INTO staff (id, name) VALUES ('".$id."', '".$name."')
// query runs and inserts successfully
您的查询的行为与您编写代码的方式相同。如果将PHP变量设置为NULL后将其回显/打印到标准输出,则根本看不到值。Null表示没有值。由于您已将缺少值(no value,null)的情况用单引号括起来,因此您告诉MySQL您想在name列中插入一个空字符串
我将重写代码如下:
$id = $_POST['id '];
$name = $_POST['name'] ? "'$_POST[name]'" : 'NULL';
$sql = "INSERT INTO staff (id, name) VALUES ('$id', $name)";
注意我是如何在name变量的字符串中输入NULL的。当我在查询中包含name变量时,我不会用引号将其括起来。这是在MySQL中显式地向列添加空值的正确方法
PHP的双引号允许变量插值。这意味着您不必将字符串分解为各个部分并将字符串值连接在一起。这使代码更清晰、更易于阅读。是否可能插入空字符串而不是空字符串?如果没有
$name
的值,则您的查询应该是$sql=“INSERT INTO staff(id)VALUES(“““$id.”)”
中的名称为空db@GeorgeHanson这就是他的查询的实际情况。所以,id
不是一个自动递增的主键吗?那么你根本不应该把它包括在查询中。我想指出原始海报上说:“请忽略任何安全漏洞,这是简化的代码。”" ... 似乎每个人在回答中都忽略了这一点。我认为这句话的意思是“我知道安全措施,我正在使用它们。”然后给出一个对slq注入不开放的答案。我目前正在回答OP发布的一个问题,该问题与他发布的代码严格相关。似乎每个人都忽略了原来的海报上写着“我的代码在下面”(请忽略任何安全漏洞(这是简化代码)”这意味着他们已经知道sql注入,并且他们正在代码中采取措施来防止它。我想这篇文章被简化了,以便得到一个快速的答案,在这种情况下,Lelio的文章是合适的。这太棒了,而且效果很好-也感谢您的解释!我理解您关于安全性的评论,并接受他们:)@我为你添加了一个粗略的PDO示例。这不考虑'0'
的名称或其他表示false的thruthy值。当然,验证需要提前进行。感谢您的精彩解释!:)
$id = $_POST['id '];
$name = $_POST['name'] ? "'$_POST[name]'" : 'NULL';
$sql = "INSERT INTO staff (id, name) VALUES ('$id', $name)";