PHP之PDO介绍

PDO为何物?

POD(PHP Data Object)扩展在PHP5中加入,PHP6中将默认识用PDO连接数据库,所有非PDO扩展将会在PHP6被从扩展中移除。该扩展提供PHP内置类 PDO来对数据库进行访问,不同数据库使用相同的方法名,解决数据库连接不统一的问题。
我是配置在windows下做开发用的。
■PDO的目标

  • 提供一种轻型、清晰、方便的 API
  • 统一各种不同 RDBMS 库的共有特性,但不排除更高级的特性。
  • 通过 PHP 脚本提供可选的较大程度的抽象/兼容性。

■PDO的特点:

  • 性能。PDO 从一开始就吸取了现有数据库扩展成功和失败的经验教训。因为 PDO 的代码是全新的,所以我们有机会重新开始设计性能,以利用 PHP 5 的最新特性。
  • 能力。PDO 旨在将常见的数据库功能作为基础提供,同时提供对于 RDBMS 独特功能的方便访问。
  • 简单。PDO 旨在使您能够轻松使用数据库。API 不会强行介入您的代码,同时会清楚地表明每个函数调用的过程。
  • 运行时可扩展。PDO 扩展是模块化的,使您能够在运行时为您的数据库后端加载驱动程序,而不必重新编译或重新安装整个 PHP 程序。例如,PDO_OCI 扩展会替代 PDO 扩展实现 Oracle 数据库 API。还有一些用于 MySQL、PostgreSQL、ODBC 和 Firebird 的驱动程序,更多的驱动程序尚在开发。
    ■安装PDO 我这里是WINDOWS下开发用的PDO扩展,要是你要在Linux下安装配置,请到别的地方寻找。 版本要求:
    php5.1以及以后版本的程序包里已经带了;
    php5.0.x则要到pecl.php.net下载,放到你的扩展库,就是PHP所在的文件夹的ext文件夹下;
    手册上说5.0之前的版本不能运行PDO扩展。
     
    配置: 修改你的php.ini配置文件,使它支持pdo.(php.ini这个东西没有弄懂的话,先弄清楚,要修改调用你的phpinfo()函数所显示的那个php.ini)
    extension=php_pdo.dll前面的分号去掉,分毫是php配置文件注释符号,这个扩展是必须的。
    往下还有 ;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
    各各扩展所对应的数据库是:

    Driver name Supported databases
    PDO_DBLIB FreeTDS / Microsoft SQL Server / Sybase
    PDO_FIREBIRD Firebird/Interbase 6
    PDO_INFORMIX IBM Informix Dynamic Server
    PDO_MYSQL MySQL 3.x/4.x
    PDO_OCI Oracle Call Interface
    PDO_ODBC ODBC v3 (IBM DB2, unixODBC and win32 ODBC)
    PDO_PGSQL PostgreSQL
    PDO_SQLITE SQLite 3 and SQLite 2
    你要使用哪种数据库,只要把相应的扩展前的注释符号";"去掉就可以了。
    使用PDO 我这里假设你已经装好mysql了,要是没装的话,麻烦先想办法装上,我的是mysql5.0.22,黑夜路人用的是MySQL 4.0.26也可以用。

    数据库的连接: 我们通过下面的例子来分析PDO连接数据库,

    <?php $dbms='mysql';    //数据库类型 Oracle 用ODI,对于开发者来说,使用不同的数据库,只要改这个,不用记住那么多的函数了 $host='localhost';//数据库主机名 $dbName='test';   //使用的数据库 $user='root';     //数据库连接用户名 $pass='';         //对应的密码 $dsn="$dbms:host=$host;dbname=$dbName"; // try{     $dbh=newPDO($dsn,$user,$pass);//初始化一个PDO对象,就是创建了数据库连接对象$dbh     echo "连接成功<br/>";     /*你还可以进行一次搜索操作

       foreach($dbh->query('SELECT * from FOO')as$row){         print_r($row);//你可以用 echo($GLOBAL); 来看到这些值     }    */     $dbh=null; }catch(PDOException$e){     die("Error!: ".$e->getMessage()."<br/>"); } //默认这个不是长连接,如果需要数据库长连接,需要最后加一个参数:array(PDO::ATTR_PERSISTENT => true) 变成这样: $db=newPDO($dsn,$user,$pass,array(PDO::ATTR_PERSISTENT=>true));
    ?>

    数据库查询: 上面我们已经进行了一次查询,我们还可以使用如下的查询:

    <?php $db->setAttribute(PDO::ATTR_CASE,PDO::CASE_UPPER); //设置属性 $rs=$db->query("SELECT * FROM foo"); $rs->setFetchMode(PDO::FETCH_ASSOC); $result_arr=$rs->fetchAll(); print_r($result_arr); ?>

    以上因为用到setAttribute()方法,放上那两个参数,把字段名强制转换成大写。下面列出多有PDO::setAttribute()的参数:

    • PDO::ATTR_CASE: 强制列名变成一种格式,详细如下(第二个参数):

      • PDO::CASE_LOWER: 强制列名是小写.

      • PDO::CASE_NATURAL: 列名按照原始的方式

      • PDO::CASE_UPPER: 强制列名为大写.

    • PDO::ATTR_ERRMODE: 错误提示.

      • PDO::ERRMODE_SILENT: 不显示错误信息,只显示错误码.

      • PDO::ERRMODE_WARNING: 显示警告错误.

      • PDO::ERRMODE_EXCEPTION: 抛出异常.

    • PDO::ATTR_ORACLE_NULLS(不仅仅是ORACLE有效,别的数据库也有效): )指定数据库返回的NULL值在php中对应的数值。

      • PDO::NULL_NATURAL: 不变.

      • PDO::NULL_EMPTY_STRING: Empty string is converted toNULL.

      • PDO::NULL_TO_STRING: NULL is converted to an empty string.

    • PDO::ATTR_STRINGIFY_FETCHES: Convert numeric values to strings when fetching. Requiresbool.

    • PDO::ATTR_STATEMENT_CLASS: Set user-supplied statement class derived from PDOStatement. Cannot be used with persistent PDO instances. Requiresarray(string classname, array(mixed constructor_args)).

    • PDO::ATTR_AUTOCOMMIT(available in OCI, Firebird and MySQL): Whether to autocommit every single statement.

    • PDO::MYSQL_ATTR_USE_BUFFERED_QUERY(available in MySQL): Use buffered queries.

    例子中的$rs->setFetchMode(PDO::FETCH_ASSOC);是PDOStatement::setFetchMode(),对返回类型的声明。 有如下: PDO::FETCH_ASSOC-- 关联数组形式 PDO::FETCH_NUM   -- 数字索引数组形式 PDO::FETCH_BOTH  -- 两者数组形式都有,这是缺省的 PDO::FETCH_OBJ  -- 按照对象的形式,类似于以前的 mysql_fetch_object()
    更多返回类型声明(PDOStatement::方法名)看手册。
    ★插入,更新,删除数据,

    $db->exec("DELETE FROM `xxxx_menu` where mid=43");

  • 简单的总结一下上面的操作:

    查询操作主要是PDO::query()、PDO::exec()、PDO::prepare()。 PDO::query()主要是用于有记录结果返回的操作,特别是SELECT操作, PDO::exec()主要是针对没有结果集合返回的操作,比如INSERT、UPDATE、DELETE等操作,它返回的结果是当前操作影响的列数。 PDO::prepare()主要是预处理操作,需要通过$rs->execute()来执行预处理里面的SQL语句,这个方法可以绑定参数,功能比较强大,不是本文能够简单说明白的,大家可以参考手册和其他文档。

    获取结果集操作主要是:PDOStatement::fetchColumn()、PDOStatement::fetch()、PDOStatement::fetchALL()。 PDOStatement::fetchColumn()是获取结果指定第一条记录的某个字段,缺省是第一个字段。 PDOStatement::fetch()是用来获取一条记录, PDOStatement::fetchAll()是获取所有记录集到一个中,获取结果可以通过PDOStatement::setFetchMode来设置需要结果集合的类型。

    另外有两个周边的操作,一个是PDO::lastInsertId()和PDOStatement::rowCount()。PDO::lastInsertId()是返回上次插入操作,主键列类型是自增的最后的自增ID。 PDOStatement::rowCount()主要是用于PDO::query()和PDO::prepare()进行DELETE、INSERT、UPDATE操作影响的结果集,对PDO::exec()方法和SELECT操作无效。

    事务和自动提交
        至此,您已经通过 PDO 连接到了 mysql,在发出查询之前,您应该理解 PDO 是如何管理事务的。如果之前没有接触过事务,那么首先要知道事务的 4 个特征:原子性(Atomicity)、一致性(Consistency)、独立性(Isolation)和持久性(Durability),即 ACID。用外行人的话说,对于在一个事务中执行的任何工作,即使它是分阶段执行的,也一定可以保证该工作会安全地应用于数据库,并且在工作被提交时,不会受到来自其他连接的影响。事务性工作可以根据请求自动撤销(假设您还没有提交它),这使得脚本中的错误处理变得更加容易。     事务通常是通过把一批更改积蓄起来、使之同时生效而实现的。这样做的好处是可以大大提高这些更新的效率。换句话说,事务可以使脚本更快,而且可能更健壮(不过需要正确地使用事务才能获得这样的好处)。     不幸的是,并不是每种数据库都支持事务(Mysql5支持事务,mysql4我不知道),所以当第一次打开连接时,PDO 需要在所谓的“自动提交(auto-commit)”模式下运行。自动提交模式意味着,如果数据库支持事务,那么您所运行的每一个查询都有它自己的隐式事务,如果数据库不支持事务,每个查询就没有这样的事务。如果您需要一个事务,那么必须使用 PDO::beginTransaction() 方法来启动一个事务。如果底层驱动程序不支持事务,那么将会抛出一个 PDOException(无论错误处理设置是怎样的:这总是一个严重错误状态)。在一个事务中,可以使用 PDO::commit() 或 PDO::rollBack() 来结束该事务,这取决于事务中运行的代码是否成功。     当脚本结束时,或者当一个连接即将被关闭时,如果有一个未完成的事务,那么 PDO 将自动回滚该事务。这是一种安全措施,有助于避免在脚本非正常结束时出现不一致的情况 —— 如果没有显式地提交事务,那么假设有某个地方会出现不一致,所以要执行回滚,以保证数据的安全性。

    //例子来自http://www.ibm.com/developerworks/cn/db2/library/techarticles/dm-0505furlong/index.html try{   $dbh=new PDO('odbc:SAMPLE','db2inst1','ibmdb2',       array(PDO_ATTR_PERSISTENT=>true));   echo"Connected\n";   $dbh->setAttribute(PDO_ATTR_ERRMODE,PDO_ERRMODE_EXCEPTION);   $dbh->beginTransaction();   $dbh->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')");   $dbh->exec("insert into salarychange (id, amount, changedate)       values (23, 50000, NOW())");   $dbh->commit();    }catch(Exception $e){   $dbh->rollBack();   echo"Failed: ".$e->getMessage(); }

    在上面的示例中,假设我们为一个新雇员创建一组条目,这个雇员有一个 ID 号,即 23。除了输入这个人的基本数据外,我们还需要记录雇员的薪水。两个更新分别完成起来很简单,但通过将这两个更新包括在 beginTransaction() 和 commit() 调用中,就可以保证在更改完成之前,其他人无法看到更改。如果发生了错误,catch 块可以回滚事务开始以来发生的所有更改,并打印出一条错误消息。

    并不是一定要在事务中作出更新。您也可以发出复杂的查询来提取数据,还可以使用那种信息构建更多的更新和查询。当事务在活动时,可以保证其他人在工作进行当中无法作出更改。事实上,这不是 100% 的正确,但如果您之前没有听说过事务的话,这样介绍也未尝不可。

    预处理语句和存储过程

    很多更成熟的数据库都支持预处理语句的概念。什么是预处理语句?您可以把预处理语句看作您想要运行的 SQL 的一种编译过的模板,它可以使用变量参数进行定制。预处理语句可以带来两大好处:

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

    预处理语句是如此有用,以致 PDO 实际上打破了在目标 4 中设下的规则:如果驱动程序不支持预处理语句,那么 PDO 将仿真预处理语句。
    实例:PDO的应用例子:

    <?php $dbms='mysql';//数据库类型 Oracle 用ODI,对于开发者来说,使用不同的数据库,只要改这个,不用记住那么多的函数了 $host='localhost';//数据库主机名 $dbName='test';//使用的数据库 $user='root';//数据库连接用户名 $pass='';//对应的密码 $dsn="$dbms:host=$host;dbname=$dbName";
    classdbextendsPDO{     publicfunction__construct(){         try{             parent::__construct("$GLOBALS[dsn]",$GLOBALS['user'],$GLOBALS['pass']);         }catch(PDOException$e){         die("Error: ".$e->__toString()."<br/>");         }     }          publicfinalfunctionquery($sql){         try{             returnparent::query($this->setString($sql));         }catch(PDOException$e){             die("Error: ".$e->__toString()."<br/>");         }     }          privatefinalfunctionsetString($sql){         echo"我要处理一下$sql";         return$sql;     } }
    $db=newdb(); $db->setAttribute(PDO::ATTR_CASE,PDO::CASE_UPPER); foreach($db->query('SELECT * from xxxx_menu')as$row){     print_r($row); } $db->exec('DELETE FROM  `xxxx_menu` where mid=43'); ?>

