mysqli_stmt::bind_param

mysqli_stmt_bind_param

(PHP 5)

mysqli_stmt::bind_param -- mysqli_stmt_bind_paramBinds variables to a prepared statement as parameters

Description

Object oriented style

bool mysqli_stmt::bind_param ( string $types , mixed &$var1 [, mixed &$... ] )

Procedural style

bool mysqli_stmt_bind_param ( mysqli_stmt $stmt , string $types , mixed &$var1 [, mixed &$... ] )

Bind variables for the parameter markers in the SQL statement that was passed to mysqli_prepare().

Note:

If data size of a variable exceeds max. allowed packet size (max_allowed_packet), you have to specify b in types and use mysqli_stmt_send_long_data() to send the data in packets.

Note:

Care must be taken when using mysqli_stmt_bind_param() in conjunction with call_user_func_array(). Note that mysqli_stmt_bind_param() requires parameters to be passed by reference, whereas call_user_func_array() can accept as a parameter a list of variables that can represent references or values.

Parameters

stmt

Procedural style only: A statement identifier returned by mysqli_stmt_init().

types

A string that contains one or more characters which specify the types for the corresponding bind variables:

Type specification chars
Character Description
i corresponding variable has type integer
d corresponding variable has type double
s corresponding variable has type string
b corresponding variable is a blob and will be sent in packets

var1

The number of variables and length of string types must match the parameters in the statement.

Return Values

Returns TRUE on success or FALSE on failure.

Examples

Example #1 Object oriented style

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

/* check connection */
if (mysqli_connect_errno()) {
    
printf("Connect failed: %s\n"mysqli_connect_error());
    exit();
}

$stmt $mysqli->prepare("INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
$stmt->bind_param('sssd'$code$language$official$percent);

$code 'DEU';
$language 'Bavarian';
$official "F";
$percent 11.2;

/* execute prepared statement */
$stmt->execute();

printf("%d Row inserted.\n"$stmt->affected_rows);

/* close statement and connection */
$stmt->close();

/* Clean up table CountryLanguage */
$mysqli->query("DELETE FROM CountryLanguage WHERE Language='Bavarian'");
printf("%d Row deleted.\n"$mysqli->affected_rows);

/* close connection */
$mysqli->close();
?>

Example #2 Procedural style

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

/* check connection */
if (!$link) {
    
printf("Connect failed: %s\n"mysqli_connect_error());
    exit();
}

$stmt mysqli_prepare($link"INSERT INTO CountryLanguage VALUES (?, ?, ?, ?)");
mysqli_stmt_bind_param($stmt'sssd'$code$language$official$percent);

$code 'DEU';
$language 'Bavarian';
$official "F";
$percent 11.2;

/* execute prepared statement */
mysqli_stmt_execute($stmt);

printf("%d Row inserted.\n"mysqli_stmt_affected_rows($stmt));

/* close statement and connection */
mysqli_stmt_close($stmt);

/* Clean up table CountryLanguage */
mysqli_query($link"DELETE FROM CountryLanguage WHERE Language='Bavarian'");
printf("%d Row deleted.\n"mysqli_affected_rows($link));

/* close connection */
mysqli_close($link);
?>

The above examples will output:

1 Row inserted.
1 Row deleted.

See Also

Коментарии

Автор:
Columns with type bigint need to be specified as type 'd' NOT 'i'.

Using 'i' results in large numbers (eg 3000169151) being truncated.

--
flame
2007-02-18 22:44:29
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
Автор:
It's worth noting that you have to bind all parameters in one fell swoop - you can't go through and call bind_param once for each.
2007-12-15 12:24:50
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
You can, in fact, use mysqli_bind_parameter to pass a NULL value to the database. simply create a variable and store the NULL value (see the manpage for it) to the variable and bind that. Works great for me anyway.
2010-02-10 22:24:36
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
Автор:
I did a prepared statement for inserting in a simple table - images ( blob ) and their unique identifiers ( string ). All my blobs have smaller sizes than the MAX-ALLOWED-PACKET value.

I've found that when binding my BLOB parameter, I need to pass it as a STRING, otherwise it's truncated to zero length in my table. So I have to do this:

<?php
   $ok 
$stmt->bind_param'ss'$id$im ) ;
?>
2010-03-18 17:42:16
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
Автор:
Blob and null handling aside, a couple of notes on how param values are automatically converted and forwarded on to the Mysql engine based on your type string argument:

