Skip to content
 

MySQLi: Avoid Explicitly Listing Every Column in bind_result()

Upon being motivated by a “PHP style critique” discussion at the WebDeveloper.com forums, I dug around the manual page for mysqli_stmt::bind_result(), and noticed an interesting suggestion for the use of the call_user_func_array() function in combination with the bind_result() method (see the user note by “hamidhossain”).

The essence of the technique is to use call_user_func_array() to call the bind_param() method, supplying the list of variables to be bound via an array which has its elements defined as references to the actual variables you want bound. In the following example, I’m referencing them to a class variable named $data which is an associative array where the keys are the field names for the database table being operated upon.

<?php
class Test
{
   /**
    * MySQLi object
    * @var object
    */
   private $db;

   /**
    * DB fields to be used in this table
    * @var array
    */
   private $data = array(
      'ID' => null,
      'col_1' => null,
      'col_2' => null,
      'col_3' => null,
      'col_4' => null
   );

   /**
    * Constructor
    * @param object $db  MySQLi
    */
   public function __construct(mysqli $db)
   {
      $this->db = $db;
   }

   /**
    * Populate data from DB for specified ID
    * @param int $id
    * @return bool
    */
   public function populate($id)
   {
      $sql = sprintf(
         "SELECT `%s` FROM `example_table` WHERE ID = ?",
         implode("`, `", array_keys($this->data))
      );
      $stmt = $this->db->prepare($sql);
      $stmt->bind_param('i', $id);
      $stmt->execute() or die('exec');
      $stmt->store_result();
      if($stmt->num_rows == 1)
      {
         $params = array();
         foreach($this->data as $key => $val)
         {
            $params[] = &$this->data[$key]; // note use of reference
         }
         call_user_func_array(array($stmt, 'bind_result'), $params);
         $stmt->fetch();
         $return = true;
      }
      else
      {
         user_error("No rows returned for id '$id'");
         $return = false;
      }
      return $return;
   }

   /**
    * Get record data as assoc. array
    * @return array
    */
   public function getData()
   {
      return $this->data;
   }
}

// TEST IT:
$db = new mysqli('localhost', 'username', 'password', 'test_db');
$test = new Test($db);
$test->populate((int)$_GET['id']);
echo "<pre>".print_r($test->getData(), 1)."</pre>";
?>

Thanks to “hamidhoussain” wherever you are for enlightening me to the use of call_user_func_array().

One Comment

  1. Charles says:

    As an addendum to this, you can use a similar technique with a variable number of input parameters and the bind_param() function as described at http://phpbuilder.com/board/showthread.php?p=10933647#post10933647 .

Leave a Reply

You must be logged in to post a comment.