„Nicht abgefangene mysqli_sql_Exception: Der Befehl ist nicht synchron; Sie können diesen Befehl jetzt nicht ausführen' beim Update auf php8.2.5 von einer älteren PHP-Version
P粉883278265
P粉883278265 2024-01-16 14:25:42
0
1
574

Ich habe einen MySQL-Wrapper für PHP 5, den ich vor Jahren geschrieben habe, aber ich erhalte eine Fehlermeldung, wenn ich versuche, ihn unter PHP 8.2.5 auszuführen. Ich habe alles versucht. Hier sind die beiden Hauptmerkmale:

global $db_obj, $db_driver;

function db_login() {
    global $db_obj;
    $res = @$db_obj->connect(DB_HOST, DB_USER, DB_PASS);
    if($res == false) {
        display_error("Could not connect to database.");
    }
    db_maybe_handle_error();
    db_select_db();
    db_set_charset();
}

function db_select_db($db = DB_NAME) {
    global $db_obj;
    @$db_obj->select_db($db);
    db_maybe_handle_error();
}

function db_set_charset($charset = 'utf8') {
    global $db_obj;
    @$db_obj->set_charset($charset);
    db_maybe_handle_error();
}

function db_error() {
    global $db_obj;
    return $db_obj->error();
}

function db_maybe_handle_error($r = null, $extra_info = "") {
    $e = db_error();
    if($e != '') {
       echo "mysql error: " . $e . " " . hsc($extra_info);
    }
    return $r;
}

function db_query($q) {

    $num_args = func_num_args();
    $arg_list = func_get_args();
    $r = null;

    global $db_obj;

    if($num_args > 1) {
        $stmt = $db_obj->stmt_init();
        if($stmt->prepare($q)) {
            $types = "";
            $refArr = array("");
            for($i = 1; $i < $num_args; $i++) {
                $type = gettype($arg_list[$i]) === "integer" ? "i" : "s";
                //$stmt->bind_param($type, $arg_list[$i]);
                // PHP <=5.2: Remove the ampersand
                // See http://php.net/manual/de/mysqli-stmt.bind-param.php
                $refArr[] = &$arg_list[$i];
                $types .= $type;
            }
            $refArr[0] = $types;
            $ref = new ReflectionClass('mysqli_stmt');
            $method = $ref->getMethod("bind_param");
            $method->invokeArgs($stmt, $refArr);
            $stmt->execute();
            $stmt->store_result();
            $r = $stmt;
        } else {
            db_maybe_handle_error(null, $q);
        }
    } else {
        $r = @$db_obj->query($q);
    }

    db_maybe_handle_error(null, $q);

    return $r;
}

function db_fetch($res, $use_numerical_indices = null) {
    global $db_obj;

    $use_numerical_indices = $use_numerical_indices === true ||
        ($use_numerical_indices === null && DB_DEFAULT_USE_NUMERICAL_INDEXES);

    if(is_array($res)) {
        return array_shift($res);
    }

    if($res instanceof mysqli_stmt) {
        $res->store_result();
        //$res->get_result();
        $variables = array();
        $data = array();
        $meta = $res->result_metadata();

        while($field = $meta->fetch_field()) {
            $variables[] = &$data[$field->name];
        }

        call_user_func_array(array($res, 'bind_result'), $variables);

        if(!$res->fetch()) {
            $res->close();
            return null;
        }
        $array = array();
        $i = 0;
        foreach($data as $k => $v) {
            $array[$k] = $v;
            if($use_numerical_indices) {
                $array[$i] = $v;
            }
            $i++;
        }
        db_maybe_handle_error($array);
    }
    $result_type = $use_numerical_indices ? $db_obj->BOTH : $db_obj->ASSOC;
    $r = @$db_obj->fetch_array($res, $result_type);
    return db_maybe_handle_error($r);
}

function db_num_rows($res) {
    global $db_obj;
    if(is_array($res)) {
        return count($res);
    }
    if($res instanceof mysqli_stmt) {
        return mysqli_stmt_num_rows($res);
    }
    $r = @$db_obj->num_rows($res);
    return db_maybe_handle_error($r);
}

function db_insert_id() {
    global $db_obj;
    $r = @$db_obj->insert_id();
    return db_maybe_handle_error($r);
}

Um eine Zeile zu erhalten, kann dies mit einer Standardabfrage erfolgen:

$row = db_fetch(db_query("SELECT * FROM $table WHERE id=? LIMIT 1", $id));

in einer Funktion mit store_result() 的行(在 db_fetch) gibt diesen Fehler aus:

Ungefangene mysqli_sql_Exception: Befehl nicht synchron; Sie können diesen Befehl jetzt nicht ausführen

Ich habe fast alles versucht, einschließlich des Versuchs, $stmt->free_result()$stmt->close() zu verschiedenen Teilen des Codes hinzuzufügen.

Die Frage ist, dass ich speziell um Hilfe bei der Verwendung von $stmt->free_request()$stmt->close() 重写此代码段,所以发生最少的代码更改并可以尽可能地保持原样。这些将在 db_querydb_fetch Wohin in der Funktion bitten möchte?

P粉883278265
P粉883278265

Antworte allen(1)
P粉718165540

您收到的错误意味着您正在尝试无序执行 mysqli 函数(以及 MySQL 命令)。当 MySQL 收到此时不期望的命令时,它会回复此错误。

您不要在代码中的任何位置添加 free_result()close()。正确结构的代码不应具有任何这些功能。它们只是为了防止意大利面条代码中的内存泄漏。

要修复该错误,您必须确保操作以正确的顺序执行。但这段代码太混乱了,无法搞清它的情况。你必须重写它!

尝试像这样简单的事情:

function db_query($q, $params = []): mysqli_result
{
    global $db_obj; // DO NOT USE GLOBALS!!!

    return $db_obj->execute_query($q, $params);
}

function db_fetch(mysqli_result $res, $use_numerical_indices = null)
{
    $use_numerical_indices = $use_numerical_indices === true ||
        ($use_numerical_indices === null && DB_DEFAULT_USE_NUMERICAL_INDEXES);

    $result_type = $use_numerical_indices ? MYSQLI_NUM : MYSQLI_ASSOC;
    return $res->fetch_array($result_type);
}

其他函数需要以类似的方式进行修剪。

实际问题是您调用了 store_result() 两次。最简单的解决方法是删除其中之一。但是删除哪一个是一个谜,因为这段代码并没有明确说明哪一个(如果有的话)实际上是必要的。您可能可以删除两者,但是 db_num_rows 将不起作用。

Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage