文章详情

短信预约信息系统项目管理师 报名、考试、查分时间动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

php中值得收藏的PDO对象安装配置与使用

2016-03-15 22:10

关注
extension=php_pdo.dll
extension=php_pdo_firebird.dll
extension=php_pdo_informix.dll
extension=php_pdo_mssql.dll
extension=php_pdo_mysql.dll
extension=php_pdo_oci.dll
extension=php_pdo_oci8.dll
extension=php_pdo_odbc.dll
extension=php_pdo_pgsql.dll
extension=php_pdo_sqlite.dll

1.3 PDO类

1.3.1 PDO::__construct

PDO::__construct — 创建一个表示数据库连接的 PDO 实例

PDO::__construct ( string $dsn , string $username = ? , string $password = ? , array $driver_options = ? )
<?php$dsn = 'mysql:host=localhost;dbname=pxscj';$user = 'user';$password = '123456';try {
    $dbh = new PDO($dsn, $user, $password);} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();}?>

1.3.2 PDO::exec

PDO::exec — 执行一条 SQL 语句,并返回受影响的行数

PDO::exec ( string $statement ) : int
<?php$db=new PDO("mysql:host=localhost;dbname=PXSCJ","user","123456");$delete_sql="delete from userinfo where username='user1'";    //注销自己的SQL语句$affected=$db->exec($delete_sql);              //执行没有返回的sql语句$delete_sqlif($affected)                                  //如果受影响记录数不为0
    echo "注销用户成功!";else
    echo "注销用户失败!";?>

1.3.3 PDO::query

PDO::query — 执行 SQL 语句,以 PDOStatement 对象形式返回结果集

public PDO::query ( string $statement ) : PDOStatement
<?php$db=new PDO("mysql:host=localhost;dbname=pxscj","user","123456");$query="select * from kcb";                 //SQL语句foreach($db->query($query) as $row) {       //执行SQL语句$query--执行有结果集的SQL语句
    echo "课程号:".$row[0]."<br>";          //返回的是一个PDOStatement类(型)的对象
    echo "课程名:".$row[1]."<br>";          //还可以用PDOStatement类的方法fetch()行读
    echo "开课日期:".$row[2]."<br>"; 
    echo "学时:".$row[3]."<br><br>";}?>

1.3.4 PDO::prepare

PDO::prepare — 准备要执行的语句,并返回语句对象

public PDO::prepare ( string $statement , array $driver_options = array() ) : PDOStatement

为PDOStatement::execute() 方法准备待执行的 SQL 语句。 SQL 语句可以包含零个或多个参数占位标记,格式是命名(:name)或问号(?)的形式,当它执行时将用真实数据取代。 在同一个 SQL 语句里,命名形式和问号形式不能同时使用;只能选择其中一种参数形式。 注:用参数形式绑定用户输入的数据,不要直接字符串拼接到查询里,防SQL注入

$db=new PDO("mysql:host=localhost;dbname=pxscj","user","123456");$in_sql="insert into userinfo(username,password,sex,age,email) values(?,?,?,?,?)";  $in_result=$db->prepare($in_sql);                                                   //预处理SQL语句$in_sql$userid="php3"; $pwd1="111111"; $sex=0; $age=36; $email="php3@qq.com";$in_result->bindParam(1, $userid);   //PDOStatement的bindParam()的作用是绑定参数给execute()$in_result->bindParam(2, $pwd1);    //SQL语句使用问号参数时--bindParam()第一个参数是问号索引偏移(第几个)$in_result->bindParam(3, $sex);     //bindParam()第二个参数是赋值给SQL语句参数(问号)的变量$in_result->bindParam(4, $age);          $in_result->bindParam(5, $email);$in_result->execute();             //执行经过预处理的SQL语句$in_resultif($in_result->rowCount()==0)     //用PDOStatement的rowCount()返回结果集行的总数
    echo "插入记录失败!";else
    echo "插入记录成功!";

