在mysqli准备语句中使用null值

29
在mysqli预处理语句中,NULL值会被转换为''(字符串)或0(整数)。我想将其作为真正的NULL值存储。有没有办法做到这一点?

1
我简直不敢相信我为此苦苦挣扎了这么久,而答案几乎是显而易见的。严格来说:你不能。结构上:bind_param。通过代码:$query_param_01 = (null===$param_01) ? "?" : "NULL"; 给大家加一分。(我会坚持使用 {$query_param_01},因为仍然没有注入问题。如有需要请指正。) - Bradmage
5个回答

46

可以通过准备语句绑定真正的NULL值(请阅读这里)。

实际上,您可以使用mysqli_bind_parameter将NULL值传递给数据库。只需创建一个变量并将NULL值(请参见其man页)存储到变量中,然后绑定即可。对我来说效果很好。

因此,它应该像这样:

<?php
    $mysqli = new mysqli('localhost', 'my_user', 'my_password', 'world');

    // person is some object you have defined earlier
    $name = $person->name();
    $age = $person->age();
    $nickname = ($person->nickname() != '') ? $person->nickname() : NULL;

    // prepare the statement
    $stmt = $mysqli->prepare("INSERT INTO Name, Age, Nickname VALUES (?, ?, ?)");

    $stmt->bind_param('sis', $name, $age, $nickname);
?>

这应该将一个 NULL 值插入数据库。


3
很好,这正是我需要知道的,只是让它更加通用:foreach($param as $k => $v) { if($v == '') $param[$k] = NULL; },所以基本上任何空条目都会被转换为真正的NULL,但要小心嵌套数组,如果你使用了嵌套数组,就要递归处理^^。虽然如此,这应该是最佳答案,谢谢。 - Fernando Silva

46

如果有人因为在他们的WHERE语句中绑定NULL而遇到问题,解决方法如下:

有一个MySQL NULL安全运算符必须使用:

<=>

示例:

<?php
$price = NULL; // NOTE: no quotes - using php NULL
$stmt = $mysqli->prepare("SELECT id FROM product WHERE price <=> ?"); // Will select products where the price is null
$stmt->bind_param($price);
?>

4
PHP文档中的mysqli_stmt :: bind_param 的评论表明,传递 NULL 并不容易。

请参见@creatio的答案:https://dev59.com/oXRC5IYBdhLWcg3wOeSB#6892491


评论中提供的解决方案对预处理语句进行一些预处理工作,将具有PHP null值的每个参数的"?"标记替换为"NULL"。然后使用修改后的查询字符串。

以下函数来自用户评论80119

function preparse_prepared($sQuery, &$saParams)
{
    $nPos = 0;

    $sRetval = $sQuery;
    foreach ($saParams as $x_Key => $Param)
    {
        //if we find no more ?'s we're done then
        if (($nPos = strpos($sQuery, '?', $nPos + 1)) === false)
        {
            break;
        }

        //this test must be done second, because we need to 
        //increment offsets of $nPos for each ?.
        //we have no need to parse anything that isn't NULL.
        if (!is_null($Param))
        {
            continue;
        }


        //null value, replace this ? with NULL.
        $sRetval = substr_replace($sRetval, 'NULL', $nPos, 1);

        //unset this element now
        unset($saParams[$x_Key]);
    }
    return $sRetval;
} 

虽然这不是我本来会选择的代码风格,但如果它能正常工作的话……


3
值得一提的是,“WHERE column_name !=?”会出现错误,因为与NULL的比较总是NULL。而“WHERE question = 'et tu, brute?'”也会出现错误。 - Bill Karwin

-2

我将所有参数存储在一个数组中,并使用array_shift($myArray)函数将它们传递给bind_param函数。NULL可以这样接受。


-3
<?php
$mysqli=new mysqli('localhost','root','','test');
$mysqli->query("CREATE TABLE test_NULL (id int(11))");
if($query=$mysqli->prepare("insert into test_NULL VALUES(?)")){
    $query->bind_param('i',$null); //note that $null is undefined
    $query->execute();
}else{
    echo __LINE__.' '.$mysqli->error;
}
?>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接