mysqli_stmt::bind_result

mysqli_stmt_bind_result

(PHP 5, PHP 7)

mysqli_stmt::bind_result -- mysqli_stmt_bind_result Привязка переменных к подготовленному запросу для размещения результата

Описание

Объектно-ориентированный стиль

bool mysqli_stmt::bind_result ( mixed &$var1 [, mixed &$... ] )

Процедурный стиль

bool mysqli_stmt_bind_result ( mysqli_stmt $stmt , mixed &$var1 [, mixed &$... ] )

Привязывает столбцы результирующего набора к переменным.

При вызове mysqli_stmt_fetch() для выборки данных, протокол клиент-серверного взаимодействия MySQL помещает выбранные данные в переменные var1, ... привязанные к столбцам результата выборки.

Замечание:

Следует заметить, что все столбцы должны быть привязаны к переменным после вызова mysqli_stmt_execute() и до вызова mysqli_stmt_fetch(). В зависимости от типов данных столбцов привязанные переменные могут неявно изменять свой PHP тип.

Столбцы можно привязывать и перепривязывать многократно, даже когда результирующий набор уже частично выбран. Новая привязка даст эффект при следующем вызове mysqli_stmt_fetch().

Список параметров

stmt

Только для процедурного стиля: Идентификатор выражения, полученный с помощью mysqli_stmt_init().

var1

Привязываемая переменная.

Возвращаемые значения

Возвращает TRUE в случае успешного завершения или FALSE в случае возникновения ошибки.

Примеры

Пример #1 Объектно-ориентированный стиль

<?php
$mysqli 
= new mysqli("localhost""my_user""my_password""world");

if (
mysqli_connect_errno()) {
    
printf("Не удалось подключиться: %s\n"mysqli_connect_error());
    exit();
}

/* подготовка запроса */
if ($stmt $mysqli->prepare("SELECT Code, Name FROM Country ORDER BY Name LIMIT 5")) {
    
$stmt->execute();

    
/* привязка переменных к запросу */
    
$stmt->bind_result($col1$col2);

    
/* выборка данных */
    
while ($stmt->fetch()) {
        
printf("%s %s\n"$col1$col2);
    }

    
/* закрываем запрос */
    
$stmt->close();
}
/* закрываем подключение */
$mysqli->close();

?>

Пример #2 Процедурный стиль

<?php
$link 
mysqli_connect("localhost""my_user""my_password""world");

/* попытка подключения */
if (!$link) {
    
printf("Не удалось подключиться: %s\n"mysqli_connect_error());
    exit();
}

/* подготовка запроса */
if ($stmt mysqli_prepare($link"SELECT Code, Name FROM Country ORDER BY Name LIMIT 5")) {
    
mysqli_stmt_execute($stmt);

    
/* привязка переменных к запросу */
    
mysqli_stmt_bind_result($stmt$col1$col2);

    
/* выборка данных */
    
while (mysqli_stmt_fetch($stmt)) {
        
printf("%s %s\n"$col1$col2);
    }

    
/* закрываем запрос */
    
mysqli_stmt_close($stmt);
}

/* закрываем подключение */
mysqli_close($link);
?>

Результат выполнения данных примеров:

AFG Afghanistan
ALB Albania
DZA Algeria
ASM American Samoa
AND Andorra

Смотрите также

  • mysqli_stmt_get_result() - Получает результат из подготовленного запроса
  • mysqli_stmt_bind_param() - Привязка переменных к параметрам подготавливаемого запроса
  • mysqli_stmt_execute() - Выполняет подготовленный запрос
  • mysqli_stmt_fetch() - Связывает результаты подготовленного выражения с переменными
  • mysqli_prepare() - Подготавливает SQL выражение к выполнению
  • mysqli_stmt_prepare() - Подготовка SQL запроса к выполнению
  • mysqli_stmt_init() - Инициализирует запрос и возвращает объект для использования в mysqli_stmt_prepare
  • mysqli_stmt_errno() - Возвращает код ошибки выполнения последнего запроса
  • mysqli_stmt_error() - Возвращает строку с пояснением последней ошибки при выполнении запроса

