0

I am trying to change the following code to use MySqli instead of MySql. I have removed some methods that seem unimportant to what I'm addressing here.

class db {
    var $hostname,
        $database,
        $username,
        $password,
        $connection,
        $last_query,
        $last_i,
        $last_resource,
        $last_error;

    function db($hostname=DB_HOSTNAME,$database=DB_DATABASE,$username=DB_USERNAME,$password=DB_PASSWORD) {
        $this->hostname = $hostname;
        $this->database = $database;
        $this->username = $username;
        $this->password = $password;

        $this->connection = mysql_connect($this->hostname,$this->username,$this->password) or $this->choke("Can't connect to database");
        if($this->database) $this->database($this->database);
        }

    function database($database) {
        $this->database = $database;
        mysql_select_db($this->database,$this->connection);
        }

    function query($query,$flag = DB_DEFAULT_FLAG) {
        $this->last_query = $query;

        $resource = mysql_query($query,$this->connection) or $this->choke();
        list($command,$other) = preg_split("|\s+|", $query, 2);

        // Load return according to query type...
        switch(strtolower($command)) {
            case("select"):
            case("describe"):
            case("desc"):
            case("show"):
                $return = array();
                while($data = $this->resource_get($resource,$flag)) $return[] = $data;
                //print_r($return);
                break;
            case("replace"):
            case("insert"):
                if($return = mysql_insert_id($this->connection))
                    $this->last_i = $return;
                break;
            default:
                $return = mysql_affected_rows($this->connection);
            }

        return $return;
        }

    function resource_get($resource = NULL,$flag = DB_DEFAULT_FLAG) {
        if(!$resource) $resource = $this->last_resource;
        return mysql_fetch_array($resource,$flag);
        }   
    }

This is what I've got so far:

class db {
    var $hostname = DB_HOSTNAME,
        $database = DB_DATABASE,
        $username = DB_USERNAME,
        $password = DB_PASSWORD,
        $connection,
        $last_query,
        $last_i,
        $last_resource,
        $last_error;

    function db($hostname, $database, $username, $password) {
        $this->hostname = $hostname;
        $this->database = $database;
        $this->username = $username;
        $this->password = $password;

        $this->connection = new mysqli($this->hostname, $this->username, $this->password, $this->database) or $this->choke("Can't connect to database");
if (mysqli_connect_errno())
  {
  echo "Failed to connect to MySQL: " . mysqli_connect_error();
  }


        if($this->database)
            $this->database($this->database);
    }

    function database($database) {
        $this->database = $database;
        mysqli_select_db($this->connection, $this->database );
    }

    function query($query, $flag = DB_DEFAULT_FLAG) {
        $this->last_query = $query;
//print_r($query);
        $result = mysqli_query($this->connection, $query) or $this->choke("problem connecting to DB");
while($row=mysqli_fetch_assoc($result)) {
$resource[]=$row;
}
//print($command);
//print_r($resource);print("<br>");
        list($command, $other) = preg_split("|\s+|", $query, 2);

        // Load return according to query type...
        switch(strtolower($command)) {
            case("select"):
            case("describe"):
            case("desc"):
            case("show"):
                $return = array();
                while($data = $this->resource_get($resource, $flag))
                    $return[] = $data;
                //print_r($return);
                break;
            case("replace"):
            case("insert"):
                if($return = mysqli_insert_id($this->connection))
                    $this->last_i = $return;
                break;
            default:
                $return = mysqli_affected_rows($this->connection);
            }

        return $return;
        }

    function resource_get($resource = NULL, $flag = DB_DEFAULT_FLAG) {
        if(!$resource)
            $resource = $this->last_resource;
        return mysqli_fetch_array($resource, $flag);
    }

So here's the problem: I've checked the results with a print_r() and the $resource array is loading correctly, but the value of $return when checked with print_r() just ends up being "Array()". Therefore, as near as I can figure, something isn't being handled correctly in this part of the code, which is why I included the resource_get() function call:

            $return = array();
            while($data = $this->resource_get($resource, $flag))
                $return[] = $data;
            //print_r($return);
            break;

If I use mysqli_fetch_row($resource, $flag) instead of mysqli_fetch_array($resource, $flag) I still get the same result, i.e. print_r($return) yields simply "Array()".

user1780242
  • 541
  • 1
  • 10
  • 25
  • 1
    Looks like `$resource` _already_ contains your result array, because `while($row=mysqli_fetch_assoc($result)) { $resource[]=$row; }`. When you pass `$resource` into `$this->resource_get()`, its call to `mysqli_fetch_array()` is getting an array instead of a result resource. Don't bother with the `resource_get()` method if you have already fetched the rows. To verify this for yourself, just `print_r($resource)` before the `switch` or in `switch:"show"`. – Michael Berkowski Aug 30 '14 at 18:38
  • This suggests you don't have `display_errors` turned on, because `resource_get()` should be throwing warnings. Always when developing code, `error_reporting(E_ALL); ini_set('display_errors', 1);` – Michael Berkowski Aug 30 '14 at 18:39
  • Thanks, Michael. That solved it. I just removed the while loop and made $return = $resource and it works! This wasn't my code and I frankly didn't understand why I needed a call to resource_get() and with MySqli I guess I don't. – user1780242 Aug 30 '14 at 21:12
  • I'll convert it to an answer then, hang on... – Michael Berkowski Aug 30 '14 at 21:13
  • Yeah, there's a lot in here that's kind of redundant to wrap existing functionality of `mysql_*()` and `mysqli_()`. I would consider that unnecessary. Probably it was done to add an object-oriented layer onto `mysql_*()`, but MySQLi already supports OO methodology. – Michael Berkowski Aug 30 '14 at 21:18
  • I think that's right, and I think I probably don't actually need a DB object now but at least it keeps all the DB calls in one place. I tried just doing the mysqli_query() in a function and ended up with some sort of loop that was overloading my DB connections. – user1780242 Aug 30 '14 at 21:21

1 Answers1

1

The variable $resource does not represent a mysqli_result resource object at the time you pass it into $this->resource_get(). Instead, it is already a 2D array of results since you previously ran a mysqli_fetch_assoc() loop.

To make this work with your current code, you may either remove the earlier fetch loop:

$result = mysqli_query($this->connection, $query) or $this->choke("problem connecting to DB");
// Remove this
//while($row=mysqli_fetch_assoc($result)) {
//  $resource[]=$row;
//}

And later, pass $result instead of $resource into your resource_get() method since it is $result that is the resource object.

Or, you might just skip the resource_get() call entirely and return $resource directly since it already contains the result array.

Michael Berkowski
  • 267,341
  • 46
  • 444
  • 390