1) PHP will automatically convert the value behind the scenes to the underlying type corresponding to your binding type string.  i.e.:

<?php

$var 
true;
bind_param('i'$var); // forwarded to Mysql as 1

?>

2) Though PHP numbers cannot be reliably cast to (int) if larger than PHP_INT_MAX, behind the scenes, the value will be converted anyway to at most long long depending on the size.  This means that keeping in mind precision limits and avoiding manually casting the variable to (int) first, you can still use the 'i' binding type for larger numbers.  i.e.:

<?php

$var 
'429496729479896';
bind_param('i'$var); // forwarded to Mysql as 429496729479900

?>

3) You can default to 's' for most parameter arguments in most cases.  The value will then be automatically cast to string on the back-end before being passed to the Mysql engine.  Mysql will then perform its own conversions with values it receives from PHP on execute.  This allows you to bind not only to larger numbers without concern for precision, but also to objects as long as that object has a '__toString' method.

This auto-string casting behavior greatly improves things like datetime handling.  For example: if you extended DateTime class to add a __toString method which outputs the datetime format expected by Mysql, you can just bind to that DateTime_Extended object using type 's'.  i.e.:

<?php

// DateTime_Extended has __toString defined to return the Mysql formatted datetime
$var = new DateTime_Extended;
bind_param('s'$var); // forwarded to Mysql as '2011-03-14 17:00:01'

?>
2011-03-14 16:28:02
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
Автор:
You can bind to variables with NULL values, and on update and insert queries, the corresponding field will be updated to NULL no matter what bind string type you associated it with.  But, for parameters meant for the WHERE clause (ie where field = ?), the query will have no effect and produce no results.

When comparing a value against NULL, the MYSQL syntax is either "value IS NULL" or "value IS NOT NULL".  So, you can't pass in something like "WHERE (value = ?)" and expect this to work using a null value parameter.

Instead, you can do something like this in your WHERE clause:

"WHERE (IF(ISNULL(?), field1 is null, field1 = ?))"

Then, pass in the value you want to test twice:

bind_param('ss', $value1, $value1);
2011-03-28 16:49:51
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
It should be noted that MySQL has some issues regarding the use of the IN clause in prepared statements.

I.e. the code:
<?php

$idArr 
"1, 2, 3, 4";
$int_one 1;
$int_two 2;
$int_three 3;
$int_four 4;

$db = new MySQLi();
$bad_stmt $db->prepare(SELECT `idAsLettersFROM `tblWHERE `idIN(?));
$bad_stmt->bind_param("s"$idArr);
$bad_stmt->bind_result($ias);
$bad_stmt->execute();

echo 
"Bad results:" PHP_EOL;
while(
$stmt->fetch()){
   echo 
$ias PHP_EOL;
}

$good_stmt->close();

$good_stmt $db->prepare(SELECT `idAsLettersFROM `tblWHERE `idIN(?, ?, ?, ?));
$good_stmt->bind_param("iiii"$int_one$int_two$int_three$int_four);
$good_stmt->bind_result($ias);
$good_stmt->execute();

echo 
"God results:" PHP_EOL;
while(
$stmt->fetch()){
   echo 
$ias PHP_EOL;
}
$bad_stmt->close();

$db->close();
?>
will print this result:

Bad results:
one

Good results:
one
two
three
four

Using "IN(?)" in a prepared statement will return just one (the first) row from a table/view. This is not an error in PHP, but merely how MySQL handles prepared statements.
2011-04-22 21:05:35
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
There are some things to note when working with mysqli::bind_param() and array-elements.
Re-assigning an array will break any references, no matter if the keys are identical.
You have to explicitly reassign every single value in an array, for the references to be kept.
Best shown in an example:
<?php
function getData() {
    return array(
       
0=>array(
           
"name"=>"test_0",
           
"email"=>"test_0@example.com"
       
),
       
1=>array(
           
"name"=>"test_1",
           
"email"=>"test_1@example.com"
       
)
    );
}
$db  = new mysqli("localhost","root","","tests");
$sql "INSERT INTO `user` SET `name`=?,`email`=?";
$res $db->prepare($sql);
// If you bind array-elements to a prepared statement, the array has to be declared first with the used keys:
$arr = array("name"=>"","email"=>""); 
$res->bind_param("ss",$arr['name'],$arr['email']);
//So far the introduction...