Коментарии

A potential problem exists in binding result parameters from a prepared statement which reference large datatypes like mediumblobs.  One of our database tables contains a table of binary image data.  Our largest image in this table is around 50Kb, but even so the column is typed as a mediumblob to allow for files larger than 64Kb.  I spent a frustrating hour trying to figure out why mysqli_stmt_bind_result choked while trying to allocate 16MB of memory for what should have been at most a 50Kb result, until I realized the function is checking the column type first to find out how big a result _might_ be retrieved, and attempting to allocate that much memory to contain it.  My solution was to use a more basic mysqli_result() query.  Another option might have been to retype the image data column as blob (64Kb limit).
2005-03-22 11:10:39
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
If you select LOBs use the following order of execution or you risk mysqli allocating more memory that actually used

1)prepare()
2)execute()
3)store_result()
4)bind_result()

If you skip 3) or exchange 3) and 4) then mysqli will allocate memory for the maximal length of the column which is 255 for tinyblob, 64k for blob(still ok), 16MByte for MEDIUMBLOB - quite a lot and 4G for LONGBLOB (good if you have so much memory). Queries which use this order a bit slower when there is a LOB but this is the price of not having memory exhaustion in seconds.
2005-10-07 08:38:42
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
I've created these functions which will act like mysqli_fetch_array() and mysqli_fetch_object() but work with bound results.

<?php
   
function fetch_object() {
       
$data mysqli_stmt_result_metadata($this->stmt);
       
$count 1//start the count from 1. First value has to be a reference to stmt.
       
$fieldnames[0] = &$this->stmt;
       
$obj = new stdClass;
        while (
$field mysqli_fetch_field($data)) {
           
$fn $field->name//get all the feild names
           
$fieldnames[$count] = &$obj->$fn//load the fieldnames into an object..
           
$count++;
        }
       
call_user_func_array(mysqli_stmt_bind_result$fieldnames);
       
mysqli_stmt_fetch($this->stmt);
        return 
$obj;
    }

    function 
fetch_array() {
       
$data mysqli_stmt_result_metadata($this->stmt);
       
$count 1//start the count from 1. First value has to be a reference to the stmt. because bind_param requires the link to $stmt as the first param.
       
$fieldnames[0] = &$this->stmt;
        while (
$field mysqli_fetch_field($data)) {
           
$fieldnames[$count] = &$array[$field->name]; //load the fieldnames into an array.
           
$count++;
        }
       
call_user_func_array(mysqli_stmt_bind_result$fieldnames);
       
mysqli_stmt_fetch($this->stmt);
        return 
$array;

    }

?>

Hope this helps some people, I was puzzled by this for a while.
2005-10-19 16:12:06
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
Although inspired by an earlier post, this method could be added to any of your database objects. It's an object oriented implementation of an earlier post.

The method returns an array with objects representing a row. Each property represents a column and its value.
 
<?php
   
private function getresult($stmt)
    {
     
$result = array();
     
     
$metadata $stmt->result_metadata();
     
$fields $metadata->fetch_fields();

      for (;;)
      {
       
$pointers = array();
       
$row = new stdClass();
       
       
$pointers[] = $stmt;
        foreach (
$fields as $field)
        {
         
$fieldname $field->name;
         
$pointers[] = &$row->$fieldname;
        }
       
       
call_user_func_array(mysqli_stmt_bind_result$pointers);
       
        if (!
$stmt->fetch())
          break;
       
       
$result[] = $row;
      }
     
     
$metadata->free();
     
      return 
$result;
    }
?>
2008-02-23 17:24:41
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
lot of people don't like how bind_result works with prepared statements! it requires you to pass long list of parameters which will be loaded with column value when the function being called.

To solve this, i used call_user_func_array function and result_metadata functions. which make easy and automatically returns an array of all columns results stored in an array with column names.

please don't forget to change setting variables with your own credentials:

<?php
$host 
'localhost';
$user 'root';
$pass '1234';
$data 'test';

$mysqli = new mysqli($host$user$pass$data);
/* check connection */
if (mysqli_connect_errno()) {
   
printf("Connect failed: %s\n"mysqli_connect_error());
    exit();
}