1.3.5 PDO::beginTransaction

PDO::beginTransaction — 启动一个事务

PDO::beginTransaction():bool

1.3.6 PDO::rollBack

PDO::rollBack — 回滚一个事务

PDO::rollBack():bool

回滚由 PDO::beginTransaction() 发起的当前事务。如果没有事务激活,将抛出一个 PDOException 异常。
如果数据库被设置成自动提交模式,此函数(方法)在回滚事务之后将恢复自动提交模式。

<?php$dbh->beginTransaction();$sth = $dbh->exec("DROP TABLE fruit");$sth = $dbh->exec("UPDATE dessert
    SET name = 'hamburger'");$dbh->rollBack();?>

1.3.7 内部函数说明

PDO::beginTransaction — 启动一个事务
PDO::commit — 提交一个事务
PDO::__construct — 创建一个表示数据库连接的 PDO 实例
PDO::errorCode — 获取跟数据库句柄上一次操作相关的 SQLSTATE
PDO::errorInfo — Fetch extended error information associated with the last operation on the database handle
PDO::exec — 执行一条 SQL 语句,并返回受影响的行数
PDO::getAttribute — 取回一个数据库连接的属性
PDO::getAvailableDrivers — 返回一个可用驱动的数组
PDO::inTransaction — 检查是否在一个事务内
PDO::lastInsertId — 返回最后插入行的ID或序列值
PDO::prepare — 准备要执行的语句,并返回语句对象
PDO::query — 执行 SQL 语句,以 PDOStatement 对象形式返回结果集
PDO::quote — 为 SQL 查询里的字符串添加引号
PDO::rollBack — 回滚一个事务
PDO::setAttribute — 设置属性

1.4 PDOStatement类

1.4.1 PDOStatement::bindParam

PDOStatement::bindParam — 绑定一个参数到指定的变量名

PDOStatement::bindParam ( mixed $parameter , mixed &$variable , int $data_type = PDO::PARAM_STR , int $length = ? , mixed $driver_options = ? ):bool

绑定一个PHP变量到用作预处理的SQL语句中的对应命名占位符或问号占位符。 不同于 PDOStatement::bindValue() ,此变量作为引用被绑定,并只在 PDOStatement::execute() 被调用的时候才取其值。

<?php$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();?>

1.4.2 PDOStatement::execute

PDOStatement::bindParam — 绑定一个参数到指定的变量名

PDOStatement::execute ( array $input_parameters = ? ) : bool

执行预处理过的语句。如果预处理过的语句含有参数标记,必须选择下面其中一种做法:

1)调用 PDOStatement::bindParam() 绑定 PHP 变量到参数标记:如果有的话,通过关联参数标记绑定的变量来传递输入值和取得输出值
2)或传递一个只作为输入参数值的数组

<?php$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));?>

1.4.3 PDOStatement::fetch

PDOStatement::fetch — 从结果集中获取下一行

PDOStatement::fetch ( int $fetch_style = ? , int $cursor_orientation = PDO::FETCH_ORI_NEXT , int $cursor_offset = 0 ):mixed

从一个 PDOStatement 对象相关的结果集中获取下一行。fetch_style 参数决定 POD 如何返回行。

PDO::FETCH_ASSOC:返回一个索引为结果集列名的数组
PDO::FETCH_BOTH(默认):返回一个索引为结果集列名和以0开始的列号的数组
PDO::FETCH_BOUND:返回 true ,并分配结果集中的列值给 PDOStatement::bindColumn() 方法绑定的 PHP 变量。
PDO::FETCH_CLASS:返回一个请求类的新实例,映射结果集中的列名到类中对应的属性名。如果 fetch_style 包含 PDO::FETCH_CLASSTYPE(例如:PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE),则类名由第一列的值决定
PDO::FETCH_INTO:更新一个被请求类已存在的实例,映射结果集中的列到类中命名的属性
PDO::FETCH_LAZY:结合使用 PDO::FETCH_BOTH 和 PDO::FETCH_OBJ,创建供用来访问的对象变量名
PDO::FETCH_NUM:返回一个索引为以0开始的结果集列号的数组
PDO::FETCH_OBJ:返回一个属性名对应结果集列名的匿名对象
<?php$sth = $dbh->prepare("SELECT name, colour FROM fruit");$sth->execute();print("PDO::FETCH_ASSOC: ");print("Return next row as an array indexed by column name\n");$result = $sth->fetch(PDO::FETCH_ASSOC);print_r($result);print("\n");?>

