将心比心,方得人心~

php数据库连接-PDO

周洲 2017-04-06 20:49:16

虽然所有主流数据库都遵循 SQL 标准,但程序员用来与数据库交互的接口却有很多不同。因此,应用程序几乎总是绑定与某个数据库,要求用户要么安装和维护所需的数据库, 要么选择一个与当前环境兼容,而不可以随便选择一款你想要的数据库。 

比如,你使用不同的数据库,就必须使用不同的数据库扩展。MYSQL 有 mysql、mysqli 等,MSSQL 有 mssql,ORACLE 有 oracle 扩展,db2 有 db2 等。每个数据库都有自己的数 据库操作写法,如果一个系统已经采用了 MYSQL 数据库,突然要变更为 ORACLE,那么 数据库操作部分,就必须全部重写。 

为了解决这个难题,企业程序员开始开发数据库抽象层,它能够解除应用程序逻辑与数 据库通信逻辑之间的耦合。通过这个通用接口传递所有与数据库相关的命令,应用程序就可 以使用多种数据库解决方案中的某一种了。

一.PDO 介绍 

PDO 扩展为 PHP 访问数据库定义了一个轻量级的、一致性的接口,它提供了一个数据 访问抽象层,这样,无论使用什么数据库,都可以通过一致的函数执行查询和获取数据。 PDO 随 PHP5.1 发行,在 PHP5.0 的 PECL 扩展中也可以使用。

开启 PDO,如果是按照 Appserv 集成环境来开发的。系统会自动开启 PDO,我们可以 phpinfo 去查看一下。 

extension=php_pdo.dll //开启 PDO 
extension=php_pdo_mysql.dll //PDO 访问 mysql 驱动

PDO 给开发者提供了三组类:PDO、PDOStatement、PDOException;分别为:数据库 使用、预处理、异常等操作。 

PDO 还提供了大量的常量,以解决数据库操作的各种功能。

二.PDO数据库连接

如果是连接 mysql 数据库,可以使用一下方式: 

$_pdo = new PDO('mysql:host=localhost;dbname=cms','root','123456');

在 PDO 构造方法里的三个参数分别为:数据源 DSN、用户名、密码 

数据源 DSN:'数据库驱动:地址=localhost;数据库名=cms' 数据库驱动:mysql

对 PDO 错误的处理,有专门的 PDOException 异常类处理。 

try {
   $_pdo = new PDO('mysql:host=localhost;dbname=cms','root','123456',$_drive_opt);
} catch (PDOException  $e) {
   exit('数据库链接错误:'.$e->getMessage());
}

PDO与连接有关的选项 

可以使用$_pdo->getAttribute();来获取连接有关的选项,具体如下: 

1.ATTR_AUTOCOMMIT 确定每次提交,是否等待 commit()方法才生效。 

2.ATTR_CASE 强制获取的列字符大小写全部转换为大写或小写,或不动。有三个选项 可以控制:CASE_UPPER、CASE_LOWER 和 CASE_NATURAL。 3.ATTR_EMULATE_PREPARES 可使准备语句利用 MySQL 的查询缓存。 

4.ATTR_ERRMODE 错误模式报告,PDO 支持三种:ERRMODE_EXCEPTION、 ERRMODE_SILENT 和 ERRMODE_WARNING。 

5.ATTR_ORACLE_NULLS 设置为 TRUE 时,把字符串转成 NULL。默认情况 FALSE。 

6.ATTR_PERSISTENT 是否持久连接。 

7.ATTR_PREFETCH 预获取是一种获取多行的数据库特性。 

8.ATTR_TIMEOUT 超时,MySQL 不支持。 

9.ATTR_SERVER_INFO 数据库信息。 

10.ATTR_SERVER_VERSION 数据库版本。 

11.ATTR_CLIENT_VERSION 数据库客户端版本。 

12.ATTR_CONNECTION_STATUS 数据库连接状态信息。

我们可以通过$_pdo->getAttribute();来获取这些属性信息,自然也可以通过 $_pdo->setAttribute();来设置它。

<?php

