downloads | documentation | faq | getting help | mailing lists | licenses | wiki | reporting bugs | php.net sites | links | conferences | my php.net

search for in the

mysqli_stmt::close> <mysqli_stmt::bind_param
Last updated: Fri, 13 Nov 2009

view this page in

mysqli_stmt::bind_result

mysqli_stmt_bind_result

(PHP 5)

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() が返すステートメント ID。

var1

バインドする変数。

返り値

成功した場合に TRUE を、失敗した場合に FALSE を返します。

例1 オブジェクト指向型

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

if (
mysqli_connect_errno()) {
    
printf("Connect failed: %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("Connect failed: %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::close> <mysqli_stmt::bind_param
Last updated: Fri, 13 Nov 2009
 
add a note add a note User Contributed Notes
mysqli_stmt::bind_result
uramihsayibok, gmail, com
27-Jul-2009 08:35
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...
Miguel Hatrick
17-Jul-2009 04:18
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];
    }
}
?>
atulkashyap1 at hotmail dot com
25-Apr-2009 10:31
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();
  }
}
?>
hamidhossain at gmail dot com
01-Sep-2008 02:07
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);
?>
bb at servertje dot nl
23-Feb-2008 11:24
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;
    }
?>
thejkwhosaysni at gmail dot com
19-Oct-2005 08:12
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.
andrey at php dot net
07-Oct-2005 12:38
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.
matti at withoutthis dot keller dot com
25-Jul-2005 02:30
Hi
I saw a bit of discussion about using mysqli_stmt_bin_result dynamically, without knowing exactly how many columns will be returned.
After a while i developed this snippet to mimic the same behaviour as mysql_fetch_array():
<?php
# of fields in result set.
$nof = mysqli_num_fields( mysqli_stmt_result_metadata($handle) );

# The metadata of all fields
$fieldMeta = mysqli_fetch_fields( mysqli_stmt_result_metadata($handle) );
       
# convert it to a normal array just containing the field names
$fields = array();
for(
$i=0; $i < $nof; $i++)
   
$fields[$i] = $fieldMeta[$i]->name;

# The idea is to get an array with the result values just as in mysql_fetch_assoc();
# But we have to use call_user_func_array to pass the right number of args ($nof+1)
# So we create an array:
# array( $stmt, &$result[0], &$result[1], ... )
# So we get the right values in $result in the end!

# Prepare $result and $arg (which will be passed to bind_result)
$result = array();
$arg = array($this->stmt);
for (
$i=0; $i < $nof; $i++) {
   
$result[$i] = '';
   
$arg[$i+1] = &$result[$i];
}

call_user_func_array ('mysqli_stmt_bind_result',$arg);

# after mysqli_stmt_fetch(), our result array is filled just perfectly,
# but it is numbered (like in mysql_fetch_array() ), not indexed by field name!
# If you just want to mimic that ones behaviour you can stop here :)

mysqli_stmt_fetch($this->stmt);

# Now you can use $result
print_r($result);

# But beware! when using the fetch in a loop, always COPY $result or else you might
# end with all the same values because of the references
?>
Hope that this will help someone....
Matt
brad dot jackson at resiideo dot com
22-Mar-2005 05:10
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).

mysqli_stmt::close> <mysqli_stmt::bind_param
Last updated: Fri, 13 Nov 2009
 
 
show source | credits | stats | sitemap | contact | advertising | mirror sites