2

Here is the MYSQLi code:

  public function display() {
    $sql = "SELECT title, date_posted, text, url
              FROM notes ORDER BY date_posted DESC
              LIMIT ?, ?";
    $results = $this->query($sql, "ii",
                              $this->page_offset,
                              $this->notes_per_page);
    $results = $this->db->store_result();
    while ($row = $results->fetch_row()) {
      var_dump($row);
    }
    //$this->write($results);
  }

  // this is the $this->db->query() function referred to above.
  public function query() {
    $args = func_get_args();
    $statement = $this->db->prepare($args[0]);
    $args = array_slice($args, 1);
    call_user_func_array(array($statement, 'bind_param'), &$args);
    $statement->execute();
    return $statement;
  }

The MYSQL table:

mysql> desc notes;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| date_posted | date         | NO   |     | NULL    |                |
| title       | varchar(255) | NO   |     | NULL    |                |
| text        | longblob     | NO   |     | NULL    |                |
| url         | varchar(255) | NO   |     | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+

A sample row:

mysql> SELECT title, url, date_posted FROM notes WHERE url='init';
+-------+------+-------------+
| title | url  | date_posted |
+-------+------+-------------+
| init  | init | 2011-02-16  |
+-------+------+-------------+
1 row in set (0.00 sec)

The output for the corresponding row. What in the world...?:

array(4) { [0]=> string(0) "" [1]=> string(0) "" [2]=> string(4) "init" [3]=> string(4) "�" }

If I switch fetch_array() to fetch_object(), I get this:

object(stdClass)#3 (4) { ["title"]=> string(0) "" ["date_posted"]=> string(0) "" ["text"]=> string(4) "init" ["url"]=> string(4) "�" }

Thank you for all and any help/suggestions/comments!

New observation:

Adding another column to the query outputs a new column (the wrong one again though). So for example, if:

// and yes, I do realize that I am repeating 'url',
// and I have no clue why this is happening.
$sql = "SELECT title, date_posted, text, url, url
              FROM notes ORDER BY date_posted DESC
              LIMIT ?, ?";

Then the output row is:

