我通过URL将值传递到PHP页面并在MySQLi查询中使用它们。问题是,对于整数列,空字符串被转换为零,而实际上它需要为NULL。
我如何得到NULL成一个整数列与PHP/MySQLi,从在URL传递的参数?
更新:下面是如何使用传入参数和预处理语句执行插入的示例。我需要在DB上为NULL的是$specialtyType。
function InsertItem($itemID, $ownerID, $specialtyType)
{
$this->insertItemStmt->bind_param("ssi", $itemID, $ownerID, $specialtyType);
$this->insertItemStmt->execute();
如果我在bind_param之前添加Jason建议的行(设置一个中间变量并在bind_param中使用它而不是$specialty_type),那么在execute()之后它将包含0。
$int_value = empty($_GET['int_value']) ? NULL : (int)$_GET['int_value'];
使用$int_value
作为INSERT
中的列
问题不是如何通过mysqli向MySQL发送NULL,而是如何从get参数中获取NULL值。
我建议两种方法。要么使用filter_input()
,这是一个非常方便的功能或提供null作为默认值,如果没有值在URL查询中传递。
$id = filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
// or
$id = empty($_GET['id']) ? null : (int) $_GET['id'];
// If no value was presented in GET then $id will be passed as NULL
$stmt->bind_param('s', $id);
我认为filter_input()
提供了更正确的结果。请看下面的对比:
| $_GET['id'] | filter_input | Cast to int |
|---------------|--------------|-------------|
| Inexistent | false | NULL |
| | NULL | NULL |
| <white space> | NULL | 0 |
| 0 | 0 | NULL |
| 42 | 42 | 42 |
| 42.333 | NULL | 42 |
您可能需要查看数据库模式,看看所讨论的列是否允许空值。如果列不允许为空,那么当您尝试放入空值时,它将使用该字段的默认值…对于整数字段通常为零。
我遇到了这个问题,只是将相关的DB列从INT改为VARCHAR。空值现在存储为NULL, 0就是0。即使删除0在PHP MyAdmin会看到一个'0'弹回来,所以我猜INT等于空与零和VARCHAR没有。
对于MySQLi,您不能传递像NULL或0甚至"NULL"这样的常量作为bind_param()参数。
传递的所有内容都必须是引用类型。这是一个愚蠢的限制,我知道。
但是绕过它很容易。只需创建一个一次性变量。在我一直从事的一个项目中,我需要向BLOB字段插入一些数据。不幸的是,MySQLi不允许您绑定二进制数据,如果它超过一定的长度。你必须绑定 NULL,然后通过send_long_data()发送二进制信息。
但是,同样,你不能绑定像NULL这样的常量,所以在这个例子中,看看我在哪里使用了变量$Dummy。
$InfoToInsert = array
(
'a number' => 9000,
'a double' => 9000.0,
'a string' => 'Hello World',
'a blob' => gzdeflate('Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed')
);
$Stmnt =
(
'INSERT INTO _mytable '.
'(_myintcol, _mydoublecol _mystringcol, _myblobcol) '.
'VALUES '.
'(?, ?, ?, ?)'
);
if(!$PreparedStmnt = $Conn->prepare($Stmnt))
{
$OutputError = 'Failure preparing statement: '.my_SanitizeHtml($Conn->error).'<br /><br />Full query:<br />'.$Stmnt;
$Conn->rollback();
$Conn->close();
return(false);
}
$Dummy = null;
$PreparedStmnt->bind_param
(
'idsb', // Possible types:
// i for Integer
// d for Double
// s for String
// b for BLOB
$InfoToInsert['a number'], // _myintcol
$InfoToInsert['a double'], // _mydoublecol
$InfoToInsert['a string'], // _mystringcol
$Dummy // _myblobcol
);
$PreparedStmnt->send_long_data(3, $InfoToInsert['a blob']); // 3 because it's the 4th parameter (-1 for zero-based)
if(!$PreparedStmnt->execute())
{
$OutputError = 'Failure inserting report: '.my_SanitizeHtml($Conn->error);
$PreparedStmnt->close();
$Conn->rollback();
$Conn->close();
return(false);
}
$PreparedStmnt->close();