我正在尝试创建一个小型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(),但错误仍然存在。
有什么想法吗?
答案 0 :(得分:2)
$stmt->bind_param()
要求所有参数都通过引用传递,因此您无法直接传递函数的返回值(而不是首先将其赋值给变量,即)。但是,正如评论中已经提到的那样,您根本不需要逃避参数,这是使用预准备语句的优势之一。
答案 1 :(得分:2)
mysqli_stmt::bind_param
期望第二个和以下任何参数都是变量,因为它是passed by reference,在参数之前由&
表示:
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就可以完成其余的工作。