try {
   $_pdo = new PDO('mysql:host=localhost;dbname=cms','root','123456',$_drive_opt);
} catch (PDOException  $e) {
   exit('数据库链接错误:'.$e->getMessage());
}

//设置自动提交
//$_pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,false);
//$_pdo->setAttribute(PDO::ATTR_SERVER_VERSION,'4.0'); //这个不行,不能修改


echo '是否自动提交:'.$_pdo->getAttribute(PDO::ATTR_AUTOCOMMIT).'<br />';
echo '数据库版本:'.$_pdo->getAttribute(PDO::ATTR_SERVER_VERSION);

?>

当然,还有一个更好的方法来设置,那就是 PDO 连接数据库的第四个参数:drive_opt。 通过数组来设置这些属性。 

<?php
try {
   $_drive_opt = array(
                                 PDO::ATTR_AUTOCOMMIT=>false
   );
   $_pdo = new PDO('mysql:host=localhost;dbname=cms','root','123456',$_drive_opt);
} catch (PDOException  $e) {
   exit('数据库链接错误:'.$e->getMessage());
}

三.数据库操作

PDO 提供了几个执行查询的方法,每个方法都经过调整以尽可能更高效的方式执行一 个特定的查询。 

1.执行没有结果集的查询:当执行 INSERT、UPDATE 和 DELETE 等查询时,不返回结 果集。在这些情况下,exec()方法将返回查询所影响的行数。 

2.一次执行一个查询:当执行返回结果集的查询时,或者所影响的行数无关紧要时,应 当使用 query()方法。 

3.多次执行一个查询:虽然可以使用 while 循环和 query()配合执行多次查询,但使用准 备语句来实现效率会更加高效 prepare()。

范例:使用 exec()新增一条数据

<?php
try {
   $_pdo = new PDO('mysql:host=localhost;dbname=cms','root','123456');
} catch (PDOException  $e) {
   exit('数据库链接错误:'.$e->getMessage());
}

$_sql = "INSERT INTO cms_user (user,email) VALUES ('Zhou','zhou@163.com')";
$_pdo->exec($_sql);

?>

在 PDO 操作 SQL 如果有错误的情况下,他报错的方式提供了三种: 

1.ERRMODE_EXCEPTION //异常模式,通过异常来捕获错误 

2.ERRMODE_SILENT //默认模式,错误时不进行任何操作 

3.ERRMODE_WARNING //警告模式,错误时会报警告


如果采用默认模式,那么,我们需要自行判断和输出错误结果。 

<?php
if (!$_affected_rows) { 
    echo '错误代号:'.$_pdo->errorCode(); 
    echo '<br />错误信息:'; 
    print_r($_pdo->errorInfo()); 
}

如果设置了警告模式,会自动提醒PDO操作数据库存在的问题。

<?php
try {
   $_pdo = new PDO('mysql:host=localhost;dbname=cms','root','123456');
   $_pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
} catch (PDOException  $e) {
   exit('数据库链接错误:'.$e->getMessage());
}

$_sql = "INSERT INTO cms_user (user,email) VALUES ('Zhou','zhou@163.com')";
$_pdo->exec($_sql);

?>

如果设置了异常模式,则需要通过 try{}catch{}来捕获。 

<?php
try {
    $_pdo = new PDO('mysql:host=localhost;dbname=cms','root','123456');
    $_pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
} catch (PDOException  $e) {
    exit('数据库链接错误:'.$e->getMessage());
}

try {
   $_sql = "INSERT INTO cms_user (use2r,email) VALUES ('Zhou','zhou@163.com')";
   $_pdo->exec($_sql);
} catch (PDOException  $e) {
   echo 'SQL语句有误:'.$e->getMessage();
}


?>

使用 query()来设置字符集编码: 

<?php
try {
   $_pdo = new PDO('mysql:host=localhost;dbname=cms','root','123456');
   $_pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
   $_pdo->query('SET NAMES UTF8');
} catch (PDOException  $e) {
   exit('数据库链接错误:'.$e->getMessage());
}

也可以是用常量来设置字符集编码:

