PDOStatement::bindValue

(PHP 5 >= 5.1.0, PHP 7, PHP 8, PECL pdo >= 1.0.0)

PDOStatement::bindValue 绑定值到参数

描述

public PDOStatement::bindValue(string|int $param, mixed $value, int $type = PDO::PARAM_STR): bool

将值绑定到 SQL 语句中相应的命名或问号占位符,该 SQL 语句用于准备语句。

参数

param

参数标识符。对于使用命名占位符的准备语句,这将是 :name 格式的参数名称。对于使用问号占位符的准备语句,这将是参数的 1 索引位置。

value

要绑定到参数的值。

type

使用 PDO::PARAM_* 常量 的参数的显式数据类型。

返回值

成功时返回 true,失败时返回 false

错误/异常

如果属性 PDO::ATTR_ERRMODE 设置为 PDO::ERRMODE_WARNING,则发出级别为 E_WARNING 的错误。

如果属性 PDO::ATTR_ERRMODE 设置为 PDO::ERRMODE_EXCEPTION,则抛出 PDOException

示例

示例 #1 使用命名占位符执行准备语句

<?php
/* 通过绑定 PHP 变量来执行准备语句 */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour'
);

/* 使用其名称设置参数值 */
$sth->bindValue('calories', $calories, PDO::PARAM_INT);
/* 可选地,参数名称也可以以冒号 ":" 为前缀 */
$sth->bindValue(':colour', $colour, PDO::PARAM_STR);
$sth->execute();
?>

示例 #2 使用问号占位符执行准备语句

<?php
/* 通过绑定 PHP 变量来执行准备语句 */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
FROM fruit
WHERE calories < ? AND colour = ?'
);
$sth->bindValue(1, $calories, PDO::PARAM_INT);
$sth->bindValue(2, $colour, PDO::PARAM_STR);
$sth->execute();
?>

参见

添加笔记

用户贡献的笔记 14 个笔记

159
streaky at mybrokenlogic dot com
16 年前
bindValue() 文档没有解释的一点(如果不仔细阅读的话),就是 bindParam() 是通过引用传递给 PDO 的,而 bindValue() 则不是。

因此,使用 bindValue(),您可以执行类似 $stmt->bindValue(":something", "bind this"); 的操作,而使用 bindParam() 则会失败,因为您无法通过引用传递字符串,例如。
70
D.Kellner
8 年前
在绑定参数时,显然您不能重复使用占位符(例如 "select * from mails where sender=:me or recipient=:me"),您必须为它们指定不同的名称,否则您的查询将返回空结果(但不会失败,不幸的是)。如果您遇到类似问题,请注意这一点。
30
e-ruiz at git hub
7 年前
使用 PDO::PARAM_INT 进行验证时要小心。

请考虑以下示例

<?php
/* php --version
* PHP 5.6.25 (cli) (built: Aug 24 2016 09:50:46)
* Copyright (c) 1997-2016 The PHP Group
* Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
*/

$id = '1a';
$stm = $pdo->prepare('select * from author where id = :id');
$bind = $stm->bindValue(':id', $id, PDO::PARAM_INT);

$stm->execute();
$authors = $stm->fetchAll();

var_dump($id); // string(2)
var_dump($bind); // true
var_dump((int)$id); // int(1)
var_dump(is_int($id)); // false
var_dump($authors); // the author id=1 =(

// remember
var_dump(1 == '1'); // true
var_dump(1 === '1'); // false
var_dump(1 === '1a'); // false
var_dump(1 == '1a'); // true
?>

我的观点:bindValue() 应该首先在内部测试 is_int(),然后再进行任何操作。
这是一个错误吗?我不确定。
42
cpd-dev
14 年前
虽然 bindValue() 会转义引号,但它不会转义 "%" 和 "_",因此在使用 LIKE 时要小心。如果参数本身没有转义,恶意参数中充满 "%%" 可以转储整个数据库。
19
匿名
13 年前
请注意,在大多数情况下,第三个参数 ($data_type) 不会将值类型转换为查询中使用的任何其他类型,也不会在类型与提供的值不匹配时抛出任何错误。此参数本质上没有任何效果,除非设置了它并且不是浮点数,才会抛出错误,因此不要认为它为查询增加了任何额外的安全级别。

执行类型转换的两个例外情况:

- 如果使用 PDO::PDO_PARAM_INT 并提供布尔值,则会将其转换为长整型
- 如果使用 PDO::PDO_PARAM_BOOL 并提供长整型,则会将其转换为布尔值

<?php

$query
= 'SELECT * FROM `users` WHERE username = :username AND `password` = ENCRYPT( :password, `crypt_password`)';

$sth= $dbh->prepare($query);

// First try passing a random numerical value as the third parameter
var_dump($sth->bindValue(':username','bob', 12345.67)); // bool(true)

// Next try passing a string using the boolean type
var_dump($sth->bindValue(':password','topsecret_pw', PDO::PARAM_BOOL)); // bool(true)

$sth->execute(); // Query is executed successfully
$result = $sth->fetchAll(); // Returns the result of the query

?>
18
contact[at]maximeelomari.com
13 年前
此函数用于在数组上绑定值。可以使用 $typeArray 预先指定值的类型。

