300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > php pdo 查询语句 PDO:预处理语句(参数化查询)

php pdo 查询语句 PDO:预处理语句(参数化查询)

时间:2024-04-03 19:13:36

相关推荐

php pdo 查询语句 PDO:预处理语句(参数化查询)

@(PDO(PHP data object/PHP数据对象))[PDO|预处理语句|参数化查询]

The database library called PHP Data Objects or PDO for short can use drivers for many different database types, and supports a very important feature known as prepared statements, sometimes also known as parametrized queries.

PDO::prepare

Paste_Image.png

在执行之前,对一条语句进行预处理,并返回一个语句对象。

预处理一条 SQL 语句,以便 PDOStatement::execute() 方法执行。该 SQL 语句可以包含 0 或更多个命名参数(:name)或问号参数(?),这些参数的真实值在语句执行的时候会被替换掉。使用这些参数绑定所有的用户输入的数据,不要在查询中直接包含用户输入的数据。

返回值:

如果数据库服务器成功地预处理了该语句,PDO::prepare() 将会返回一个 PDOStatement 对象;否则,返回 false 或 抛出 PDOException(依 error handling 而定)。

模拟的预处理语句并没有与数据库服务器进行通信,所以PDO::prepare()并没有检查该语句。

PDOStatement::bindParam

Paste_Image.png

原来 PDO 官方手册的简要描述的描述顺序有点怪怪的,并且后面的详细描述也不一致。所以这里把简要描述跟详细描述中的描述顺序统一一下。

Binds the specified variable name to a parameter.

绑定 指定的变量名(只能是 $name 的形式)到 一个参数(:name 或 ?参数 ,可以是 :name 或 从1 开始的索引 的形式)。

绑定 一个 PHP 变量 到 预处理语句中对应的命名占位符或问号占位符。

与 PDOStatement::bindValue() 不同的是:PDOStatement::bindParam() 中的变量是作为引用而绑定的,并且只有在调用 PDOStatement::execute() 的时候才会读取这个变量的值。

Note we used bindValue and not bindParam. Trying to bind a parameter by reference will generate a Fatal Error and this cannot be caught by PDOException either.

但如果需要循环执行预处理语句,最好使用bindParam,具体原因见对应的章节:Executing prepared statements in a loop。

返回值:

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

例如:

/* Execute a prepared statement by binding PHP variables */

$calories = 150;

$colour = 'red';

