Error with the function "function bind_param () on boolean"

0

I have an error with a php line, and I can not find the error.

function existingEmail($Email){
    global $mysqli;
    $stmt = $mysqli->prepare("SELECT id FROM users WHERE Email = ? LIMIT 1");
    $stmt->bind_param("s", $Email);
    $stmt->execute();
    $stmt->store_result();
    $num = $stmt->num_rows;
    $stmt->close();
    if ($num > 0){
        return true;
    } else {
        return false;
    }
}
  

#1 {main} thrown in functions.php on line 116

$stmt->bind_param('ssssisi', $Email, $User, $Password_hash, $active, $token, $user_type);

if ($stmt->execute()){
    return $mysqli->insert_id;
} else {
    return 0;
}

Hi critical, line 116 is this: it would be in functions.php

(Linea 115-) $stmt = $mysqli->prepare("INSERT INTO users (Email, User, Password, active, token, id_type) VALUES(?,?,?,?,?,?,?)"); 
(Linea 116 -) $stmt->bind_param('ssssisi', $Email, $User, $Password_hash, $active, $token, $user_type);

But I also have an error on line 62 that is in the register.php next to the html code:

$register = registerUser($Email, $User, $Password_hash, $active, $token, $user_type);

And the total error is:

Fatal error: Uncaught Error: Call to a member function bind_param() on boolean 
in C:\xampp\htdocs\dev\login\php\functions.php:116 
Stack trace: 
#0 C:\xampp\htdocs\dev\login\register.php(62): registerUser('[email protected]', 'admin1', '$2y$10$fOUDVQnB...', 0, 'afff25d132889d5...', 2) 
#1 {main} thrown in C:\xampp\htdocs\dev\login\php\functions.php on line 116

If it is a register and login form

To run this php, you need the connection.php file with connection to the database, which is included as soon as the code starts

    
asked by sqk 25.07.2018 в 22:39
source

1 answer

2

I would say there is no error in registerUser or in the file register.php per se.

The error is that when doing:

$register = registerUser($Email, $User, $Password_hash, $active, $token, $user_type);

you pass 6 parameters:

  • Email
  • User
  • Password_hash
  • active
  • token
  • user_type
  • But then you try to prepare the sentence with seven placeholders:

    $stmt = $mysqli->prepare("INSERT INTO users (Email, User, Password, active, token, id_type) VALUES(?,?,?,?,?,?,?)"); 
    

    When it should be:

    $stmt = $mysqli->prepare("INSERT INTO users (Email, User, Password, active, token, id_type) VALUES(?, ?, ?, ?, ?, ?)"); 
    

    As you passed seven, the output of $mysqli->prepare returns false instead of an object mysqli_statement . Then when you try to invoke a method about false you clearly can not.

    However, even if you correct the error on line 115, again try to match more parameters than you have:

    $stmt->bind_param('ssssisi', $Email, $User, $Password_hash, $active, $token, $user_type);
    

    When it should be:

    $stmt->bind_param('sssisi', $Email, $User, $Password_hash, $active, $token, $user_type);
    

    Finally, what A.Cedano tells you is very true, avoid global variables. That code is prone to failures and is impossible to test. It would be better if you pass the connection object as a parameter:

    function existingEmail($Email, $mysqli){
        $stmt = $mysqli->....
    }
    

    Bonus Track:

    In this question, and in many others that are seen in Stack Overflow Español , it is striking that an error in the driver mysql (obsolete) or mysqli return FALSE instead of triggering an error or exception.

    This forces the error handling to be of the type

    $salida = $conexión->método( $parámetros);
    
    if($salida === false) {
      ... manejo del error...
      return $conexión->error;
    } 
    ...manejo del resultado...
    return $resultado;
    

    As you will see, to know what went wrong, you have to consult additionally the content of connection-> error .

    Using the PDO driver, whose syntax is very, very similar to mysqli you can tell it to transform those internal errors into exceptions:

    For example when instantiating the connection:

    $conexión = new PDO($dsn, $usuario, $contraseña);
    $conexión->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    

    From then on, you can operate the style:

    try {
    
      $salida = $conexión->método( $parámetros );
      ... procesamiento con el resultado...
      return $resultado;
    
    } catch (\PDOException $e) {
    
      ... manejo del error ...
      return $e->getMessage(); (o bien la traza de la excepcion como string)
    
    }
    

    The exception already has a message of its own, and one saves one step.

    This advantage is more noticeable when you want to prepare a query and then execute it. In mysqli you should do:

    $statement = $conexión->prepare( $parámetros);
    
    if($statement === false) { // comprobación 1
      ... manejo del error...
      return $conexión->error; // además preguntar cuál fue el error
    } 
    
    $salida = $statement->método( $otros_parámetros ) // bind, execute, etc
    
    if($salida === false) {
      ... manejo del error...
      return $conexión->error;  // comprobación 2
    }
    ...manejo del resultado...  // ...y preguntar por el error
    return $resultado;
    

    While in PDO the same try / catch block can wrap everything:

    try {
    
      $statement = $conexión->prepare( $parámetros );
    
      $salida = $conexión->método($otros_parámetros);
    
      ... procesamiento con el resultado...
      return $resultado;
    
    } catch (\PDOException $e) {  // entras sin tener que comprobar la salida o el statement
    
      ... manejo del error ...
      return $e->getMessage(); // ya contiene todo lo que necesitas saber
    
    }
    

    I thought the comment was appropriate to show that, in my opinion, the flow of a program is much more understandable (and has less Ciclomatic Complexity ) when one gets used to handling exceptions instead of checking things as inconsistent as an error in the DDBB returns FALSE . And with all that I like and I defend PHP, one of the most exasperating things that it has are the inconsistencies.

        
    answered by 26.07.2018 / 01:17
    source