MySQL fetch_array returns false

iconer

i'm pretty new with PHP, so maybe my question is so dumb but anyways...

I have this code to check if exist some user and a email address

    $username = $_POST['user'];
    $email = $_POST['email'];

    $isUsernameTaken = false;
    $isEmailTaken = false;

    // check for email availability
    $result = DBConnection::isEmailTaken($email);
    if(count($result) > 0) {
        $isEmailTaken = true;
        $response["error"] = 3;
    } 


    $anotherResult = DBConnection::isUsernameTaken($username);
    if(count($anotherResult) > 0) {
        $isUsernameTaken = true;
        $response["error"] = 2;
    } 

when i try it with a non existing data, lets say:

username = jfgsjhfsjfjhsfsf email = [email protected]

the isEmailTaken($email) function retuns '[]' and the if is false, thats correct!!!

but the isUsernameTaken function returns 'false' so the if is always true, thats incorrect:(

if i change the order of the code now the isUsernameTaken function returns '[]' and the other function return 'false'

Why is that?

PD. When i try it in MySQL console it works fine, so the error is in PHP

my db connection class is the provided by @Evan de la Cruz(Static version)

Evan de la Cruz

As others have said, accessing a static member as an instance member may be contributing to the issue. Also, constructing an object with the new keyword (ex: $foo = new Bar();) will never result in false. It will either succeed and return the constructed object, or it will fail with an error or exception.

I can't be sure that these are the only issues, but try using the following (corrected) code and let me know if any issues remain.

<?php
class DBConnection {
    private static $db;
    private static $host;
    private static $user;
    private static $password;

    private static $connection;

    function __construct() {
        if (!isset(self::$connection))
        {
            self::$db = 'myDB';
            self::$host = 'localhost';
            self::$user = 'root';
            self::$password = '1234';
            self::connect();
        }
   }

   /**
    * Note: You don't really need the connect method at all, unless you are trying to get the connection
    * from outside classes.
    * You could instead just put this code in the constructor
    */
    private static function connect() {
        if(!isset(self::$connection)) {
            self::$connection = new mysqli(self::$host, self::$user, self::$password, self::$db);
        }
    }

    function isEmailTaken($email) {
        $q = "CALL isEmailTaken('".$email."');";
        $result = $this -> select($q);

        return $result;
    }

    function isUsernameTaken($username) {
        $q = "CALL isUsernameTaken('".$username."');";
        $result = $this -> select($q);

        return $result;
    }

    public function query($q) {
        $result = self::$connection -> query($q);

        return $result;
    }

    public function select($query) {
        $rows = array();

        $result = $this -> query($query);
        if($result === false) {
            return false;
        }

        while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
            array_push($rows, $row);
        }

        return $rows;
    }

    function tryToLogin($username, $pass) {
        $q = "CALL getUserData('".$username."','".$pass."');";
        $result = $this -> select($q);

        return $result;
    }
}
?>

Also, you might consider just making this whole class static. Unless you are going to ever have more than one instance of it with different settings. but, if you are always going to have just this single instance, then it is probably cleaner to make the entire class static. Like so:

<?php
class DBConnection {
    private static $db;
    private static $host;
    private static $user;
    private static $password;
    private static $connection;


    private static function connect($db,$host,$user,$password) {
        if(!isset(self::$connection)) {
            self::$db = $db;
            self::$host = $host;
            self::$user = $user;
            self::$password = $password;
            self::$connection = new mysqli(self::$host, self::$user, self::$password, self::$db);
        }
    }

    public static function isEmailTaken($email) {
        $q = "CALL isEmailTaken('".$email."');";
        $result = self::select($q);

        return $result;
    }

    public static function isUsernameTaken($username) {
        $q = "CALL isUsernameTaken('".$username."');";
        $result = self::select($q);

        return $result;
    }

    public static function query($q) {
        self::connect("myDV", "localhost", "root", "1234");
        $result = self::$connection -> query($q);
        return $result;
    }

    public static function select($query) {
        $rows = array();

        $result = self::query($query);
        if($result === false) {
            return false;
        }

        while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
            array_push($rows, $row);
        }

        return $rows;
    }

    public static function tryToLogin($username, $pass) {
        $q = "CALL getUserData('".$username."','".$pass."');";
        $result = self::select($q);

        return $result;
    }
}
?>

You would then call the methods like this:

$isEmailTaken = DBConnection::isEmailTaken("an email address");
$isUserTaken = DBConnection::isUsernameTaken("a user name");

And you will never instantate DBConnection. (In other words, never call new DBConnection()) Explaining the difference between static classes and instance classes is quite difficult, and often even experienced PHP programmers don't have a clue as to the difference. (Programmers in other OO languages tend to understand it better.)

But the idea is this:

An instance class can be "instantiated" unlimited times. And each time, a new instance of the class is created. This is call an object. Each instance of the class can have different properties and so each instance can act different.

A static class cannot be instantiated. There is never an instance. It functions the same way no matter what. It is kind of like having one single instance (the difference being that there is no constructor and members are accessed statically [i.e. using the "self" keyword instead of "this"])

There is a pattern called "singleton" which is actually a single instance. So it is important that you do not think of statics as a single instance, although they are very similar.

Consider the following cases:

Case 1: You have a class called "Person" with the properties "Name" and "Gender". For this you would use an instance class, because there can be many people and each person can have different properties:

$john = new Person("John Doe","Male");
$joe = new Person("Joe Smith","Male");
$tina = new Person("Tina Thomson","Feale");

Case 2: You have a class call "Math" with the methods Add() and Subtract(). Adding and subtracting is ALWAYS the same. There is only one type of math. There is no need to have multiple instances. That is to say, Math is static.

$sum = Math::Add(1,5);
$difference = Math::Subtract(10,5);

Notice that we never construct the static Math class using new Math().

EDIT: Here is the problem, I believe:

if($result === false) {
    return false;
}

I'd have to see your stored procedures to explain why. But I'm fairly sure this is your problem.

Here is the fixed version:

<?php
class DBConnection {
    private static $db;
    private static $host;
    private static $user;
    private static $password;
    private static $connection;


    private static function connect($db,$host,$user,$password) {
        if(!isset(self::$connection)) {
            self::$db = $db;
            self::$host = $host;
            self::$user = $user;
            self::$password = $password;
            self::$connection = new mysqli(self::$host, self::$user, self::$password, self::$db);
        }
    }

    public static function isEmailTaken($email) {
        $q = "CALL isEmailTaken('".$email."');";
        $result = self::select($q);

        return $result;
    }

    public static function isUsernameTaken($username) {
        $q = "CALL isUsernameTaken('".$username."');";
        $result = self::select($q);

        return $result;
    }

    public static function query($q) {
        self::connect("myDV", "localhost", "root", "1234");
        $result = self::$connection -> query($q);
        return $result;
    }

    public static function select($query) {
        $rows = array();

        $result = self::query($query);
        if ($result !== false)
        {
            while ($row = $result->fetch_array(MYSQLI_ASSOC)) {
                array_push($rows, $row);
            }
        } else {
            //uncomment this line to see what the underlying problem actually is.
            //die("The error from mysql is: ". self::$connection->errno . ": " . self::$connection->error);
        }

        return $rows;
    }

    public static function tryToLogin($username, $pass) {
        $q = "CALL getUserData('".$username."','".$pass."');";
        $result = self::select($q);

        return $result;
    }
}
?>

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related