if (
$stmt $mysqli->prepare("SELECT * FROM sample WHERE t2 LIKE ?")) {
   
$tt2 '%';
   
   
$stmt->bind_param("s"$tt2);
   
$stmt->execute();

   
$meta $stmt->result_metadata();
    while (
$field $meta->fetch_field())
    {
       
$params[] = &$row[$field->name];
    }

   
call_user_func_array(array($stmt'bind_result'), $params);

    while (
$stmt->fetch()) {
        foreach(
$row as $key => $val)
        {
           
$c[$key] = $val;
        }
       
$result[] = $c;
    }
   
   
$stmt->close();
}
$mysqli->close();
print_r($result);
?>
2008-09-01 10:07:39
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
bind_ result can also be used to return an array of variables from a function,
This took me a long time to figure out, so I would like to share this.

<?php
function extracting(){
 
$query="SELECT topic, detail, date, tags
    FROM updates
    ORDER BY date DESC
    LIMIT 5 "
;
  if(
$stmt $this->conn->prepare($query)) {
   
$stmt->execute();
   
$stmt->bind_result($updates[0],$updates[1],$updates[2],$updates[3]);
   
$i=0;
    while(
$stmt->fetch()){
     
$i++;
     
$name='t'.$i;
      $
$name = array($updates[0],$updates[1],$updates[2],$updates[3]);
    }
    return array(
$t1,$t2,$t3,$t4,$t5,);
   
$stmt->close();
  }
}
?>
2009-04-25 06:31:24
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
Автор:
Took some cool code from here and made a little class for those object oriented kind of guys

used like this:

<?php
// execute prepared statement
$stmt->execute();
$stmt->store_result();
           
//custom class :D bind to Statement Result mambo jambo!
$sr = new Statement_Result($stmt);
           
$stmt->fetch();
printf("ID: %d\n"$sr->Get('id') );

/////////////////////////////////

class Statement_Result
{
    private 
$_bindVarsArray = array();
    private 
$_results = array();

    public function 
__construct(&$stmt)
    {
       
$meta $stmt->result_metadata();

        while (
$columnName $meta->fetch_field())
           
$this->_bindVarsArray[] = &$this->_results[$columnName->name];

       
call_user_func_array(array($stmt'bind_result'), $this->_bindVarsArray);
       
       
$meta->close();
    }
   
    public function 
Get_Array()
    {
        return 
$this->_results;   
    }
   
    public function 
Get($column_name)
    {
        return 
$this->_results[$column_name];
    }
}
?>
2009-07-17 12:18:22
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
A note to people to want to return an array of results - that is, an array of all the results from the query, not just one at a time.

<?php

// blah blah...
call_user_func_array(array($mysqli_stmt_object"bind_result"), $byref_array_for_fields);

$results = array();
while (
$mysqli_stmt_object->fetch()) {
   
$results[] = $byref_array_for_fields;
}

?>
This will NOT work. $results will have a bunch of arrays, but each one will have a reference to $byref.

PHP is optimizing performance here: you aren't so much copying the $byref array into $results as you are *adding* it. That means $results will have a bunch of $byrefs - the same array repeated multiple times. (So what you see is that $results is all duplicates of the last item from the query.)

hamidhossain (01-Sep-2008) shows how to get around that: inside the loop that fetches results you also have to loop through the list of fields, copying them as you go. In effect, copying everything individually.

Personally, I'd rather use some kind of function that effectively duplicates an array than write my own code. Many of the built-in array functions don't work, apparently using references rather than copies, but a combination of array_map and create_function does.

<?php

// blah blah...
call_user_func_array(array($mysqli_stmt_object"bind_result"), $byref_array_for_fields);

// returns a copy of a value
$copy create_function('$a''return $a;');

$results = array();
while (
$mysqli_stmt_object->fetch()) {
   
// array_map will preserve keys when done here and this way
   
$results[] = array_map($copy$byref_array_for_fields);
}

?>