/* 
    Example 1 (wont work as expected, creates two empty entries)
    Re-assigning the array in the while()-head generates a new array, whereas references from bind_param stick to the old array
*/
foreach( getData() as $arr ) {
   
$res->execute();
}

/*
    Example 2 (will work as expected)
    Re-assigning every single value explicitly keeps the references alive
*/
foreach( getData() as $tempArr ) {
    foreach(
$tempArr as $k=>$v) {
       
$arr[$k] = $v;
    }
   
$res->execute();
}
?>
2011-05-20 17:39:25
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
MySQL has a "NULL-safe equal" operator (I'm guessing since 5.0)
http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#operator_equal-to

If you use this operator instead of the usual = you can interchange values and null in where clauses.

There is however a known bug when using this operator with datetime or timestamp fields: http://bugs.mysql.com/bug.php?id=36100
2011-07-16 21:50:37
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
It is believed that if one has specified 'b' in $types, the corresponding variable should be set to null, and one has to use mysqli_stmt::send_long_data() or mysqli_stmt_send_long_data() to send the blob, otherwise the blob value would be treated as empty.
2012-09-30 09:52:17
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
I just came across a very strange behaviour when using bind_param() with a reflection class.  I figured I ought to post it here to save anyone else who comes across it from banging their head against their desk for an hour (as I just did).

First, some background:  I have a set of classes,  one per file format (i.e. CSV, HTML table, etc), which import data from flat files to a temporary table in my database.  The class then transforms the data to 3NF.

I'm  using a reflection class to pass an array to mysqli->bind_param() because the column counts and types are variable.  The code (simplified) I am having issues with is:

<?php

/* Code that loops through the rows and columns in the 
 * flat file and appends the MySQLi 'type' letter to the
 * $typeString variable and appends the actual value
 * to the $data array.  I left the code out because it's 
 * (probably) not relevant and would bloat the post.
 */
$stmtInsert $db->prepare('INSERT.....');
$typeString 'ississis';
$data = array(1'two''three'4'five''six'7'eight');

/* Here's where the actual strangeness starts happening
 */

// Merge the parameter types with the parameter values
$data array_merge((array) $typeString$data);

// Create the reflection class
$ref = new \ReflectionClass('mysqli_stmt');

// Get the bind_param  method
$method $ref->getMethod('bind_param');

// Invoke it with $data
$method->invokeArgs($stmtInsert$data);

// Execute the statement
$stmtInsert->execute();

}
?>

Oddly, in one (and only one) case it started throwing "Warning: Parameter 41 to mysqli_stmt::bind_param() expected to be a reference, value given".  The reflection class throws an exception.  Other import sets using this code work just fine.  Parameter 41 is the last parameter.   Changing the affected code as follows resolves the issue:

<?php

$ref 
= new \ReflectionClass("mysqli_stmt");
$method $ref->getMethod("bind_param");
$data[count($data)-1] = (string) $data[count($data)-1];
$method->invokeArgs($stmtInsert$data);
$stmtInsert->execute();

?>

Not sure what's going on here, but like I said, hopefully this will keep the next person from thinking they're totally insane.
2013-10-09 00:08:56
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
When trying to bind a string param you get a "Number of variables doesn't match number of parameters in prepared statement" error, make sure you're not wrapping the question mark with quotes.

By mistake I had a query like:
SELECT something FROM table WHERE param_name = "?"

Binding it with <?php $stmt->bind('s'$param_value); ?> had been failing on me. All I had to do was to remove quotes around "?".
Hope this saves someone's time.
2014-03-27 17:46:16
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
Parameter type matters more than you might think!

A cautionary tail to any who would seek to find less than thorough solutions for automating prepared statements. Take the following mysqli_stmt extension method for example. 

<?php

public function param_type($param)
{
    if (
ctype_digit((string) $param)
        return 
$param <= PHP_INT_MAX 'i' 's';

    if (
is_numeric($param))
        return 
'd';

    return 
's';
}

?>

At face value this seems like a perfectly straightforward and innocuous function. Something like this served as a small piece in a larger automation extension which dutifully served its purpose efficiently handling hundreds of thousands of queries a day.

Now I know what you're thinking: it doesn't handle blob types. Well we didn't work with blob types (and still don't) so that's never been an issue. This problem was far more insidious and ultimately pernicious than that.

So what went wrong? The problem began to surface when we started automating SELECT queries on a newly created index for a column designed to store telephone numbers. The column was of type VARCHAR but the data stored was always formatted as an integer. Not a problem when performing a write operation but as soon as we went to read from the table on this index everything went to hell.

