Fatal error: Call to a member function fetch_assoc () on boolean

1

I'm trying to make a php page with a login by copying a fragment that a partner passed me but at the time of executing it I skip that error:

  

Fatal error: Call to a member function fetch_assoc () on boolean.

I do not know how to solve it; this is the code:

<?php
if(isset($_POST["login"])){
  $mysqli = new mysqli('localhost','toni','','ssf');

  if(!$mysqli->connect_errno){
    $mysqli->set_charset("utf8");
    $Usuario = $_POST['Usuario'];
    $Contrasena = $_POST['pw'];
    $Admin = $_POST['Usuario'];
    $Contra = $_POST['pw'];

    if($_POST['Tipo'] == "cliente"){
      $result = $mysqli->query("SELECT * FROM usuario WHERE Usuario='$Usuario' AND Contrasena='$Contrasena'");

      if(mysqli_num_rows($result)>0){
        setcookie("login",$_POST['usuario'],time() + (86400 * 30),"/");
        $_COOKIE["login"] = $_POST["usuario"];
        $Admin=false;
      }
      else{
        echo "Login Incorrecto";
      }
    }
    else{
      $results = $mysqli->query("SELECT * FROM usuario WHERE Usuario='$Usuario' AND Contrasena='$Contrasena'");

      if(!$results || mysqli_num_rows($results)>0){
        setcookie("login",$_POST['Usuario'],time() + (86400 * 30),"/");
        $_COOKIE["login"] = $_POST["Usuario"];
        $row = $results->fetch_assoc();
        $Admin= $row["Tipo"] == "Admin" ? true : false;
      }
      else{
        echo "Ni lo intentes";
      }
    }  
  }
}
?>
    
asked by Toni serrano 10.06.2017 в 19:35
source

2 answers

1

Here you are telling your code to run when your query fails

if(!$results || mysqli_num_rows($results)>0){
                    setcookie("login",$_POST['Usuario'],time() + (86400 * 30),"/");
                    $_COOKIE["login"] = $_POST["Usuario"];
                    $row = $results->fetch_assoc();
                    $Admin= $row["Tipo"] == "Admin" ? true : false;
                }

then when your query fails you can not execute

$row = $results->fetch_assoc();

so your if should be

if($results && mysqli_num_rows($results)>0){

to be executed when the query works and returns results.

On the other hand, your query will not work because you are not escaping correctly, you should escape like this:

"SELECT * FROM usuario WHERE Usuario='".$Usuario."' AND Contrasena='".$Contrasena."'"

but this way of creating query is very insecure and can easily make an sql injection.

try to investigate about prepared querys, of type

if ($result= $mysqli->prepare("SELECT  * FROM  users WHERE  'name' =  ? and pass= ?")) {
        $result->bind_param('ss', $name, $pass,);  
        $result->execute();   
    
answered by 10.06.2017 в 19:59
1

The error is due, as stated in the previous answer, to an error in the if.

But, your code has a vulnerability that could be dangerous. It is a very bad practice to send the complete SQL query to the database, that is, query and data. Why? Because by doing so you open the door to the so-called SQL injection.

I show you a code snippet in which you can see an example of prepared queries . It is the recommended practice to consult the data when they involve values that can be taken from another party, such as forms and others.

It's an element to take very much into account if you want to write a robust code.

VIEW DEMO

Code:

<?php

require "util/public_db_info.php";

$mysqli = new mysqli($host_name, $user_name, $pass_word, $database_name, $port);

$sql = "SELECT * FROM books WHERE ean = ?"; 
$id=4;

//Preparar la consulta
$stmt=$mysqli->prepare($sql);

//Evaluar si  tuvo  éxito
if ($stmt) {
    /*
      * Pasar parámetros separados  de la instrucción SQL
      * Ejecutar
      * Almacenar los resultados
    */
    $stmt->bind_param("i", $id);
    $stmt->execute();
    $stmt->store_result();


    echo "<pre>";

    /*
      * Imptimir los  resultados
      * Si no  esta instalado  mysqlnd  es complicado obtener
      * los resultados en un  arreglo por eso uso una función  propia
    */


    while($row = mi_fetchassoc($stmt))
    { 
            echo "id: ".$row["id"]. " título: ".$row["title"]."\n";


    }

echo "</pre>";

    $stmt->close();
}

$mysqli->close();




// Función para cuando  no está  instalado  mysqlnd

function mi_fetchassoc($stmt)
{
    if($stmt->num_rows>0)
    {
        $rs = array();
        $md = $stmt->result_metadata();
        $params = array();
        while($field = $md->fetch_field()) {
            $params[] = &$rs[$field->name];
        }
        call_user_func_array(array($stmt, 'bind_result'), $params);
        if($stmt->fetch())
            return $rs;
    }

    return null;
}





?>

Result

id: 38053 título: Hamlet
id: 38054 título: Romeo y Julieta
id: 38055 título: Lo que el viento se llevó
id: 38056 título: No hay amor más grande
id: 38057 título: El Principito
id: 38058 título: El Quijote
    
answered by 11.06.2017 в 00:50