<?php
/**
* @param string $req : 要链接值的查询
* @param array $array : 包含要绑定的值的关联数组
* @param array $typeArray : 关联数组,其中包含与 $array 中相应键的期望值
* */
function bindArrayValue($req, $array, $typeArray = false)
{
if(
is_object($req) && ($req instanceof PDOStatement))
{
foreach(
$array as $key => $value)
{
if(
$typeArray)
$req->bindValue(":$key",$value,$typeArray[$key]);
else
{
if(
is_int($value))
$param = PDO::PARAM_INT;
elseif(
is_bool($value))
$param = PDO::PARAM_BOOL;
elseif(
is_null($value))
$param = PDO::PARAM_NULL;
elseif(
is_string($value))
$param = PDO::PARAM_STR;
else
$param = FALSE;

if(
$param)
$req->bindValue(":$key",$value,$param);
}
}
}
}

/**
* ## 例子 ##
* $array = array('language' => 'php','lines' => 254, 'publish' => true);
* $typeArray = array('language' => PDO::PARAM_STR,'lines' => PDO::PARAM_INT,'publish' => PDO::PARAM_BOOL);
* $req = 'SELECT * FROM code WHERE language = :language AND lines = :lines AND publish = :publish';
* 可以像这样绑定 $array:
* bindArrayValue($array,$req,$typeArray);
* 当使用 limit 子句时,该函数更有用,因为它们需要整型。
* */
?>
3
Vladimir Kovpak
9 年前
<?php
/**
* 绑定位值。
*/

$sql = 'SELECT * FROM myTable WHERE level & ?';
$sth = \App::pdo()->prepare($sql);
$sth->bindValue(1, 0b0101, \PDO::PARAM_INT);
$sth->execute();
$result = $sth->fetchAll(\PDO::FETCH_ASSOC);
0
me at iabdullah dot info
10 年前
我们无法在调用 bindValue() 之后定义值变量的原因是,它会立即将值绑定到准备好的语句,而不会等待 execute() 的执行。

以下代码将发出一个通知,并阻止查询执行
<?php
$st
= $db->prepare ("SELECT * FROM posts WHERE id= :val ");
$st->bindValue(':val',$val);

$val = '2';
$st->execute();
?>
输出
注意:未定义变量:val。

而在 bindParam 的情况下,对参数的值的计算将不会在执行 execute() 之前进行。这是为了获得引用传递的优势。
<?php
$st
= $db->prepare ("SELECT * FROM posts WHERE id = :val ");
$st->bindParam(':val',$val);

$val = '2';
//
// some code
//
$val = '3'; // 重新分配值变量
$st->execute();
?>
运行良好。
0
nicolas dot baptiste at gmail dot com
14 年前
这实际上可以用于在 MySQL 中的整数字段上绑定 NULL

$stm->bindValue(':param', null, PDO::PARAM_INT);
-4
sageptr at gmail dot com
7 年前
注意边缘情况!
使用 MySQL 原生预处理,您的整数可能会在某些机器上发生溢出。

<?php
$x
= 2147483648;
var_dump($x); // 输出: int(2147483648)
$s = $db->prepare('SELECT :int AS I, :str AS S;');
$s->bindValue(':int', $x, PDO::PARAM_INT);
$s->bindValue(':str', $x, PDO::PARAM_STR);
$s->execute();
var_dump( $s->fetchAll(PDO::FETCH_ASSOC) );
/* 输出: array(2) {
["I"]=>
string(11) "-2147483648"
["S"]=>
string(10) "2147483648"
} */
?>

此外,尝试在 MySQL 中使用原生预处理绑定 PDO::PARAM_BOOL 可能会导致查询静默失败并返回空集。

在这些情况下,模拟预处理工作更稳定,因为它们将所有内容转换为字符串,并仅决定是否对参数进行引用。
-4
goofiq dot no dot spam at antispam dot wp dot pl
14 年前
bindValue 带数据类型取决于参数名称

<?php

$db
= new PDO (...);
$db -> setAttribute (PDO::ATTR_STATEMENT_CLASS, array ('MY_PDOStatement ', array ($db)));

class
MY_PDOStatement extends PDOStatement {

public function
execute ($input = array ()) {
foreach (
$input as $param => $value) {
if (
preg_match ('/_id$/', $param))
$this -> bindValue ($param, $value, PDO::PARAM_INT);
else
$this -> bindValue ($param, $value, PDO::PARAM_STR);
}
return
parent::execute ();
}

}

?>
-6
ts//tpdada//art//pl
17 年前
一次性绑定整个数组

<?php

function PDOBindArray(&$poStatement, &$paArray){

foreach (
$paArray as $k=>$v){

@
$poStatement->bindValue(':'.$k,$v);

}
// foreach

} // function

// 例子

$stmt = $dbh->prepare("INSERT INTO tExample (id,value) VALUES (:id,:value)");

$taValues = array(
'id' => '1',
'value' => '2'
); // 数组

PDOBindArray($stmt,$taValues);

$stmt->execute();

?>
-10
consatangmailcom
8 年前
参数名称必须像 PHP 变量一样。
例如:
<?php
$dbh
= new PDO("mysql:dbname=test;host=127.0.0.1", "user", "password");

$sth = $dbh->prepare("SELECT * FROM `table` WHERE `last-name`=:last-name");

if(
$sth !== false && $sth->bindValue(":last-name", "Ngo")) {
$sth->execute();
}

// 输出: PHP Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
?>
-29
Lambdaman
15 年前
如果您想将空值绑定到数据库字段,则必须在引号中使用 'NULL'(对于 MySQL)

<?php

$stmt
->bindValue(:fieldName, 'NULL');

// 不是
$stmt->bindValue(:fieldName, NULL);
// 或者
$stmt->bindValue(:fieldName, null);

?>

使用 PHP 的 null/NULL 作为值不起作用。
To Top