We're not entirely sure, but as near as we can tell the act of binding a parameter to a VARCHAR index as 'i' instead of 's' on a read query is detrimental in the following way: MySQL will ignore the b-tree on the index and perform a full table scan. With smaller tables this may never present itself as a significant performance issue. When your tables get into the tens of millions of rows, however...
2016-03-06 07:59:52
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
Автор:
Hey Folks,

just wanted to mention that parameters can only be used for input data, NOT for Table, Columns or Database names.
That gave me a headache yesterday!
So this code will not work:

$searchtype = "Title";
$searchterm = "The Fellowship of the Ring: The Lord of the Rings";

$query = 
"SELECT ISBN, Author, Title, Price 
FROM books 
WHERE ? = ?";

$mySql_stmt = $db->prepare($query);
$mySql_stmt->bind_param("ss" , $searchtype, $searchterm);
$mySql_stmt->execute(); 

In contrast, you will have to include the searchtype in ther query directly like this:

$searchtype = "Title";
$searchterm = "The Fellowship of the Ring: The Lord of the Rings";
$query = 
"SELECT ISBN, Author, Title, Price 
FROM books 
WHERE $searchtype = ?";

$mySql_stmt = $db->prepare($query);
$mySql_stmt->bind_param("s", $searchterm);
$mySql_stmt->execute(); 

Hope that helps someone to have a peaceful nights sleep :)
2016-11-10 09:57:36
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
Автор:
if bind_param() fails due to Number of elements in type definition string doesn't match number of bind variables. it triggers an E_WARNING error. and you will not find that error in $stmt->error property
2017-01-16 12:09:18
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
Автор:
A small remark from what I tried:
- if you use prepared statements with bind_param and your query looks like
"SELECT user_id FROM users WHERE ... = ?" and then you bind an integer param to this, the user_ids you get will be casted to int. On the other hand, if you don't use prepared statements, but sth like "SELECT user_id FROM users WHERE ... = $var", where $var is an int, and just make the query, the fetched results will be strings. (e.g., at var_dump,  ["user_id"]=> string(1) "6" for some row)
This is just from what I observed in my project, hope it's correct.
2017-07-10 18:23:20
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
There are two solutions in this page for calling bind_param() via  call_user_func_array() that involve using a user-created function called refValues(), so that you can pass the parameters to bind_param() as references. 

This works perfectly in PHP v5.3 (and I assume before), but since upgrading to PHP v7.1.7, the refValues() functions here no longer correctly convert the arrays to arrays of references. Instead you will get a warning: 

"PHP Warning:  Parameter 3 to mysqli_stmt_bind_param() expected to be a reference, value given"

I believe this is because of changes to arrays and reference handling as noted in the "Migrating from PHP 5.6.x to PHP 7.0.x" guide in Backwards Incompatibilities (change: "foreach by-value operates on a copy of the array"). 

So in PHP v7.1.7 at least, the user-created function refValues() no longer returns an array of references but instead a normal array of values. 

Changing the function definition of refValues() to accept the array as a reference seems to fix this - as intended it returns an array of references and thus bind_param() works as expected (although I haven't tested this super thoroughly to make sure there are no other ill effects, especially in older versions of PHP). 

New refValues() definition is simply: 

<?php
function refValues(&$arr// Changed $arr to reference for PHP v7.1.7 
{
    if (
strnatcmp(phpversion(),'5.3') >= 0//Reference is required for PHP 5.3+
   
{
       
$refs = array();
        foreach(
$arr as $key => $value)
           
$refs[$key] = &$arr[$key];
        return 
$refs;
     }
     return 
$arr;
}
?>
2017-07-16 11:20:54
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
I sometimes forget that you can't put functions inside. For example:

If I wanted to use md5() on a value like so:
<?php
$stmt
->bind_param("s",md5($val));
?>
If would not work. Because it uses the variables by binding them, you need to change them beforehand like this:
<?php
$val 
md5($val);
$stmt->bind_param("s",$val);
?>
2019-01-29 09:29:29
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html
Автор:
It is very important to understand that you can not supply bind_param values

this will not work:

    $stmt -> bind_param("s", "value");
 

you have to do it like this :

    $var =  "value";
    $stmt -> bind_param("s", $var);
2021-08-02 00:26:11
http://php5.kiev.ua/manual/ru/mysqli-stmt.bind-param.html

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