【问题标题】:mysqli_real_escape_string foreach function db_array_updatemysqli_real_escape_string foreach 函数 db_​​array_update
【发布时间】:2015-09-14 11:46:41
【问题描述】:

以前有人给我写过很多次PHP程序,现在运行代码时出现这个错误:

mysqli_real_escape_string() 期望参数 2 为字符串、数组 给...

我无法解决这个问题,这里是代码:

function db_array_update($table, $a, $where) 
{    
    $q = "update $table set ";
    $b = NULL;  

    foreach($a as $key => $value)   
    {   
        if (is_int($key))
            continue;   

        $con = mysqli_connect("localhost", MYSQLUSER , MYSQLPASS, MYSQLDB);
        $b[] = "$key='".mysqli_real_escape_string($con, $value)."'";        
    }

    $q .= implode(",", $b);
    $q .= " where ".$where;

    db_query($q);

}

我是这样使用它的:

db_array_update("all_data",array('last_fetched' =>date("Y/m/d H:i:s"),'name'=>$name, 'creation'=>$creat, 'expiration' =>$expire,"id=".$res['id']);

有人可以帮我解决这个问题吗? 尝试了很多东西但没有用...

【问题讨论】:

    标签: php arrays mysqli foreach


    【解决方案1】:

    作为$a 传递给您的函数的内容必须具有一个或多个本身就是数组的数组值。如果$value 是一个数组,你会得到这个错误,即。你有一个多维数组而不是简单的键/字符串对。

    在您的函数中执行var_dump($a) 以查看您的数组值中的哪一个是数组。此外,您传入的数据中有一些错误:

    db_array_update("all_data",array(
        'last_fetched' => date("Y/m/d H:i:s"),
        'name'=>$name,  // May be an array?
        'creation'=>$creat,  // May be an array?
        'expiration' =>$expire, // May be an array?
        ), // Need this closing ) to end the array.
        "id=".$res['id'] // This one should be outside the array!
        );
    

    您还需要在您为$where 条件传递的'id=' 位之前关闭数组,那里有未闭合的括号。

    ...实际上,您的代码在这个问题之外充满了乐趣。在这里研究答案。如果这是代码的代表性样本,那么应该有人重写您的数据库功能。

    【讨论】:

    • 谢谢... var_dump 真的很有帮助:)
    • 你能告诉我为什么代码充满了搞笑吗?为了什么?
    • 我现在注意到您传入的数组也有未闭合的括号,并且您拼写出来的 "id=".$res['id'] 包含在要更新的字段数组中。那会引起问题。如果您将它作为数组的一部分,它将导致您的最后一对更新子句变为:0 = 'id=123'(或您的$res['id'] 是什么)。您的函数也可能会给您一个错误 $where 未定义,并且您的 SQL 查询将失败,因为它以 where 结尾而没有任何后续。
    • 其中的“有趣”是这些。 1. 在每个循环中建立 MySQL 连接。您至少应该在函数的开头使用它,并且您可能只想在代码中建立一次连接,并继续重新使用该连接(例如,通过在函数参数中传递连接变量或声明一个全局,如果你不打算将它重新分解为一个适当的类,你可以将链接存储在 $this->sql 或其他东西中。)
    • 我认为问题解决了,我会更多地研究 PHP,并会根据您的建议编写新代码:)。
    【解决方案2】:

    mysqli的使用是做错了。 mysqli 的全部好处已经减少到大约为零。有关示例,请参阅http://php.net/manual/en/book.mysqli.php

    更正部分代码:

    • 连接打开了很多次:效率真的很低。
    • 以正确的方式将数据添加到数据库时不需要转义:不使用变量绑定=>对 SQL 注入的保护非常弱。

    这些可能的更正后的代码:

    function db_array_update($table, $a, $where) 
    {    
    $q = "update $table set";
    $b = NULL; 
    $c=null; 
    
    $con = mysqli_connect("localhost", MYSQLUSER , MYSQLPASS, MYSQLDB);
    foreach($a as $key => $value)   
    {   
        if (is_int($key))
            continue;   
    
        $b[]="$key=?";
    }
    
    $q .= implode(",", $b);
    $q .= " where ".$where;
    
    $stmt = $mysqli->prepare($q);
    foreach($a as $key => $value)   
    {   
        if (is_int($key))
            continue;   
        $stmt->bind_param($key, $value);
    }
    
    
    $stmt->execute();
    $stmt->close();
    
    }
    

    这仍然不合规:

    • $where为未知字符串,应与参数绑定。
    • $table 被假定为一个内部值,但应该只是一个直接的表名,以防止其中的任何滥用。

    【讨论】:

    • 良好的基本调优。如果$table 不是来自用户输入,我不明白为什么它需要在那里硬编码,如果它是在代码的其他地方内部定义的。毕竟,如果有人可以在你的服务器上执行任意代码,你就比这个函数麻烦多了。对于foreach 循环,您可能不想跳过添加和绑定整数。 :)
    • @MarkusAO 是的,可能必须删除 if 语句。在这一点上,原始代码并不是真正透明的。
    • 原始代码在不转义整数方面是“经济的”,那里有很好的优化。 :D 它仍然将它们添加到引号内。 OP 的代码有多少错误,你数不清了吗?
    • @MarkusAO 我知道这段代码肯定不会产生很多好处:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-05
    • 1970-01-01
    相关资源
    最近更新 更多