【问题标题】:using nulls in a mysqli prepared statement在 mysqli 准备好的语句中使用空值
【发布时间】:2010-09-27 03:56:32
【问题描述】:

在 mysqli 准备好的语句中,NULL 变成 ''(在字符串的情况下)或 0(在整数的情况下)。我想将其存储为真正的 NULL。有没有办法做到这一点?

【问题讨论】:

  • 我不敢相信我已经为此苦苦挣扎了多久,答案几乎是显而易见的。严格地说:你不能。结构上:bind_param。通过代码:$query_param_01 = (null===$param_01) ? "?" : "NULL"; 给所有人 +1。 (我会坚持使用{$query_param_01},因为仍然没有注入问题。请随时纠正。

标签: php mysql null mysqli prepared-statement


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    可以将真正的 NULL 值绑定到准备好的语句(阅读 this)。

    实际上,您可以使用 mysqli_bind_parameter 将 NULL 值传递给数据库。只需创建一个变量并将 NULL 值(参见手册页)存储到变量并绑定它。无论如何对我来说都很好。

    因此它必须是这样的:

    <?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 值。

    【讨论】:

    • 很好,正是我需要知道的,只是让它更通用一点:foreach($param as $k =&gt; $v) { if($v == '') $param[$k] = NULL; },所以基本上任何 null 条目都会转换为真正的 NULL,但要小心嵌套数组,只需让它递归如果你使用那些^^虽然这应该是选择的答案,thks
    【解决方案3】:

    PHP documentation on mysqli_stmt::bind_param 的 cmets 表明传入NULL 并不容易。


    请看@creatio 的回答:https://stackoverflow.com/a/6892491/18771


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

    以下函数来自user comment 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;
    } 
    

    (这不是我真正应该采用的编码风格,但如果它有效的话......)

    【讨论】:

    • FWIW,这会在“WHERE column_name != ?”上中断因为与 NULL 的比较总是 NULL。这也打破了“WHERE question = 'et tu, brute?'”
    【解决方案4】:
    <?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;
    }
    ?>
    

    【讨论】:

      【解决方案5】:

      对于任何因为在WHERE 语句中绑定 NULL 时遇到问题而前来查看此问题的人,解决方案如下:

      有一个mysqlNULL safe operator一定要用:

      &lt;=&gt;

      例子:

      <?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);
      ?>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-12-01
        • 1970-01-01
        • 2016-07-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多