Rumah  >  Soal Jawab  >  teks badan

"Uncaught mysqli_sql_exception: Perintah tidak segerak; anda tidak boleh menjalankan arahan ini sekarang" apabila mengemas kini kepada php8.2.5 daripada versi PHP yang lebih lama

Saya mempunyai pembungkus mysqli untuk PHP 5 yang saya tulis tahun lalu, tetapi saya mendapat ralat semasa cuba menjalankannya pada PHP 8.2.5. Saya telah mencuba segala-galanya. Berikut adalah dua ciri utama:

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);
}

Untuk mendapatkan baris, ia boleh dilakukan menggunakan pertanyaan standard:

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

dalam fungsi dengan store_result() 的行(在 db_fetch) memberikan ralat ini:

Uncaught mysqli_sql_Exception: Perintah tidak segerak; anda tidak boleh menjalankan arahan ini sekarang

Saya telah mencuba hampir semua perkara, termasuk cuba menambah $stmt->free_result()$stmt->close() pada bahagian kod yang berlainan.

Persoalannya ialah saya secara khusus meminta bantuan menggunakan $stmt->free_request()$stmt->close() 重写此代码段,所以发生最少的代码更改并可以尽可能地保持原样。这些将在 db_querydb_fetch Ke mana hendak pergi dalam fungsi?

P粉883278265P粉883278265277 hari yang lalu519

membalas semua(1)saya akan balas

  • P粉718165540

    P粉7181655402024-01-17 12:42:35

    Ralat yang anda terima bermakna anda cuba melaksanakan fungsi mysqli (dan oleh itu arahan MySQL) tidak teratur. MySQL membalas dengan ralat ini apabila ia menerima arahan yang tidak dijangka pada masa ini.

    Anda tidak menambah free_result()close() di mana-mana dalam kod anda. Kod yang berstruktur dengan betul tidak sepatutnya mempunyai sebarang ciri ini. Ia hanya untuk mengelakkan kebocoran memori dalam kod spageti.

    Untuk membetulkan ralat ini, anda mesti memastikan bahawa operasi dilakukan dalam susunan yang betul. Tetapi kod ini terlalu mengelirukan untuk mengetahui apa yang berlaku. Anda perlu menulis semula!

    Cuba sesuatu yang mudah seperti ini:

    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);
    }

    Fungsi lain perlu dicantas dengan cara yang sama.

    Masalah sebenar ialah jika anda menghubungi store_result() 两次。最简单的解决方法是删除其中之一。但是删除哪一个是一个谜,因为这段代码并没有明确说明哪一个(如果有的话)实际上是必要的。您可能可以删除两者,但是 db_num_rows ia tidak akan berfungsi.

    balas
    0
  • Batalbalas