【问题标题】:mysqli : Strict Standards: Only variables should be passed by referencemysqli : 严格标准:只有变量应该通过引用传递
【发布时间】:2014-07-13 15:34:21
【问题描述】:

我正在尝试创建一个小型 SQL 查询类。

这是我的课程,但我不知道为什么,我有这个错误: 严格标准:在第 52 行中只能通过引用传递变量

第 52 行是:

if (!$stmt->bind_param($param[$i][0], mysqli_real_escape_string($this->mysqli, $param[$i][1]))) {

我的代码(我开始了):

<?php
class Sql{

    private $db;
    private $user;
    private $pwd;
    private $url;

    private $param;

    private $mysqli;

    function __construct($db, $user, $pwd, $url){
        $this->db = $db;
        $this->user = $user;
        $this->pwd = $pwd;
        $this->url = $url;


    }

    /**
     * mysqli::connection()
     * 
     * @return 
     */
    public function connection()
    {
        try{
            $this->mysqli = new mysqli($this->db, $this->user, $this->pwd, $this->url);
        }catch(Exception $e){
            throw new Exception("Impossible de se connecter à la base " . $this->db);
        }
    }

    public function select($query, $param, $debug=false){

        $this->connection();

        $r = $this->InitialiseResult("select");

        if (!($stmt = $this->mysqli->prepare($query))) {
            echo "Echec de la préparation : (" . $this->mysqli->errno . ") " . $this->mysqli->error;
        }

        //Param
        for($i=0;$i<sizeof($param);$i++){
            if (!$stmt->bind_param($param[$i][0], mysqli_real_escape_string($this->mysqli, $param[$i][1]))) {
                echo "Echec lors du liage des paramètres : (" . $stmt->errno . ") " . $stmt->error;
            }
        }

        if (!$stmt->execute()) {
            echo "Echec lors de l'exécution : (" . $stmt->errno . ") " . $stmt->error;
        }

        if (!($res = $stmt->get_result())) {
            echo "Echec lors de la récupération du jeu de résultats : (" . $stmt->errno . ") " . $stmt->error;
        }else{

            $r["state"] = true;
            $r["rows"] = $res->fetch_assoc();
            $r["num_rows"] = $res->num_rows;

            if($debug)
                var_dump($r);

        }

        return $r;

    }


    /**
     * mysqli::InitialiseResult()
     *
     * @param mixed $p
     * @return
     */
    public function InitialiseResult($p)
    {
        $r = array(); //on écrase
        $r["state"] = false;

        switch($p){
            case "select":

                $r["rows"] = array();
                $r["num_rows"] = 0;
                break;

        }

        return $r;
    }
}
?>

我尝试将 $param 放在一个属性中并使用 mysqli_real_escape_string() 但错误仍然存​​在。

有什么想法吗?

【问题讨论】:

标签: php object mysqli


【解决方案1】:

$stmt-&gt;bind_param() 要求所有参数都通过引用传递,因此您不能直接传递函数的返回值(即不先将其分配给变量)。但是,正如 cmets 中已经提到的,您根本不需要转义参数,这是使用准备好的语句的优点之一。

【讨论】:

  • 好的,谢谢。这是我第一次使用准备好的陈述,但它真的很有用。再次感谢。
  • 请注意,避免 SQL 注入并不是准备好的语句的全部点!
  • @lonesomeday 是的,我意识到 whole 不是我第二次提交答案时最幸运的词,但我懒得编辑。我想我现在就这样做:-)
【解决方案2】:

mysqli_stmt::bind_param 期望第二个和任何后续参数是一个变量,因为它是 passed by reference,在参数之前由 &amp; 表示:

bool mysqli_stmt::bind_param ( string $types , mixed &$var1 [, mixed &$... ] )

在内部,PHP 不存储实际值,而只是对保存该值的变量的引用。并且仅在执行准备好的语句时才获取实际值。这就是为什么你不能绑定值而只能绑定变量的原因。

但是,因此,可以执行以下操作:

$stmt = $mysqli->prepare('INSERT INTO table (a, b) VALUES (?, ?)');
$stmt->bind_param(1, $a);
$stmt->bind_param(2, $b);

$pairs = array(
    array('a1', 'b1'),
    array('a2', 'b2'),
    array('a3', 'b3'),
);    

foreach ($pairs as $pair) {
    list($a, $b) = $pair;
    $stmt->execute();
}

INSERT 语句已准备好,其参数仅绑定一次,但多次使用不同的参数值执行。更改变量值不会破坏变量引用。


但是,对于您的实际问题,您根本不需要也不应该在准备好的语句的参数上使用mysqli_real_escape_string。只需绑定变量,其余的由 MySQLi 完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-12
    • 2014-11-01
    • 2015-05-27
    • 2016-10-05
    相关资源
    最近更新 更多