array(5) { [0]=> string(0) "" [1]=> string(0) "" [2]=> string(4) "init" [3]=> string(4) "�" [4]=> string(350) "

This is the text for the init article. I cut it short for the sake of brevity in this stackoverflow question " }

Nona Urbiz
  • 4,873
  • 16
  • 57
  • 84
  • Do you get the same strange *before* $results = $this->db->store_result()? (you're assigning $results twice, no?) – jpwco Feb 19 '11 at 22:52
  • err, maybe I don't follow you, before `$this->db->store_result()`, $results is an `object(mysqli_stmt)`, and afterwards it is an `object(mysqli_result)`, which makes sense to me. Everything seems to be working perfectly except that the final data is mangled. – Nona Urbiz Feb 19 '11 at 23:22
  • What value did you expect for *url*? – Gumbo Feb 19 '11 at 23:38
  • The string "init". If you'll take another look at my post, I included the result of a MYSQL query (through the console) for the corresponding row to make it easy to see what the result should be. – Nona Urbiz Feb 19 '11 at 23:43
  • Which versions of MySQL and MYSQLi are you using? The doc for MYSQLi says you should run against MySQL 5.0.7 or newer (http://www.php.net/manual/en/mysqli.requirements.php). – Grzegorz Oledzki Feb 20 '11 at 22:25
  • Server version: 5.1.49-1ubuntu8.1 (Ubuntu) – Nona Urbiz Feb 21 '11 at 01:24

4 Answers4

1

    public function display() {
    $sql = "SELECT title, date_posted, text, url
              FROM notes ORDER BY date_posted DESC
              LIMIT ?, ?";
    $results = $this->query($sql, "ii",
                              $this->page_offset,
                              $this->notes_per_page);
    var_dump($results);
  }



 public function query() {
    $args = func_get_args();
    $statement = $this->db->prepare($args[0]);
    $args = array_slice($args, 1);
    call_user_func_array(array($statement, 'bind_param'), &$args);
    $statement->execute();
    $return = array();
$statement->store_result();
$row=array();
$data = $statement->result_metadata();
$fields = array();
$fields[0] = &$statement;
while($field = $data->fetch_field()) {
$fields[] = &$row[$field->name];
}
call_user_func_array("mysqli_stmt_bind_result", $fields);

$i = 0;
while ($statement->fetch()) {
foreach ($row as $key1=>$value1) $return[$i][$key1] = $value1;
$i++;
}
$statement->free_result();
return $return;


  }


Dev
  • 137
  • 6
  • I'm afraid I don't fully understand what this code is doing, but following your directions results in nothing being printed out. Switching the print_r to var_dump shows `NULL`. Thanks for helping though! – Nona Urbiz Feb 22 '11 at 20:56
  • did you do print_r or var_dump after this sentence $results=$this->query($sql,"ii",$this->page_offset,$this->notes_per_page); ??? – Dev Feb 23 '11 at 10:13
  • Hey! I don't know what went wrong before, but this works! I have to run to class, but I will accept your answer after I get back and try to understand what I was doing incorrectly in the first place. Thank you! – Nona Urbiz Feb 23 '11 at 20:10
0

There is a chance that because you're blowing away the statement object (you delete it by reassigning the variable that refers to it) it's getting garbage collected and affecting the result. Try changing your code like so:

 public function display() {
    $sql = "SELECT title, date_posted, text, url
              FROM notes ORDER BY date_posted DESC
              LIMIT ?, ?";
    // Notice the changed variable name
    $stmt = $this->query($sql, "ii",
                              $this->page_offset,
                              $this->notes_per_page);
    $results = $this->db->store_result();
    while ($row = $results->fetch_row()) {
      var_dump($row);
    }
    //$this->write($results);
  }
A. R. Younce
  • 1,913
  • 17
  • 22
0

(edit: oops I misread part of your code. Anyway...)

Before fetching data from a prepared statement, you have to bind variables to fetch into, using mysqli_stmt::bind_result(). Then, you fetch each row using mysqli_stmt::fetch().

public function display() {     
    $sql = "SELECT title, date_posted, text, url
            FROM notes ORDER BY date_posted DESC
            LIMIT ?, ?";
    $results = $this->query($sql, "ii", 
                      $this->page_offset,
                      $this->notes_per_page);

    /* We have to BIND variables to store the result in */
    $row = new StdClass;
    $row->title = null;
    $row->date_posted = null;
    $row->text = null;
    $row->url = null;
    $results->bind_results($row->title, $row->date_posted, $row->text, $row->url);

    while (($status = $results->fetch()) === true) { 
        var_dump($row):
    }
    if($status === false) die("Error fetching data");
}  
gnud
  • 77,584
  • 5
  • 64
  • 78
  • Unfortunately, I can't use this method as the 'text' column is a MEDIUMBLOB. mysqli attempts to allocate the maximum potential space taken by all rows immediately, which causes an error. Here is my original question regarding this issue: http://stackoverflow.com/questions/5052870/mysqli-bind-result-allocates-too-much-memory – Nona Urbiz Feb 22 '11 at 15:19
0

To be honest, I could not get your code working - store_result() keeps returning (bool)false. Though, this worked fine for me:

class Sandbox {

    private $db;
    private $page_offset = 0;
    private $notes_per_page = 10;

    public function __construct() {
        $this->db = new mysqli('127.0.0.1', 'user', 'pass', 'test');
    }

    /**
     */
    public function display() {
        $sql = "
            SELECT title, date_posted, text, url
            FROM notes
            ORDER BY date_posted DESC
            LIMIT ?, ?
        ";
        $statement = $this->query($sql, 'ii', $this->page_offset, $this->notes_per_page);
        $results = $statement->get_result();
        while ($row = $results->fetch_row()) {
            var_dump($row);
        }
    }

    /**
     * @param string $sql
     * @param string $types
     * @param mixed  $arg,...
     * @return mysqli_stmt
     */
    public function query($sql, $types = null, $arg = null, $arg = null) {
        $args = func_get_args();
        array_shift($args);

        $statement = $this->db->prepare($sql);
        call_user_func_array(array($statement, 'bind_param'), &$args);
        $statement->execute();

        return $statement;
    }

}

$notes = new Sandbox();
$notes->display();

Output:

array(4) {
  [0]=>
  string(4) "init"
  [1]=>
  string(10) "2011-02-16"
  [2]=>
  NULL
  [3]=>
  string(4) "init"
}
binaryLV
  • 9,002
  • 2
  • 40
  • 42
  • Running this code verbatim gives me the error `Fatal error: Call to undefined method mysqli_stmt::get_result()`. I looked here: http://php.net/manual/en/book.mysqli.php to see if I was missing something obvious, but I can't seem to find it listed there? – Nona Urbiz Feb 22 '11 at 20:49
  • It's listed in http://lv.php.net/manual/en/mysqli.summary.php as "NOT DOCUMENTED Available only with mysqlnd"... – binaryLV Feb 22 '11 at 21:21