$sth = $dbh->prepare('SELECT name, colour, calories

FROM fruit

WHERE calories < :calories AND colour = :colour');

$sth->bindParam(':calories', $calories, PDO::PARAM_INT);

$sth->bindParam(':colour', $colour, PDO::PARAM_STR, 12);

$sth->execute();

/* Execute a prepared statement by binding PHP variables */

$calories = 150;

$colour = 'red';

$sth = $dbh->prepare('SELECT name, colour, calories

FROM fruit

WHERE calories < ? AND colour = ?');

$sth->bindParam(1, $calories, PDO::PARAM_INT);

$sth->bindParam(2, $colour, PDO::PARAM_STR, 12);

$sth->execute();

PDOStatement::bindValue

Paste_Image.png

Binds a value to a parameter.

绑定 一个值(可以是 $name 或 'Jack' 的形式) 到 一个参数(:name 或 ?参数 ,可以是 :name 或 从1 开始的索引 的形式)。

绑定 一个值 到 预处理语句中对应的命名占位符或问号占位符。

返回值:

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

例如:

$stm->bindValue(':name',$name);

$stm->bindValue(':name','Jack');

PDOStatement::execute

Paste_Image.png

Executes a prepared statement.

执行一条 经过预处理的语句。

如果预处理语句中包含占位符,则必须执行以下两点之一:

调用PDOStatement::bindParam() 或 PDOStatement::bindValue() 把变量或值绑定到占位符上。

或 传入一个数组

1. 参数:

$input_parameters:一个数组。数组的元素数量 应该与 需要执行的 SQL 语句中占位符数量 相等。

所有的值作为 PDO::PARAM_STR 处理。

不能绑定多个值到一个单独的参数;比如,不能绑定两个值到 IN()子句中一个单独的命名占位符。

绑定值的数量不能超过指定的数量。如果在 $input_parameters 的键名数量 比 PDO::prepare() 中的 SQL 语句中指定的参数的数量还要多,则该语句将会失败并发出一个错误。

$input_parameters 中的键名 必须和 SQL 中声明的 相匹配。在 PHP 5.2.0 之前,这是被忽略的。

2. 返回值:

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

例如:

/* Execute a prepared statement by passing an array of insert values */

$calories = 150;

$colour = 'red';

$sth = $dbh->prepare('SELECT name, colour, calories

FROM fruit

WHERE calories < :calories AND colour = :colour');

$sth->execute(array(':calories' => $calories, ':colour' => $colour));

/* Execute a prepared statement by passing an array of insert values */

$calories = 150;

$colour = 'red';

$sth = $dbh->prepare('SELECT name, colour, calories

FROM fruit

WHERE calories < ? AND colour = ?');

$sth->execute(array($calories, $colour));

Preparing Statements using SQL functions

You may ask how do you use SQL functions with prepared statements. I've seen people try to bind functions into placeholders like so:

//THIS WILL NOT WORK!

$time = 'NOW()';

$name = 'BOB';

$stmt = $db->prepare("INSERT INTO table(`time`, `name`) VALUES(?, ?)");

$stmt->execute(array($time, $name));

This does not work, you need to put the function in the query as normal:

$name = 'BOB';

$stmt = $db->prepare("INSERT INTO table(`time`, `name`) VALUES(NOW(), ?)");

$stmt->execute(array($name));

You can bind arguments into SQL functions however:

$name = 'BOB';

$password = 'badpass';

$stmt = $db->prepare("INSERT INTO table(`hexvalue`, `password`) VALUES(HEX(?), PASSWORD(?))");

$stmt->execute(array($name, $password));

Also note that this does NOT work for LIKE statements:

//THIS DOES NOT WORK

$stmt = $db->prepare("SELECT field FROM table WHERE field LIKE %?%");

$stmt->bindParam(1, $search, PDO::PARAM_STR);

$stmt->execute();

So do this instead:

$stmt = $db->prepare("SELECT field FROM table WHERE field LIKE ?");

$stmt->bindValue(1, "%$search%", PDO::PARAM_STR);

$stmt->execute();

Note we used bindValue and not bindParam. Trying to bind a parameter by reference will generate a Fatal Error and this cannot be caught by PDOException either.

但如果需要循环执行预处理语句,最好使用bindParam,具体原因见对应的章节:Executing prepared statements in a loop。

Executing prepared statements in a loop

Prepared statements excel in being called multiple times in a row with different values.

Because the sql statement gets compiled first, it can be called multiple times in a row with different arguments, and you'll get a big speed increase vs calling mysql_query over and over again!

Typically this is done by binding parameters with bindParam. bindParam is much like bindValue except instead of binding the value of a variable, it binds the variable itself, so that if the variable changes, it will be read at the time of execute.

$values = array('bob', 'alice', 'lisa', 'john');

$name = '';

$stmt = $db->prepare("INSERT INTO table(`name`) VALUES(:name)");

$stmt->bindParam(':name', $name, PDO::PARAM_STR);

foreach($values as $name) {

$stmt->execute();

}

Transactions

Here's an example of using transactions in PDO: (note that calling beginTransaction() turns off auto commit automatically):

try {

$db->beginTransaction();

$db->exec("SOME QUERY");

$stmt = $db->prepare("SOME OTHER QUERY?");

$stmt->execute(array($value));

$stmt = $db->prepare("YET ANOTHER QUERY??");

$stmt->execute(array($value2, $value3));

$db->commit();

} catch(PDOException $ex) {

//Something went wrong rollback!

$db->rollBack();

echo $ex->getMessage();

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。