PHP的PDO预处理语句与存储过程


Posted in PHP onJanuary 27, 2019

PHP PDO 预处理语句与存储过程

很多更成熟的数据库都支持预处理语句的概念。

什么是预处理语句?可以把它看作是想要运行的 SQL 的一种编译过的模板,它可以使用变量参数进行定制。预处理语句可以带来两大好处:

  • 查询仅需解析(或预处理)一次,但可以用相同或不同的参数执行多次。当查询准备好后,数据库将分析、编译和优化执行该查询的计划。对于复杂的查询,此过程要花费较长的时间,如果需要以不同参数多次重复相同的查询,那么该过程将大大降低应用程序的速度。通过使用预处理语句,可以避免重复分析/编译/优化周期。简言之,预处理语句占用更少的资源,因而运行得更快。
  • 提供给预处理语句的参数不需要用引号括起来,驱动程序会自动处理。如果应用程序只使用预处理语句,可以确保不会发生SQL 注入。(然而,如果查询的其他部分是由未转义的输入来构建的,则仍存在 SQL 注入的风险)。

预处理语句如此有用,以至于它们唯一的特性是在驱动程序不支持的时PDO 将模拟处理。这样可以确保不管数据库是否具有这样的功能,都可以确保应用程序可以用相同的数据访问模式。

用预处理语句进行重复插入

下面例子通过用 name 和 value 替代相应的命名占位符来执行一个插入查询

<?php
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);
// 插入一行
$name = 'one';
$value = 1;
$stmt->execute();
// 用不同的值插入另一行
$name = 'two';
$value = 2;
$stmt->execute();
?>

用预处理语句进行重复插入

下面例子通过用 name 和 value 取代 ? 占位符的位置来执行一条插入查询。

<?php
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)");
$stmt->bindParam(1, $name);
$stmt->bindParam(2, $value);
// 插入一行
$name = 'one';
$value = 1;
$stmt->execute();
// 用不同的值插入另一行
$name = 'two';
$value = 2;
$stmt->execute();
?>

使用预处理语句获取数据

下面例子获取数据基于键值已提供的形式。用户的输入被自动用引号括起来,因此不会有 SQL 注入攻击的危险。

<?php
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name = ?");
if ($stmt->execute(array($_GET['name']))) {
 while ($row = $stmt->fetch()) {
  print_r($row);
 }
}
?>

如果数据库驱动支持,应用程序还可以绑定输出和输入参数.输出参数通常用于从存储过程获取值。输出参数使用起来比输入参数要稍微复杂一些,因为当绑定一个输出参数时,必须知道给定参数的长度。如果为参数绑定的值大于建议的长度,就会产生一个错误。

带输出参数调用存储过程

<?php
$stmt = $dbh->prepare("CALL sp_returns_string(?)");
$stmt->bindParam(1, $return_value, PDO::PARAM_STR, 4000);
// 调用存储过程
$stmt->execute();
print "procedure returned $return_value\n";
?>

还可以指定同时具有输入和输出值的参数,其语法类似于输出参数。在下一个例子中,字符串"hello"被传递给存储过程,当存储过程返回时,hello 被替换为该存储过程返回的值。

带输入/输出参数调用存储过程

<?php
$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");
$value = 'hello';
$stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000);
// 调用存储过程
$stmt->execute();
print "procedure returned $value\n";
?>

占位符的无效使用

<?php
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE '%?%'");
$stmt->execute(array($_GET['name']));
// 占位符必须被用在整个值的位置
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE ?");
$stmt->execute(array("%$_GET[name]%"));
?>

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。如果你想了解更多相关内容请查看下面相关链接

PHP 相关文章推荐
PHP如何得到当前页和上一页的地址?
Nov 27 PHP
海河写的 Discuz论坛帖子调用js的php代码
Aug 23 PHP
php 8小时时间差的解决方法小结
Dec 22 PHP
PHP面向对象分析设计的61条军规小结
Jul 17 PHP
apache+codeigniter 通过.htcaccess做动态二级域名解析
Jul 01 PHP
PHP strip_tags()去除HTML、XML以及PHP的标签介绍
Feb 18 PHP
PHP中使用SimpleXML检查XML文件结构实例
Jan 07 PHP
PHP中的命名空间相关概念浅析
Jan 22 PHP
php函数传值的引用传递注意事项分析
Jun 25 PHP
Yii框架表单提交验证功能分析
Jan 07 PHP
深入解析Laravel5.5中的包自动发现Package Auto Discovery
Sep 13 PHP
PHP树形结构tree类用法示例
Feb 01 PHP
PHP中数组转换为SimpleXML教程
Jan 27 #PHP
实例讲解php实现多线程
Jan 27 #PHP
php中访问修饰符的知识点总结
Jan 27 #PHP
实例讲解php将字符串输出到HTML
Jan 27 #PHP
PHP常见加密函数用法示例【crypt与md5】
Jan 27 #PHP
PHP基于GD2函数库实现验证码功能示例
Jan 27 #PHP
PHP的PDO事务与自动提交
Jan 24 #PHP
You might like
php 在文件指定行插入数据的代码
2010/05/08 PHP
PHP5.6新增加的可变函数参数用法分析
2017/08/25 PHP
如何通过View::first使用Laravel Blade的动态模板详解
2017/09/21 PHP
PHP7基于curl实现的上传图片功能
2018/05/11 PHP
javascript实现二分查找法实现代码
2007/11/12 Javascript
Js sort排序使用方法
2011/10/17 Javascript
jquery链式操作的正确使用方法
2014/01/06 Javascript
Jquery easyUI 更新行示例
2014/03/06 Javascript
jQuery实现向下滑出的平滑下拉菜单效果
2015/08/21 Javascript
jquery ajax双击div可直接修改div中的内容
2016/03/04 Javascript
javascript鼠标滑过显示二级菜单特效
2020/11/18 Javascript
vue-router 学习快速入门
2017/03/01 Javascript
bootstrap3-dialog-master模态框使用详解
2017/08/22 Javascript
Vue结合后台导入导出Excel问题详解
2019/02/19 Javascript
基于Vue插入视频的2种方法小结
2019/04/02 Javascript
微信小程序swiper使用网络图片不显示问题解决
2019/12/13 Javascript
vue+elementUI组件table实现前端分页功能
2020/11/15 Javascript
python的三目运算符和not in运算符使用示例
2014/03/03 Python
浅述python中argsort()函数的实例用法
2017/03/30 Python
Python创建对称矩阵的方法示例【基于numpy模块】
2017/10/12 Python
总结python中pass的作用
2019/02/27 Python
使用Python的networkx绘制精美网络图教程
2019/11/21 Python
Python定时器线程池原理详解
2020/02/26 Python
PyInstaller运行原理及常用操作详解
2020/06/13 Python
Python 使用office365邮箱的示例
2020/10/29 Python
Django权限控制的使用
2021/01/07 Python
森海塞尔美国官网:Sennheiser耳机与耳麦
2017/07/19 全球购物
澳大利亚美容产品及化妆品在线:Activeskin
2020/06/03 全球购物
2014年语文教师工作总结
2014/12/18 职场文书
四年级学生期末评语
2014/12/26 职场文书
2016中秋节晚会开场白
2015/11/26 职场文书
写作之关于描写老人的好段摘抄
2019/11/14 职场文书
使用Pytorch训练two-head网络的操作
2021/05/28 Python
CentOS8.4安装Redis6.2.6的详细过程
2021/11/20 Redis
不同品牌、不同型号对讲机如何互相通联
2022/02/18 无线电
Vue如何清空对象
2022/03/03 Vue.js