mysql动态创建预处理语句失败:"未为预处理语句中的参数提供数据"


MySQLi dynamically created prepared statement fails: "No data supplied for parameters in prepared statement"

我有一段代码,它从MySQL数据库读取崩溃日志和其他元数据,然后将其作为JSON发送回请求者(该代码由另一个页面上的AJAX函数调用)。可选地,过滤器可以用GET指定,它改变准备好的语句,只过滤指定的结果——例如,只显示一个应用程序版本的结果。下面是有问题的代码:

$conn = new mysqli($sql_servername, $sql_username, $sql_password, "Crashes");
if ($conn->connect_error) {
    //failed
    die();
}
$sql="
SELECT ID,phone,appver,osver,user_agent,username,message,app_name,date_received FROM Crashes WHERE ";
$params="";
$params2="";
if (isset($_GET["filter_phone"])) {
    $sql .= "phone = ? AND "; //i.e "WHERE phone = ? AND (...osver = ? AND appver = ? etc)"
    $params.="s";
    $params2.=', $_GET["filter_phone"]';
}
if (isset($_GET["filter_appver"])) {
    $sql .= "appver = ? AND ";
    $params.="s";
    $params2.=', $_GET["filter_appver"]';
}
if (isset($_GET["filter_osver"])) {
    $sql .= "osver = ? AND ";
    $params.="s";
    $params2.=', $_GET["filter_osver"]';
}
if (isset($_GET["filter_user_agent"])) {
    $sql .= "user_agent = ? AND ";
    $params.="s";
    $params2.=', $_GET["filter_user_agent"]';
}
if (isset($_GET["filter_username"])) {
    $sql .= "username = ? AND ";
    $params.="s";
    $params2.=', $_GET["filter_username"]';
}
if (isset($_GET["filter_message"])) {
    $sql .= "message = ? AND ";
    $params.="s";
    $params2.=', $_GET["filter_message"]';
}
if (isset($_GET["filter_app_name"])) {
    $sql .= "app_name = ? AND ";
    $params.="s";
    $params2.=', $_GET["filter_app_name"]';
}
$sql.="1";
//echo "'$params: ".$params."<br>";
//echo "'$params2: ".$params2."<br>";
//echo "<br>'$stmt->bind_param('$params$params2);<br>";
//echo var_dump($_GET);
$stmt = $conn->prepare($sql);
exec("'$stmt->bind_param('$params$params2);");
if ($stmt->execute()) {
    //echo "<br>Success!";
} else {
    //echo "<br>Failure: ".$stmt->error;
}
$result = $stmt->get_result();
$out = array();
while ($row = $result->fetch_assoc()) {
    array_push($out, $row);
}
echo json_encode($out);

当没有指定过滤器时,这段代码可以完美地工作—但是,当指定任何过滤器时,语句失败,错误为No data supplied for parameters in prepared statement。我已经验证了exec() 中的代码应该是(例如,如果设置了user_agent过滤器)$stmt->bind_param($params, $_GET["filter_user_agent"]);

此外,当我使用查询时,SQL查询可以完美地工作,但只是用过滤器手动替换? s,因此它似乎不是初始查询的问题,而是准备好的语句的问题。非常感谢你的帮助。

注:注释掉的echo s是为了调试目的,通常是禁用的,但我留下它们是为了显示我是如何获得我目前拥有的信息的。

编辑:下面回答了我自己的问题-错误是我使用exec() -一个函数executes外部shell命令,而我想要的是eval(),其中eval评估字符串输入并将其执行为PHP脚本。

原来我只是错了exec()的功能。(太多Python了?)exec()运行外部shell命令,而我正在寻找的是eval(),它评估并运行作为PHP代码输入的任何字符串

看起来您从未实际使用$params$params2的值。您将它们连接起来,但是您的$stmt->bind_param()在哪里?它被注释掉了?

我也没有看到$conn->prepare("")。您是否遗漏了一些代码?

$conn被定义为mysqli对象,然后再一次从未使用过。这里有点不对劲。

编辑:

尝试exec("'支撑美元-> bind_param (' params ' params2美元);");我假设您以某种方式执行代码并转义变量—按照该逻辑,您可能应该转义params和params2 ?