All these problems would go away if they just implemented a fetch_assoc or even fetch_array for prepared statements...
2009-07-27 16:35:44
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
If done properly, 'call_user_func_array()' works to bind variables to a result of multiple columns including BLOB columns. 

EXAMPLE:

<?php
$data 
= array() ; // Array that accepts the data.
$params = array() ; // Parameter array passed to 'bind_result()'
$column = array("fidentity""fvarchar""fdate""ftinyblob") ; // The column names.
foreach($column as $col_name)
{
 
// 'fetch()' will assign fetched value to the variable '$data[$col_name]'
 
$params[] =& $data[$col_name] ;
}
$res call_user_func_array(array($stmt"bind_result"), $params) ;
?>

Here's the complete example.
WARNING: When using 'prepare' to prepare a statement to retrieve LOBs the method order matters.
Also, method 'store_result()' must be called and be called in correct order.
Failure to observe this causes PHP/MySQLi to crash or return an erroneous value.
The proper procedure order is: prepare -> execute -> store_result -> bind -> fetch

<?php
$database 
"test" ;
$table "test" ;
$column = array("fidentity""fvarchar""fdate""ftinyblob") ;
$select_set "`fidentity`, `fvarchar`, `fdate`, `ftinyblob`" ;
$mysqli = new mysqli("localhost""root"$password$database);
// Proper procedure order: prepare -> execute -> store_result -> bind -> fetch
$stmt $mysqli->prepare("SELECT $select_set FROM `$table`") ;
$stmt->execute();
$stmt->store_result(); 
$data = array() ; // Array that accepts the data.
$params = array() ; // Parameter array passed to 'bind_result()'
foreach($column as $col_name)
{
 
// Assign the fetched value to the variable '$data[$name]'
 
$params[] =& $data[$col_name] ;
}
$res call_user_func_array(array($stmt"bind_result"), $params) ;
if(! 
$res)
{
  echo 
"bind_result() failed: " $mysqli->error "\n" ;
}
else
{
 
$res $stmt->fetch() ;
  if(
$res)
  {
      echo 
"<pre>" htmlentities(print_r($datatrue)) . "</pre>\n" ;
  }
  else
  {
    echo ((
false !== $res) ? "End of data" $stmt->error) . "\n" ;
  }
}
$stmt->close() ;
$mysqli->close() ;
exit ;
?>

The above example should output:
Array (
  [fidentity] => 24
  [fvarchar] => the rain in spain
  [fdate] => 2010-07-31
  [ftinyblob] => GIF89a...(more BLOB data)
)
2010-07-31 22:06:34
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
Автор:
If I have a longtext field in the result, the whole page will go blank, without giving me any errors what so ever. This is because PHP _crashes_. I've spent an entire morning figuring this out.

Apparently, if you have longtext present, you HAVE to call store_result before using bind_result.

http://bugs.php.net/bug.php?id=47928
2010-12-23 06:19:26
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
I wrote a function that fetches all rows from a result set - either normal or prepared.

<?php
function fetch($result)
{   
   
$array = array();
   
    if(
$result instanceof mysqli_stmt)
    {
       
$result->store_result();
       
       
$variables = array();
       
$data = array();
       
$meta $result->result_metadata();
       
        while(
$field $meta->fetch_field())
           
$variables[] = &$data[$field->name]; // pass by reference
       
       
call_user_func_array(array($result'bind_result'), $variables);
       
       
$i=0;
        while(
$result->fetch())
        {
           
$array[$i] = array();
            foreach(
$data as $k=>$v)
               
$array[$i][$k] = $v;
           
$i++;
           
           
// don't know why, but when I tried $array[] = $data, I got the same one result in all rows
       
}
    }
    elseif(
$result instanceof mysqli_result)
    {
        while(
$row $result->fetch_assoc())
           
$array[] = $row;
    }
   
    return 
$array;
}
?>

Simply call it passing a result set or executed statement and you'll get all rows fetched.
2011-02-01 03:02:02
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
To clarify for anyone having problems with arrays, PHP will automatically pass arrays as references, cloning the array if needed in the event of setting or unsetting a part of it, changing a referenced variable does not trigger cloning.

