mysqli num rows выдает ошибку на сервере, не являющемся локальным хостом

#php #mysql

#php #mysqli

Вопрос:

Я создал вспомогательную функцию и часто использую ее в своем коде, получая следующую ошибку.

но чего я не понимаю, так это того, что у меня есть сервер zend, и мой код отлично работает на локальном хосте. чего горевать на живом сервере.

Предупреждение: mysqli_ num_rows() ожидает, что параметр 1 будет mysqli_result, логическое значение в строке 26

это строка 26

 function row_count($result){   
    global $connection;
    return mysqli_num_rows($result);
}
  

код входа

 function login_user($email, $password){
    
    $active = 1;
    
    $connection = dbconnect();
    $stmt = $connection->prepare('SELECT user_pwd, user_id, username FROM users WHERE user_email = ? AND active= ?');
    $stmt->bind_param('ss', $email, $active);
    $stmt->execute();
    $result = $stmt->fetch();      
    
    if (row_count($result) == 1) {
        
        $row = fetch_array($result);
        
        $db_password = $row['user_pwd'];
        
        if (password_verify($password, $db_password)) {
            
            $_SESSION['email'] = $email;
            $_SESSION['user_id'] = $row['user_id'];
            $_SESSION['username'] = $row['username'];
            
            return true;
        
        } else {
            
            return false;
        }
        
        return true;
    
    } else {
        
        return false;
    }
}
  

Ответ №1:

Посмотрите на это утверждение здесь,

 $result = $stmt->fetch();
  

Из документации mysqli_stmt::fetch,

                                     Return Values 
    Value    Description
    TRUE     Success. Data has been fetched
    FALSE    Error occurred
    NULL     No more rows/data exists or data truncation occurred
  

Во-первых, ->fetch() не возвращает никакого набора результатов при успешном выполнении. И, во-вторых, этот метод используется для извлечения результатов из подготовленного оператора в связанные переменные, чего вы не делаете.

Решение заключается в том, чтобы сначала использовать, ->store_result() за ->num_rows которым следует, чтобы получить общее количество строк, возвращаемых SELECT запросом. А затем извлеките результаты из подготовленного оператора в связанные переменные, чтобы вы могли использовать эти связанные переменные позже в коде. Итак, ваш код должен быть таким:

 function login_user($email, $password){
    $active = 1;

    $connection = dbconnect();
    $stmt = $connection->prepare('SELECT user_pwd, user_id, username FROM users WHERE user_email = ? AND active= ?');
    $stmt->bind_param('ss', $email, $active);
    $stmt->execute();
    $stmt->store_result();     

    if ($stmt->num_rows == 1) {
        $stmt->bind_result($db_password, $user_id, $username);
        $stmt->fetch();

        if (password_verify($password, $db_password)) {
            $_SESSION['email'] = $email;
            $_SESSION['user_id'] = $user_id;
            $_SESSION['username'] = $username;
            return true;
        } else {
            return false;
        }
        return true;
    } else {
        return false;
    }
}
  

В качестве альтернативы, вы также можете использовать ->get_result() метод для достижения желаемого результата. Ваш код должен быть таким:

 function login_user($email, $password){
    $active = 1;

    $connection = dbconnect();
    $stmt = $connection->prepare('SELECT user_pwd, user_id, username FROM users WHERE user_email = ? AND active= ?');
    $stmt->bind_param('ss', $email, $active);
    $stmt->execute();
    $result = $stmt->get_result();     

    if ($result->num_rows == 1) {
        $row = $result->fetch_array();
        $db_password = $row['user_pwd'];

        if (password_verify($password, $db_password)) {
            $_SESSION['email'] = $email;
            $_SESSION['user_id'] = $row['user_id'];
            $_SESSION['username'] = $row['username'];
            return true;
        } else {
            return false;
        }
        return true;
    } else {
        return false;
    }
}
  

Примечание: ->get_result() метод доступен только с собственным драйвером MySQL (mysqlnd), поэтому он не будет работать, если у вас не установлен этот конкретный драйвер.


Кроме того, из вашего вопроса:

но чего я не понимаю, так это того, что у меня есть сервер zend, и мой код отлично работает на локальном хосте. чего горевать на живом сервере.

Это потому, что отчеты об ошибках, вероятно, отключены на вашем локальном сервере. Добавьте эти строки в самый верх вашего PHP-скрипта, чтобы включить сообщение об ошибках, ini_set('display_errors', 1); error_reporting(E_ALL); . Также используйте mysqli::$error.