为了账号安全,请及时绑定邮箱和手机立即绑定

无法对 mysqli 使用多个 STMT 查询

无法对 mysqli 使用多个 STMT 查询

PHP
有只小跳蛙 2023-07-07 10:32:34
我正在尝试生成一个用户创建页面,并进行验证以确定用户是否已存在,为此我使用以下代码:在这里,我将用户及其密码插入到表 USERS 中mysqli_stmt_bind_param($guardar_usuario, 'ss', $usuario,$encriptar);mysqli_stmt_execute($guardar_usuario);这里我重用变量 $user 来恢复创建的新 id 用户$consulta = "SELECT id_usuario FROM usuario WHERE usuario = '$usuario' ORDER BY fecha_registro DESC LIMIT 1";$ultimo_registro = mysqli_prepare($connect,$consulta);mysqli_stmt_execute($ultimo_registro);mysqli_stmt_bind_result($ultimo_registro, $id_usuario_creado);mysqli_stmt_fetch($ultimo_registro);我将额外的数据插入到名为 PERSONAS 的表中$guardar_persona = mysqli_prepare($connect, "INSERT INTO persona (id_usuario, nombre, email) VALUES (?, ?, ?)");        mysqli_stmt_bind_param($guardar_persona, 'iss',  $ultimo_registro, $nombre_usuario, $email_usuario);            mysqli_stmt_execute($guardar_persona);我的问题是第二个查询,将数据插入到表 PERSONAS 中不起作用,但是如果我删除第一个查询,使插入到表 USERS 中,则该查询可以正常工作,所以我不知道是否有规则使这项工作有效?抱歉,如果这是一个相当新手的问题,刚刚开始以这种方式工作以尝试尽可能防止数据注入。
查看完整描述

1 回答

?
千万里不及你

TA贡献1784条经验 获得超9个赞

当执行预备语句时,mysqli 默认使用无缓冲查询。这是一个非常令人困惑的行为,但这意味着结果不会自动发送到 PHP。MySQL 服务器将结果存储在服务器上并等待 PHP 检索它们。只要还有更多结果需要获取,您就无法执行另一个查询。


要解决此问题,您需要致电mysqli_stmt_store_result()或者需要获取所有结果。


在您的情况下,简单的选择是添加store_result并完成它。


$consulta = "SELECT id_usuario FROM usuario WHERE usuario = ? ORDER BY fecha_registro DESC LIMIT 1";

$ultimo_registro = mysqli_prepare($connect,$consulta);

mysqli_stmt_bind_param($ultimo_registro, 's', $usuario);

mysqli_stmt_execute($ultimo_registro);

mysqli_stmt_store_result($ultimo_registro);

mysqli_stmt_bind_result($ultimo_registro, $id_usuario_creado);

mysqli_stmt_fetch($ultimo_registro);

但是,如果您直接停止使用 mysqli 函数,这对您来说会容易得多。即使是一个简单的包装函数也可以帮助您避免所有这些 mysqli 混乱。


function safeQuery(mysqli $db, string $sql, array $params = []): ?array {

    $stmt = $db->prepare($sql);

    if ($params) {

        $stmt->bind_param(str_repeat("s", count($params)), ...$params);

    }

    $stmt->execute();

    if ($result = $stmt->get_result()) {

        return $result->fetch_all(MYSQLI_BOTH);

    }

    return null;

}

然后您可以将整个准备好的语句抽象为一行代码:


$consulta = "SELECT id_usuario FROM usuario WHERE usuario = ? ORDER BY fecha_registro DESC LIMIT 1";

$result = safeQuery($connect, $consulta, [$usuario]);

if ($result) {

    $id_usuario_creado = $result[0]['id_usuario'];

}

您甚至可以编写第二个函数,它仅从准备好的语句中获取单个值。


function fetchSingle(mysqli $db, string $sql, array $params = []) {

    $stmt = $db->prepare($sql);

    if ($params) {

        $stmt->bind_param(str_repeat("s", count($params)), ...$params);

    }

    $stmt->execute();

    if ($result = $stmt->get_result()) {

        return $result->fetch_row()[0];

    }

    return null;

}

LIMIT 1当您只想获取单个值时可以使用此方法。


$consulta = "SELECT id_usuario FROM usuario WHERE usuario = ? ORDER BY fecha_registro DESC LIMIT 1";

$id_usuario_creado = fetchSingle($connect, $consulta, [$usuario]);


查看完整回答
反对 回复 2023-07-07
  • 1 回答
  • 0 关注
  • 76 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信