<?php
try {
   $_drive_opt = array(
                              PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES UTF8'
   );
   $_pdo = new PDO('mysql:host=localhost;dbname=cms','root','123456',$_drive_opt);
   $_pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
} catch (PDOException  $e) {
   exit('数据库链接错误:'.$e->getMessage());
}

使用 query()来获取数据集,要注意,获取后返回的不是结果集,而是预处理对象 PDOStatement。所以,可以通过 foreach 来循环获取。

<?php
try {
    $_drive_opt = array(
        PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES UTF8'
    );
    $_pdo = new PDO('mysql:host=localhost;dbname=cms','root','123456',$_drive_opt);
    $_pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
} catch (PDOException  $e) {
    exit('数据库链接错误:'.$e->getMessage());
}

$_sql = "SELECT user,pass FROM cms_user";
$_stmt = $_pdo->query($_sql);
foreach ($_stmt as $_row) {
   print_r($_row);
}

可以使用 query(sql,模式)方法中的第二个参数来确定数据的获取方式。 

1.FETCH_BOTH 默认模式,关联和数字数组模式 

2.FETCH_NUM 数字模式,数字数组模式 

3.FETCH_ASSOC 关联模式,关联数组模式 

4.FETCH_OBJ 对象模式,对象数组模式

<?php
try {
    $_drive_opt = array(
        PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES UTF8'
    );
    $_pdo = new PDO('mysql:host=localhost;dbname=cms','root','123456',$_drive_opt);
    $_pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
} catch (PDOException  $e) {
    exit('数据库链接错误:'.$e->getMessage());
}

$_sql = "SELECT user,pass FROM cms_user";
$_stmt = $_pdo->query($_sql,PDO::FETCH_OBJ);
foreach ($_stmt as $_row) {
   print_r($_row);
}

使用 fetch()方法,可以获取结果集下一行。我们也可以在 fetch(模式)里传入模式参数, 可以得到相应的数据获取方式。 

<?php
try {
    $_drive_opt = array(
        PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES UTF8'
    );
    $_pdo = new PDO('mysql:host=localhost;dbname=cms','root','123456',$_drive_opt);
    $_pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
} catch (PDOException  $e) {
    exit('数据库链接错误:'.$e->getMessage());
}
$_sql = "SELECT user,pass FROM cms_user";
$_stmt = $_pdo->query($_sql);
while (!!$_row = $_stmt->fetch()) {
   print_r($_row);
}

使用 columnCount()方法返回结果集中的总列数。 

echo $_stmt->columnCount();

使用 fetchAll()方法一次性获取所有数据。PS:大规模结果集会增加巨大的负担。 

<?php
try {
    $_drive_opt = array(
        PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES UTF8'
    );
    $_pdo = new PDO('mysql:host=localhost;dbname=cms','root','123456',$_drive_opt);
    $_pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
} catch (PDOException  $e) {
    exit('数据库链接错误:'.$e->getMessage());
}
$_sql = "SELECT user,pass FROM cms_user";
$_stmt = $_pdo->query($_sql);
foreach ($_stmt->fetchAll() as $_row) {
    print_r($_row);
}

使用 fetchObject()方法以对象的方式获取下一行结果集。 

<?php
try {
    $_drive_opt = array(
        PDO::MYSQL_ATTR_INIT_COMMAND=>'SET NAMES UTF8'
    );
    $_pdo = new PDO('mysql:host=localhost;dbname=cms','root','123456',$_drive_opt);
    $_pdo->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_WARNING);
} catch (PDOException  $e) {
    exit('数据库链接错误:'.$e->getMessage());
}
$_sql = "SELECT user,pass FROM cms_user";
$_stmt = $_pdo->query($_sql);
while (!!$_row = $_stmt->fetchObject()) { 
    print_r($_row); 
}

使用setFetchMode(模式),来统一指定结果集的获取方式。 

$_stmt->setFetchMode();

使用 fetchColumn()方法返回结果集中下一行某个列的值。 

echo $_stmt->fetchColumn(0);




打赏

『微信打赏』

Tag标签php 

我是有底线的