PHP之PDO的更多相关文章

  1. 比Mysqli操作数据库更简便的方式 。PDO

    下面来说一下PDO 先画一张图来了解一下 mysqli是针对mysql这个数据库扩展的一个类 PDO是为了能访问更多数据库 如果出现程序需要访问其他数据库的话就可以用PDO来做 PDO数据访问抽象层1 ...

  2. pdo的使用

    PHP 数据对象 (PDO) 扩展为PHP访问数据库定义了一个轻量级的一致接口. PDO 提供了一个数据访问抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数(方法)来查询和获取数据. PDO随 ...

  3. PHP中PDO事务的使用方法

    事务 (Transaction) 是操作数据库中很重要的一个功能, 它可以让你预定一条, 或者一系列 SQL 语句, 然后一起执行. 在执行的过程中, 如果其中的某条执行失败, 可以回滚所有已更改的操 ...

  4. PDO连接mysql数据库

    1.PDO简介 PDO(PHP Data Object) 是PHP 5 中加入的东西,是PHP 5新加入的一个重大功能,因为在PHP 5以前的php4/php3都是一堆的数据库扩展来跟各个数据库的连接 ...

  5. PDO概念 分析 练习

    PDO 翻译过来叫做数据访问抽象层 它是一个数据访问的层面,实际上是一个类,也就是说所有操作数据库的代码,都是通过这个层面完成的 该图好理解大概就是这样一种模式 现在考虑的是能不能使用同一个类,上层代 ...

  6. PDO

    'PDO'是数据访问抽象层'用mysqli类找到mysqli驱动根据驱动操作mysqli数据库'其他类找到sqlserver驱动根据驱动操作sqlserve数据库'PDO 访问其他数据库 PDO的用法 ...

  7. 前端学PHP之PDO预处理语句

    × 目录 [1]定义 [2]准备语句 [3]绑定参数[4]执行查询[5]获取数据[6]大数据对象 前面的话 本来要把预处理语句和前面的基础操作写成一篇的.但是,由于博客园的限制,可能是因为长度超出,保 ...

  8. 前端学PHP之PDO基础操作

    × 目录 [1]创建PDO [2]使用PDO [3]事务处理 前面的话 PDO(php data object)扩展类库为php访问数据库定义了轻量级的.一致性的接口,它提供了一个数据库访问抽象层,这 ...

  9. CANopen学习——PDO

    查找资料时,发现一个很好的博客,博主剖析的通俗易懂 http://www.cnblogs.com/winshton/p/4897556.html   PDO定义: 过程数据对象,用来传输实时数据.因为 ...

  10. PHP基础之PDO

    简介 PDO(PHP Data Object)是指PHP数据对象,它定义了一个轻量级的一致接口来统一操作各种数据库.PDO提供了一个数据访问抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数(方 ...

随机推荐

  1. TP5 模型事务操作

    注意:数据只要涉及多表一致性操作,必须要开启数据库事务操作 ThinkPHP5 中模型层中使用事务: try{ $this->startTrans(); $this->data($orde ...

  2. BBS-基于用户认证组建和Ajax实现登陆验证

    功能1: 基于用户认证组件和Ajax实现登录验证(图片验证码) 总结: 1 一次请求伴随多次请求 2 PIL 3 session存储 4 验证码刷新 步骤: 1.配置静态文件夹 settings.py ...

  3. js判断网页是否加载完毕

    1. document.onreadystatechange = function () { if(document.readyState=="complete") { docum ...

  4. python反汇编函数字节码

    使用dis模块 >>> def test(): ... print(1) ... a = 1 ... print(a) ... >>> from dis impor ...

  5. vue:绑定数据的vue页面加载会闪烁问题

    1:在挂在数据的容器加上属性 v-cloak 2:在css中添加如下代码 但有时候还是会不起作用,可能原因有两个 2.1:display属性被更高权限的display属性覆盖了,我们增加权限就好了 2 ...

  6. C++17尝鲜:变长 using 声明

    using 声明 先来看 using 声明在类中的应用: 代码1 #include <iostream> using namespace std; struct A { void f(in ...

  7. walle自动部署增量上线

    walle的部署大家都会,全量上线也会,今天突然想用下增量上线,试了好多次都不行,咨询了开发的同事终于明白了,特写个笔记省的忘了 如上图我们网站根目录为/data/ifengsite/htdocs/x ...

  8. Android 深入浅出 - Android系统启动过程

    Activity的类继承关系及跟踪Activity的启动 Android系统启动过程 https://study.163.com/course/courseLearn.htm?courseId=213 ...

  9. 混合app开发,h5页面调用ios原生APP的接口

    混合APP开发中,前端开发H5页面,不免会把兼容性拉进来,在做页面的兼容性同事,会与原生app产生一些数据交互: 混合APP开发,安卓的兼容性倒是好说,安卓使用是chrome浏览器核心,已经很好兼容H ...

  10. 【转】Classful IPv4 addressing definition

    Classful addressing definition Class Leadingbits Size of networknumber bit field Size of restbit fie ...