This is done for efficiency, to clone an array containing this information you may either use a foreach loop, or set/unset a key. Techniques like array_values will also work provided you don't mind losing your keys.
2011-06-16 03:02:53
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
According to the above documentation: 
"Depending on column types bound variables can silently change to the corresponding PHP type. "

if you specify a field as int (tinyint, mediumint, etc.) with zerofill property, it will be converted (silently) to PHP integer (erasing the leading zeros). In order to keep those leading zeros, one solution is to specify the field as decimal.

Note that this only happens when using prepared statements and not when executing the query directly.
2011-07-26 01:31:33
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
Just wanted to make sure that all were aware of get_result for those needing the result in array format.

In the code sample, after execute(), perform a get_result() like this:

<?php

// ... this document's example code:

   
$stmt->execute();

   
/* instead of bind_result: */
   
$result $stmt->get_result();

   
/* now you can fetch the results into an array - NICE */
   
while ($myrow $result->fetch_assoc()) {
       
printf("%s %s\n"$myrow['Code'], $myrow['Name']);
    }

?>

This is much nicer when you have a dozen or more fields coming back from your query.  Hope this helps.  Also, as noted in the comments for get_result, it requires mysqlnd.
2012-02-20 21:29:23
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
Автор:
for people who doesn't have the mysqlInd driver or for some reason just can't use the stmt->get_result, I've made this function which allows you to "mimic" the mysqli_result::fetch_assoc:

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

        return null;
    }

you can use it in a while sentence to fetch and return an assoc array from the statement (as long as the statement is open):
usage:
$statement = $mysqli->prepare($query));
$statement.execute();
while($rowAssocArray = fetchAssocStatement($statement))
{
    //do something
}

$statement.close();

hope this helps.
2015-02-20 05:53:19
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
For those of you trying to bind rows into array,
<?php
$stmt 
$db->prepare('SELECT id, name, mail, phone, FROM contacts');
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($arr['id'], $arr['name'], $arr['mail'], $arr['phone']);
while (
$stmt->fetch()) {
   
$outArr[] = $arr;
}
$stmt->close();
return 
$outArr;
?>
this will give you all the rows you asked for except that they would all be the same as the first one because of some gremlins in the background code (i've heard that PHP is trying to save memory here).

But this one works:
<?php
$stmt 
$db->prepare('SELECT id, name, mail, phone, FROM contacts');
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($a,$b,$c,$d);
while (
$stmt->fetch()) {
   
$outArr[] = ['id' => $a'name' => $b'mail' => $c'phone' => $d];
}
$stmt->close();
return 
$outArr;
?>
Just don't use arrays to bind results :)
2015-03-05 20:31:32
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html
From PHP 7.4+, you can use the spread operator (...) to easily automate the process of assigning variables to the query statement, and to fetch data when executing a SELECT request using prepared statements.

However, the spread operator takes in consideration the size of the array. So it must be pre allocated before used in any context.

<?php 
    $link 
// Create DB Connection

   
$query_text "SELECT mission, year, report FROM table WHERE id=? AND name=?;";

   
// Data to assign
   
$types "is";
   
$param = [0"John Titor"];

   
// Prepare and Execute Statement
   
$stmt mysqli_stmt_prepare($link$query_text);
    if (
mysqli_stmt_execute($stmt)) {

       
// We know we are going to retrieve 3 columns: Mission, Year and Report.
       
$output = [000];

       
// Behind the scenes, the spread operator gives this idea when used: 
        // mysqli_stmt_bind_result($link, $output[0], $output[1], $output[2]);
       
mysqli_stmt_bind_result($stmt, ...$output);

       
// Fetch data
       
while (mysqli_stmt_fetch($stmt)) {
            echo 
"Mission: " $output[0] . "\n";
            echo 
"Year: " $output[1] ."\n";
            echo 
"Report: " $output[2] . "\n";
        }

    } else {
        echo 
"Error: Wrong Timeline\n";
    }

   
// Close DB Connection
?>
2022-01-25 02:16:43
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-result.html

    Поддержать сайт на родительском проекте КГБ