1.4.4 PDOStatement::execute

PDOStatement::fetchAll — 返回一个包含结果集中所有行的数组

PDOStatement::fetchAll ( int $fetch_style = ? , mixed $fetch_argument = ? , array $ctor_args = array() ):array
<?php$sth = $dbh->prepare("SELECT name, colour FROM fruit");$sth->execute();print("Fetch all of the remaining rows in the result set:\n");$result = $sth->fetchAll();print_r($result);?>

1.4.5 PDOStatement::rowCount

PDOStatement::rowCount — 返回受上一个 SQL 语句影响的行数

PDOStatement::rowCount():int

PDOStatement::rowCount() 返回上一个由对应的 PDOStatement 对象执行DELETE、 INSERT、或 UPDATE 语句受影响的行数。
如果上一条由相关 PDOStatement 执行的 SQL 语句是一条 SELECT 语句,有些数据可能返回由此语句返回的行数。但这种方式不能保证对所有数据有效,且对于可移植的应用不应依赖于此方式。

<?php$del = $dbh->prepare('DELETE FROM fruit');$del->execute();print("Return number of rows that were deleted:\n");$count = $del->rowCount();print("Deleted $count rows.\n");?>

1.4.6 内部函数说明

PDOStatement::bindColumn — 绑定一列到一个 PHP 变量
PDOStatement::bindParam — 绑定一个参数到指定的变量名
PDOStatement::bindValue — 把一个值绑定到一个参数
PDOStatement::closeCursor — 关闭游标,使语句能再次被执行。
PDOStatement::columnCount — 返回结果集中的列数
PDOStatement::debugDumpParams — 打印一条 SQL 预处理命令
PDOStatement::errorCode — 获取跟上一次语句句柄操作相关的 SQLSTATE
PDOStatement::errorInfo — 获取跟上一次语句句柄操作相关的扩展错误信息
PDOStatement::execute — 执行一条预处理语句
PDOStatement::fetch — 从结果集中获取下一行
PDOStatement::fetchAll — 返回一个包含结果集中所有行的数组
PDOStatement::fetchColumn — 从结果集中的下一行返回单独的一列。
PDOStatement::fetchObject — 获取下一行并作为一个对象返回。
PDOStatement::getAttribute — 检索一个语句属性
PDOStatement::getColumnMeta — 返回结果集中一列的元数据
PDOStatement::nextRowset — 在一个多行集语句句柄中推进到下一个行集
PDOStatement::rowCount — 返回受上一个 SQL 语句影响的行数
PDOStatement::setAttribute — 设置一个语句属性
PDOStatement::setFetchMode — 为语句设置默认的获取模式。

1.5 用法及小结

以上PDO类及PDOStatement类的说明摘录自php开发手册,详细描述只摘录了常用的几个内部函数。实话实说对于一个程序员最好的提升技术的方法之一就是看文档,通过查阅文档可以解决我们在开发中遇到的许多问题,而且通过文档我们可以知道很多api使用的细节和注意点,帮助我们规避很多错误。总而言之遇到问题看文档,多百度,多看博客,多总结,这才是长久的学习之道。
多说不做也是不行的,练习才是技术提升的必由之路,练习实践才可以在其中发现问题,提升自己,下面代码是我对PDO的一些常见用法的整理:

