轶哥博客

九零后全栈开发者,未来学学者。想做的事情太多,既要环游世界,也妄图改变点什么的强迫症。

PHP连接数据库进行增删查改-PDO方法-以MySQL为例

  由于PHP6中将默认以PDO方法连接数据库,而PDO方法优点很多,因此此文仅介绍PDO方法连接数据库进行操作。需要注意,从 PHP 5.1 开始附带了 PDO,在 PHP 5.0 中是作为一个 PECL 扩展使用,在生产环境中强烈建议升级到PHP5.4+版本。

PDO操作数据库的主要优点

  • 支持多种数据库(只要提供正确的数据源,其它的数据库操作是一样的)。
  • 开发效率更高,便于移植。
  • 对事务处理支持更好,特别是事务回滚。
  • 更为安全。

典型连接代码

/**
 * 数据库连接文件
 *
 * PDO连接MySQL数据库
 * @author      王轶<a@wyr.me>
 * @version     0.4
 * @copyright   BSD
 */
try {
    $db_ip = "localhost";   //数据库IP地址
    $db_port = "3306";          //数据库端口号
    $db_name = "";          //数据库名称
    $db_user = "";          //数据库用户名
    $db_pass = "";          //数据库密码
    $PDO = new PDO('mysql:host='.$db_ip.';port='.$db_por.';dbname='.$db_name.';charset=utf8', $db_user, $db_pass, array(
                PDO::ATTR_PERSISTENT => true , // 设置数据库连接为持久连接
                PDO::ATTR_EMULATE_PREPARES => false , // 防止SQL注入
                PDO::ATTR_ORACLE_NULLS => true , // 设置当字符串为空转换为 SQL 的 NULL
                PDO::ATTR_ERRMODE , // 设置抛出错误
                PDO::ERRMODE_EXCEPTION // 设置抛出错误
    ));//PDO数据库连接代码
} catch (PDOException $e) {
    print "Error!: " . $e->;getMessage() . "<br/>";
    die();
}

注释已经说明了一切,然而这里还要强调一些东西:

  “PDO::ATTR_EMULATE_PREPARES =>; false”,这句代码的含义是:是否在本地进行参数转义。一般来说,由MySQL进行变量处理能够避免SQL注入,但会负面影响——部分汉字或符号无法正常写入数据库。这个问题在PHP5.4+版本中被解决,高版本的MySQL6.5+数据库也处理了一部分这类问题。

  需要注意的是,在编写SQL语句时需要符合其变量规则。可用以下函数进行处理:

/**
 * 格式化SQL数据类型
 *
 * @param string $theValue 目标SQL数据类型
 * @param mixed $theType 传入需要变更类型的数据
 * @return mixed
 */
function GetSQLValueString($theValue, $theType)
{
    switch ($theType) {
        case "text":
            $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
            break;
        case "long":
        case "int":
            $theValue = ($theValue != "") ? intval($theValue) : "NULL";
            break;
        case "double":
            $theValue = ($theValue != "") ? doubleval($theValue) : "NULL";
            break;
        case "date":
            $theValue = ($theValue != "") ? "'" . $theValue . "'" : "NULL";
            break;
    }
    return $theValue;
}

PDO常用函数

  • PDO::beginTransaction 用于启动一个事务
  • PDO::commit 用于提交一个事务
  • PDO::rollBack 用于回滚一个事务
  • PDO::query() 用于有记录结果返回的操作,特别是SELECT操作
  • PDO::exec() 执行一条 SQL 语句,并返回受影响的行数。用于没有结果集合返回的操作,如INSERT、UPDATE等操作。
  • PDO::lastInsertId() 返回上次插入操作中主键列类型是自增的ID
  • PDOStatement::fetch()用于获取一条记录
  • PDOStatement::fetchAll()用于获取记录集,返回PHP数组
  • PDO::setAttribute 用于设置PDO属性
  • PDO::getAttribute 用于取回一个数据库连接的属性
  • 其它常用函数点击这里进入官方文档

PDO错误与错误处理

  这里推荐大家学习一下在构造函数中设置错误模式的方法。以下是官方的例子:

<php
$dsn = 'mysql:dbname=test;host=127.0.0.1';
$user = 'googleguy';
$password = 'googleguy';

/*
    使用 try/catch 围绕构造函数仍然有效,即使设置了 ERRMODE 为 WARNING,
    因为如果连接失败,PDO::__construct 将总是抛出一个  PDOException 异常。
*/
try {
    $dbh = new PDO($dsn, $user, $password, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
    exit;
}

// 这里将导致 PDO 抛出一个 E_WARNING 级别的错误,而不是 一个异常 (当数据表不存在时)
$dbh->query("SELECT wrongcolumn FROM wrongtable");
?>

//以插入用户名和密码为例:
require_once("connect.php");//加载数据库连接文件,即本文第一个代码框中的代码
$insertSQL = sprintf("INSERT INTO `admin` SET username = %s, password = %s",
            GetSQLValueString($username, "text"),
            GetSQLValueString($password, "text"));
        $Result = $PDO->exec($insertSQL);//执行数据库写入操作
        $back_id = $PDO->lastInsertId();//获取写入的数据id
        if ($Result == "1") {
            //如果成功写入一条数据
        } else {

        }
$PDO = null;//关闭数据库链接

require_once("config.php");//引入数据库连接文件

$Result = $PDO->exec("DELETE FROM 表名称 WHERE 列名称 = 值");
if ($Result != "0") {
    //删除成功$Result是受影响的条数
}

  返回一条数据以json字符串的形式。

require_once('config.php');//引入数据库

$info = $PDO->query("SELECT * FROM `order` WHERE `id` = 1");
$Foundinf = $info->fetch(PDO::FETCH_ASSOC);
$PDO = null;//注销数据库
$json = json_encode($Foundinf);
echo $json;

  返回所有数据以json字符串数组的形式。

require_once('config.php');//引入数据库

$info = $PDO->query("SELECT * FROM `order`");
$Foundinf = $info->fetchAll(PDO::FETCH_ASSOC);
$PDO = null;//注销数据库
$json = json_encode($Foundinf);
echo $json;

  可以看到,上面两个代码的区别除了SQL语句不同外,只有fetch/fetchAll的区别。其中“PDO::FETCH_ASSOC”的含义是:以字段索引的方式返回数据。如果去除fetch()或fetchAll()中的参数,那么返回结果数字和字段两者同时返回(不太明白的同学请亲自试验一下)。在很多情况下是不必要的。

require_once("config.php");//引入数据库连接文件

$Result = $PDO->exec("UPDATE `admin` SET `username`='admin' WHERE id =1");
if ($Result != "0") {
    //修改成功$Result是受影响的条数,如果要修改的数据和欲修改数据一样也会返回0
}

最后说一句

  本人能力有限,如有错误之处望大家不吝赐教,谢谢!