try {	
    $db=new PDO("mysql:host=localhost;dbname=pxscj","user","123456"); }catch (PDOException $e) {       
    echo "数据库连接失败:".$e->getMessage(); }$db->exec("set names utf-8");  //插入                             $query="insert into kcb values('606','PHP程序设计',6,48,3)";   if($affCount=$db->exec($query)) {                           
    echo "插入成功,受影响条数为:".$affCount."<br><br>";                }//查询$query="select * from kcb";                                 foreach($db->query($query) as $row) {        
    echo "课程号:".$row[0]."<br>";   
    echo "课程名:".$row[1]."<br>";  
    echo "开课日期:".$row[2]."<br>"; 
    echo "学时:".$row[3]."<br><br>";}//事务处理try {   
    $db->exec("set names utf-8");                           
    $db->beginTransaction();                                 
    $affrows=$db->exec("insert into kcb values('506','UML系统分析',5,48,3)");    
    if(!$affrows)
        throw new PDOException("插入失败1");
    $affrows=$db->exec("insert into kcb values('606','PHP程序设计',6,32,2)");  
    if(!$affrows)
        throw new PDOException("插入失败2");
    echo "插入成功!"; 
    $db->commit();                                         }catch (PDOException $e) {                                   
    echo $e->getMessage(); 
    $db->rollBack();   //回滚(要么成功要么失败)}//prepare 可以防sql注入$in_sql="insert into userinfo(username,password,sex,age,email) values(?,?,?,?,?)"; $in_result=$db->prepare($in_sql); $userid="php3"; $pwd1="111111"; $sex=0; $age=36; $email="php3@qq.com";$in_result->bindParam(1, $userid); $in_result->bindParam(2, $pwd1);         $in_result->bindParam(3, $sex);       $in_result->bindParam(4, $age);       $in_result->bindParam(5, $email);$in_result->execute();    if($in_result->rowCount()==0)       
    echo "插入记录失败!";else
    echo "插入记录成功!";//更新 改密码$oldpwd=$_POST['oldpwd'];				                           //原密码$newpwd=$_POST['newpwd'];				                           //新密码$s_sql="select * from userinfo where username='$username'";                   //SQL语句$s_result=$db->query($s_sql);                                                list($username,$password,$sex,$age,$email)=$s_result->fetch(PDO::FETCH_NUM);if($password!=$oldpwd)					                   //判断原密码是否正确
    echo "原密码错误!";else {
    $checkpwd=preg_match('/^\w{6,20}$/',$newpwd);if(!$checkpwd)
    echo "新密码格式不满足要求!";else {
    $update_sql="update userinfo set password='$newpwd' where username='$username'";  
    $affected=$db->exec($update_sql); 
    if($affected)
        echo"密码修改成功!";
    else
        echo "密码修改失败!";
    }}//删除 注销session_start();$username=@$_SESSION['userid'];$delete_sql="delete from userinfo where username='$username'";    //注销自己的SQL语句$affected=$db->exec($delete_sql);                                if($affected)             
    echo "注销用户成功!";else
    echo "注销用户失败!";

1.6 PDO与JPA闲谈

软件开发框架总是有很多互通的地方,因为无论任何开发语言,java或者php底层实现都离不开数据结构,算法,还有软件设计模式,而这些都是互通的,而好的软件框架离不开设计模式运用.
自从学习php接触了解到PDO对象扩展时我便联想到我曾使用的springboot JPA持久层框架,于是我查了些资料,以下便是我的个人理解:
首先先解释一下PDO和JPA的概念

PHP 数据对象(PHP Data Objects) 扩展为PHP访问数据库定义了一个轻量级的一致接口。
PDO 提供了一个 数据访问 抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数(方法)来查询和获取数据。PDO 不提供 数据库 抽象层;它不会重写 SQL,也不会模拟缺失的特性。如果需要的话,应该使用一个成熟的抽象层。

JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
JPA仅仅是一种规范,也就是说JPA仅仅定义了一些接口,而接口是需要实现才能工作的。所以底层需要某种实现,而Hibernate就是实现了JPA接口的ORM框架。

在这里插入图片描述

从上述概念和架构图可以看出PDO和JPA还是有一定区别的。首先PHP的PDO只是一个抽象的数据访问接口层,它对数据库的访问还要依赖相应的数据库驱动,而且需要自行编写操作数据的SQL语句。
而java的JPA则是一个持久层规范,也就是说JPA仅仅定义了一些接口,这些接口是关于类和数据库表的映射的,也就是说,JPA这个规范在数据访问接口层之上,而真正实现这个规范和底层数据访问接口是在如Hibernate的这些数据持久层框架内.
以Hibernate这个持久层框架为例,它实现了对象和数据库表的映射关系,仅需要操作相应的访问DAO层接口即可实现数据库的查询并转换为java对象内部属性数据。而Hibernate底层对数据库的访问还得依赖JDBC接口。
由此可见PDO和JPA规范完全处于两个不同层次,JPA是数据访问方法底层的高层次抽象,而PDO仅相当于java的JDBC接口层。PDO的抽象层次相对较低,这也符合PHP的轻量级web开发语言
的特点,这也是它的一个优点,可以方便清晰地实现一些复杂的数据库访问操作,但不利于复杂的高抽象度的大型项目的开发.
以上内容为个人对PHP PDO对象和java JPA规范的一些理解和比较,水平有限,可能会有不准确的地方。

1.7 实验问题与总结

1.7.1 mysql连接

php使用mysql原生密码连接如

$conn=mysqli_connect('localhost','user','123456')or die('连接失败');

会出现错误:The server requested authentication method unknown to the client.
原因:
由于本地使用mysql版本在8.0以上,而mysql 8升级了密码的验证方式 caching_sha2_password,所以原生连接会失败,解决办法使用sql修改用户登录验证方式:

use mysql;ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';

1.7.2 sql注入总结

php使用mysqli或pdo的query方法查询时,如未对用户表单输入数据进行处理可能会存在SQL注入隐患,如

$username=$_POST['username'];$password=$_POST['password']; //magic_quotes_gpc设为off的情况下//mysql$conn = mysqli_connect("localhost", "user" ,"123456") or die('连接失败'); //mysql_connect()链接MySQL服务器mysqli_select_db($conn,'PXSCJ') or die('选择数据库失败'); //mysql_select_db()选择数据库mysqli_query($conn,"SET NAMES utf-8");//设置字符集为utf-8$str="select * from userinfo where username='$username' and password='$password'";$result=mysqli_query($conn,$str); //PDO//连接数据库,新建PDO对象$pdo=new PDO("mysql:host=localhost;dbname=pxscj","user","123456");$str="select * from userinfo where username='$username' and password='$password'";$result=$pdo->query($str);

当用户输入username值为user,password值为123 ' or 1=1,即查询sql被转义为:

select * from userinfo where username='user' and password='123 ' or ' 1=1'

则用户将跳过密码的查询验证得到所有userinfo的数据,并且还存在其他SQL语句越权执行的风险
处理风险的方法有以下几种:

$password=addslashes($password);

addslashes() 函数返回在预定义字符之前添加反斜杠的字符串。预定义字符是:
单引号(')
双引号(")
反斜杠(\)
NULL

$sql="select * from userinfo where username='$username' and password='$password'";//注意不是中文状态下的问号? $result=$pdo->prepare($sql); //按照?的顺序绑定参数值 $result->bindParam(1,$username); $result->bindParam(2,$password); $result->execute();

大家如果感兴趣的话,可以点击《PHP视频教程》进行更多关于PHP知识的学习。

以上就是php中值得收藏的PDO对象安装配置与使用的详细内容,更多请关注编程界其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