【php】个人对PDO的封装以及使用

6758次阅读 467人点赞 作者: WuBin 发布时间: 2023-04-12 16:01:04
扫码到手机查看

类封装

类只适合简单的,原生PHP开发的简单项目使用。

这个类中,一共分为3个文件:

  • db_config.php
  • db.class.php
  • mypdo.class.php
我们将这3个php文件都放在名为db的文件夹中。

db_config.php

主要用于设置链接数据库的密码、账号。
<?php
$config = array(
    'dbhost' => 'localhost',
    'dbuser' => 'design0505',
    'dbpsw' => 'sj0505',
    'dbname' => 'xincards',
    'dbcharset' => 'utf8'
);

db.class.php

主要用于对mypdo.class类进行二次的封装,让类静态化,方便调用。

<?php
require 'db_config.php';

class DB {
    private static $conn;
    public static function init($config) {
        require('mypdo.class.php');
        self::$conn = new Mypdo($config);
        if (!self::$conn) {
            $res = [
                'error' => 5,
                'msg' => '数据库链接错误',
                'data' => false
            ];
            echo json_encode($res, JSON_UNESCAPED_UNICODE);
            exit;
        }
    }

    public static function handle($sql, $parameters = [])
    {
        return self::$conn->handle($sql, $parameters);
    }

    // 执行查询
    public static function query($sql, $parameters = [])
    {
        return self::$conn->query($sql, $parameters);
    }


    /**
     * [增 删 改 返回受影响的行数以及 最后插入的id]
     * array(2) { ["row"]=>int(1)  ["lastId"]=> "0"}
     * @return   [arr]             [插入返回成功的Id 和受影响的行数]
     */
    public static function getResult()
    {
        return self::$conn->getResult();
    }

    // 返回失败状态的信息
    public static function getError()
    {
        return self::$conn->getError();
    }

}

DB::init($config);

mypdo.class.php

核心库,实现对sql的查询以及其他操作。

<?php

class Mypdo {
    // mysql链接
    private $dsn;
    // 数据库用户名
    private $user;
    // 数据库密码
    private $password;
    // 数据库字符集
    private $charset;
    // PDO对象
    private $pdoInstance;
    // sql对象 查询获取的资源
    private $pdoStmt;
    // 存储错误码
    private $errArr;
    // 存储更新成功后影响的行数以及插入的id
    private $result;

    public function __construct($config) {
        if (!isset($config)) {
            return false;
        }
        $this->dsn = "mysql:host={$config['dbhost']};dbname={$config['dbname']}";
        $this->user = $config['dbuser'];
        $this->password = $config['dbpsw'];
        $this->charset = $config['dbcharset'];
        if (!$this->connect()) {
            return false;
        }
    }

    private function connect()
    {
        if (!$this->pdoInstance) {
            $options = array(
                PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES '.$this->charset
            );

            $this->pdoInstance = new PDO($this->dsn, $this->user, $this->password, $options);
            if (!$this->pdoInstance) {
               return false;
            }
            $this->pdoInstance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }
    }

    public function query($sql, $parameters = []) {
        if (!is_array($parameters)) {
            $parameters = array($parameters);
        }
        $this->pdoStmt = $this->pdoInstance->prepare($sql);
        $index = 1;
        foreach ($parameters as $parameter) {
            $this->pdoStmt->bindValue($index++, $parameter[0], $parameter[1]);
        }
        $execRe = $this->pdoStmt->execute();
        if (!$execRe) {
            $this->errArr = array(
                'code' => $this->pdoStmt->errorCode(),
                'info' => $this->pdoStmt->errorInfo()[2]
            );
            return false;
        }
        $data = $this->pdoStmt->fetchAll(PDO::FETCH_ASSOC);
        return $data;
    }

    // 增 删 改 操作
    public function handle($sql, $parameters = [])
    {
        if (!is_array($parameters)) {
            $parameters = array($parameters);
        }
        $this->pdoStmt = $this->pdoInstance->prepare($sql);
        if (count($parameters) > 0) {
            $index = 1;
            foreach ($parameters as $parameter) {
                // var_dump($parameter);
                $this->pdoStmt->bindValue($index++, $parameter[0], $parameter[1]);
            }
        }
        $execRe = $this->pdoStmt->execute();
        // var_dump($sql);
        // exit();
        if (!$execRe) {
            $this->errArr = array(
                'code' => $this->pdoStmt->errorCode(),
                'info' => $this->pdoStmt->errorInfo()[2]
            );
            return false;
        }
        $this->result = [
            // 影响的行数
            'row' => $this->pdoStmt->rowCount(),
            // 插入的id
            'lastId' => $this->pdoInstance->lastInsertId()
        ];
        return true;
    }

    public function getError()
    {
        // 如果错误状态数组返回true
        if ((bool)$this->errArr) {
            $err = $this->errArr;
        } else {
            $err = array();
        }
        return $err;
    }

    // 返回插入 修改 删除的结果
    public function getResult()
    {
        if (!is_array($this->result) && empty($this->result)) {
            $this->result = array();
        }
        return $this->result;
    }


}

使用例

查询

$pageSize = 10;
$offset = $pageSize * (2 - 1);
 $sql = "
       SELECT template_id,
              template_name as template_title,
              template_preview,
              template_public,
              created_at
       FROM `{$table}`
       ORDER BY template_id DESC
       LIMIT ? OFFSET ?
";
$res = DB::query($sql, [
    [ $pageSize, PDO::PARAM_INT ],
    [ $offset, PDO::PARAM_INT ]
]);

if(!($res === false) && 
    is_array($res) &&
    count($res) >= 0
) {
    // 查询成功
} else {
    // 查询失败
}
这里注意,如果查询失败,那么会返回false,但是不能仅仅使用!$res来判断,因为当没有相匹配的条数,但是查询是成功的,那么返回的就是空数组,这时候![] 得到的也是true!

insert

$sql = "
       INSERT INTO `{$table}` (
       template_id,
       card_name,
       card_data,
       card_template_bak,
       card_author,
       created_at,
       updated_at
       ) VALUES (
       ?,
       ?,
       ?,
       ?,
       ?,
       NOW(),
       NOW()
       )
";

try {
       $res_db = DB::handle($sql, [
              [ $template_id, PDO::PARAM_INT ],
              [ $title, PDO::PARAM_STR ],
              [ $template['compdata'], PDO::PARAM_STR ],
              [ $template['html'], PDO::PARAM_STR ],
              [ $realname, PDO::PARAM_STR ]
       ]);
       if ($res_db && DB::getResult()['row'] > 0) {
              // 插入成功
       } else {
              // 插入失败
       }
} catch (Exception $e) {
       $msg = '插入失败, ' . $e->getMessage();
       exit($msg);
}

update

$sql = "
    UPDATE `{$table}`
    SET template_name = ?,
        template_preview = ?,
        template_public = ?,
        template_path = ?,
        template_html = ?,
        template_data = ?,
        updated_at = NOW()
    WHERE template_id = ?
";
$res = DB::handle($sql, [
    [$title, PDO::PARAM_STR],
    [$preview, PDO::PARAM_STR],
    [$public, PDO::PARAM_INT],
    [$path, PDO::PARAM_STR],
    [$html, PDO::PARAM_STR],
    [$data, PDO::PARAM_STR],
    [$templateId, PDO::PARAM_INT]
]);

if($res && DB::getResult()['row'] >= 1) {
    // 更新成功
} else {
    // 更新失败    
}

delete

$sql = "
    DELETE FROM `{$table}`
    WHERE card_id = ?
";
$res = DB::handle($sql, [
    [ $cardId, PDO::PARAM_INT ]
]);
if($res && DB::getResult()['row'] > 0) {
    // 删除成功
} else {
    // 删除失败
}

PDO中的常量列表

PDO使用类常量自PHP 5.1。

PDO::PARAM_BOOL (integer)表示布尔数据类型。
PDO::PARAM_NULL (integer)表示 SQL 中的 NULL 数据类型。
PDO::PARAM_INT (integer)表示 SQL 中的整型。
PDO::PARAM_STR (integer)表示 SQL 中的 CHAR、VARCHAR 或其他字符串类型。
PDO::PARAM_LOB (integer)表示 SQL 中大对象数据类型。
PDO::PARAM_STMT (integer)表示一个记录集类型。当前尚未被任何驱动支持。
PDO::PARAM_INPUT_OUTPUT (integer)指定参数为一个存储过程的 INOUT 参数。必须用一个明确的 PDO::PARAM_* 数据类型跟此值进行按位或。
PDO::FETCH_LAZY (integer)指定获取方式,将结果集中的每一行作为一个对象返回,此对象的变量名对应着列名。PDO::FETCH_LAZY 创建用来访问的对象变量名。在 PDOStatement::fetchAll() 中无效。
PDO::FETCH_ASSOC (integer)指定获取方式,将对应结果集中的每一行作为一个由列名索引的数组返回。如果结果集中包含多个名称相同的列,则PDO::FETCH_ASSOC每个列名只返回一个值。
PDO::FETCH_NAMED (integer)指定获取方式,将对应结果集中的每一行作为一个由列名索引的数组返回。如果结果集中包含多个名称相同的列,则PDO::FETCH_ASSOC每个列名 返回一个包含值的数组。
PDO::FETCH_NUM (integer)指定获取方式,将对应结果集中的每一行作为一个由列号索引的数组返回,从第 0 列开始。
PDO::FETCH_BOTH (integer)指定获取方式,将对应结果集中的每一行作为一个由列号和列名索引的数组返回,从第 0 列开始。
PDO::FETCH_OBJ (integer)指定获取方式,将结果集中的每一行作为一个属性名对应列名的对象返回。
PDO::FETCH_BOUND (integer)指定获取方式,返回 TRUE 且将结果集中的列值分配给通过 PDOStatement::bindParam() 或 PDOStatement::bindColumn() 方法绑定的 PHP 变量。
PDO::FETCH_COLUMN (integer)指定获取方式,从结果集中的下一行返回所需要的那一列。
PDO::FETCH_CLASS (integer)指定获取方式,返回一个所请求类的新实例,映射列到类中对应的属性名。

注意: 如果所请求的类中不存在该属性,则调用 __set() 魔术方法

PDO::FETCH_INTO (integer)指定获取方式,更新一个请求类的现有实例,映射列到类中对应的属性名。
PDO::FETCH_FUNC (integer)允许在运行中完全用自定义的方式处理数据。(仅在 PDOStatement::fetchAll() 中有效)。
PDO::FETCH_GROUP (integer)根据值分组返回。通常和 PDO::FETCH_COLUMN 或 PDO::FETCH_KEY_PAIR 一起使用。
PDO::FETCH_UNIQUE (integer)只取唯一值。
PDO::FETCH_KEY_PAIR (integer)获取一个有两列的结果集到一个数组,其中第一列为键名,第二列为值。自 PHP 5.2.3 起可用。
PDO::FETCH_CLASSTYPE (integer)根据第一列的值确定类名。
PDO::FETCH_SERIALIZE (integer)类似 PDO::FETCH_INTO ,但是以一个序列化的字符串表示对象。自 PHP 5.1.0 起可用。从 PHP 5.3.0 开始,如果设置此标志,则类的构造函数从不会被调用。
PDO::FETCH_PROPS_LATE (integer)设置属性前调用构造函数。自 PHP 5.2.0 起可用。
PDO::ATTR_AUTOCOMMIT (integer)如果此值为 FALSE ,PDO 将试图禁用自动提交以便数据库连接开始一个事务。
PDO::ATTR_PREFETCH (integer)设置预取大小来为你的应用平衡速度和内存使用。并非所有的数据库/驱动组合都支持设置预取大小。较大的预取大小导致性能提高的同时也会占用更多的内存。
PDO::ATTR_TIMEOUT (integer)设置连接数据库的超时秒数。
PDO::ATTR_ERRMODE (integer)关于此属性的更多信息请参见 错误及错误处理 部分。
PDO::ATTR_SERVER_VERSION (integer)此为只读属性;返回 PDO 所连接的数据库服务的版本信息。
PDO::ATTR_CLIENT_VERSION (integer)此为只读属性;返回 PDO 驱动所用客户端库的版本信息。
PDO::ATTR_SERVER_INFO (integer)此为只读属性。返回一些关于 PDO 所连接的数据库服务的元信息。
PDO::ATTR_CONNECTION_STATUS (integer)
PDO::ATTR_CASE (integer)用类似 PDO::CASE_* 的常量强制列名为指定的大小写。
PDO::ATTR_CURSOR_NAME (integer)获取或设置使用游标的名称。当使用可滚动游标和定位更新时候非常有用。
PDO::ATTR_CURSOR (integer)选择游标类型。 PDO 当前支持 PDO::CURSOR_FWDONLY 和 PDO::CURSOR_SCROLL。一般为 PDO::CURSOR_FWDONLY,除非确实需要一个可滚动游标。
PDO::ATTR_DRIVER_NAME (string)返回驱动名称。使用 PDO::ATTR_DRIVER_NAME 的例子:

if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') {

   echo "Running on mysql; doing something mysql specific here\n";

}

PDO::ATTR_ORACLE_NULLS (integer)在获取数据时将空字符串转换成 SQL 中的 NULL 。
PDO::ATTR_PERSISTENT (integer)请求一个持久连接,而非创建一个新连接。关于此属性的更多信息请参见 连接与连接管理 。
PDO::ATTR_STATEMENT_CLASS (integer)
PDO::ATTR_FETCH_CATALOG_NAMES (integer)将包含的目录名添加到结果集中的每个列名前面。目录名和列名由一个小数点分开(.)。此属性在驱动层面支持,所以有些驱动可能不支持此属性。
PDO::ATTR_FETCH_TABLE_NAMES (integer)将包含的表名添加到结果集中的每个列名前面。表名和列名由一个小数点分开(.)。此属性在驱动层面支持,所以有些驱动可能不支持此属性。
PDO::ATTR_STRINGIFY_FETCHES (integer)
PDO::ATTR_MAX_COLUMN_LEN (integer)
PDO::ATTR_DEFAULT_FETCH_MODE (integer)自 PHP 5.2.0 起可用。
PDO::ATTR_EMULATE_PREPARES (integer)自 PHP 5.1.3 起可用。
PDO::ERRMODE_SILENT (integer)如果发生错误,则不显示错误或异常。希望开发人员显式地检查错误。此为默认模式。关于此属性的更多信息请参见 错误与错误处理 。
PDO::ERRMODE_WARNING (integer)如果发生错误,则显示一个 PHP E_WARNING 消息。关于此属性的更多信息请参见 错误与错误处理。
PDO::ERRMODE_EXCEPTION (integer)如果发生错误,则抛出一个 PDOException 异常。关于此属性的更多信息请参见 错误与错误处理。
PDO::CASE_NATURAL (integer)保留数据库驱动返回的列名。
PDO::CASE_LOWER (integer)强制列名小写。
PDO::CASE_UPPER (integer)强制列名大写。
PDO::NULL_NATURAL (integer)
PDO::NULL_EMPTY_STRING (integer)
PDO::NULL_TO_STRING (integer)
PDO::FETCH_ORI_NEXT (integer)在结果集中获取下一行。仅对可滚动游标有效。
PDO::FETCH_ORI_PRIOR (integer)在结果集中获取上一行。仅对可滚动游标有效。
PDO::FETCH_ORI_FIRST (integer)在结果集中获取第一行。仅对可滚动游标有效。
PDO::FETCH_ORI_LAST (integer)在结果集中获取最后一行。仅对可滚动游标有效。
PDO::FETCH_ORI_ABS (integer)根据行号从结果集中获取需要的行。仅对可滚动游标有效。
PDO::FETCH_ORI_REL (integer)根据当前游标位置的相对位置从结果集中获取需要的行。仅对可滚动游标有效。
PDO::CURSOR_FWDONLY (integer)创建一个只进游标的 PDOStatement 对象。此为默认的游标选项,因为此游标最快且是 PHP 中最常用的数据访问模式。
PDO::CURSOR_SCROLL (integer)创建一个可滚动游标的 PDOStatement 对象。通过 PDO::FETCH_ORI_* 常量来控制结果集中获取的行。
PDO::ERR_NONE (string)对应 SQLSTATE '00000',表示 SQL 语句没有错误或警告地成功发出。当用 PDO::errorCode() 或 PDOStatement::errorCode() 来确定是否有错误发生时,此常量非常方便。在检查上述方法返回的错误状态代码时,会经常用到。
PDO::PARAM_EVT_ALLOC (integer)分配事件
PDO::PARAM_EVT_FREE (integer)解除分配事件
PDO::PARAM_EVT_EXEC_PRE (integer)执行一条预处理语句之前触发事件。
PDO::PARAM_EVT_EXEC_POST (integer)执行一条预处理语句之后触发事件。
PDO::PARAM_EVT_FETCH_PRE (integer)从一个结果集中取出一条结果之前触发事件。
PDO::PARAM_EVT_FETCH_POST (integer)从一个结果集中取出一条结果之后触发事件。
PDO::PARAM_EVT_NORMALIZE (integer)在绑定参数注册允许驱动程序正常化变量名时触发事件。

附件下载

db

相关资料

点赞 支持一下 觉得不错?客官您就稍微鼓励一下吧!
关键词:pdo
推荐阅读
  • uniapp实现被浏览器唤起的功能

    当用户打开h5链接时候,点击打开app若用户在已经安装过app的情况下直接打开app,若未安装过跳到应用市场下载安装这个功能在实现上主要分为两种场景,从普通浏览器唤醒以及从微信唤醒。

    9603次阅读 623人点赞 发布时间: 2022-12-14 16:34:53 立即查看
  • Vue

    盘点Vue2和Vue3的10种组件通信方式

    Vue中组件通信方式有很多,其中Vue2和Vue3实现起来也会有很多差异;本文将通过选项式API组合式API以及setup三种不同实现方式全面介绍Vue2和Vue3的组件通信方式。

    4297次阅读 317人点赞 发布时间: 2022-08-19 09:40:16 立即查看
  • JS

    几个高级前端常用的API

    推荐4个前端开发中常用的高端API,分别是MutationObserver、IntersectionObserver、getComputedstyle、getBoundingClientRect、requ...

    14452次阅读 948人点赞 发布时间: 2021-11-11 09:39:54 立即查看
  • PHP

    【正则】一些常用的正则表达式总结

    在日常开发中,正则表达式是非常有用的,正则表达式在每个语言中都是可以使用的,他就跟JSON一样,是通用的。了解一些常用的正则表达式,能大大提高你的工作效率。

    13497次阅读 491人点赞 发布时间: 2021-10-09 15:58:58 立即查看
  • 【中文】免费可商用字体下载与考证

    65款免费、可商用、无任何限制中文字体打包下载,这些字体都是经过长期验证,经得住市场考验的,让您规避被无良厂商起诉的风险。

    12015次阅读 963人点赞 发布时间: 2021-07-05 15:28:45 立即查看
  • Vue

    Vue3开发一个v-loading的自定义指令

    在vue3中实现一个自定义的指令,有助于我们简化开发,简化复用,通过一个指令的调用即可实现一些可高度复用的交互。

    16376次阅读 1307人点赞 发布时间: 2021-07-02 15:58:35 立即查看
  • JS

    关于手机上滚动穿透问题的解决

    当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。在PC上使用css即可解决,但是在手机端,情况就变的比较复杂,就需要禁止触摸事件才可以。

    15187次阅读 1234人点赞 发布时间: 2021-05-31 09:25:50 立即查看
  • Vue

    Vue+html2canvas截图空白的问题

    在使用vue做信网单页专题时,有海报生成的功能,这里推荐2个插件:一个是html2canvas,构造好DOM然后转canvas进行截图;另外使用vue-canvas-poster(这个截止到2021年3月...

    29849次阅读 2347人点赞 发布时间: 2021-03-02 09:04:51 立即查看
  • Vue

    vue-router4过度动画无效解决方案

    在初次使用vue3+vue-router4时候,先后遇到了过度动画transition进入和退出分别无效的情况,搜遍百度没没找到合适解决方法,包括vue-route4有一些API都进行了变化,以前的一些操...

    25911次阅读 1994人点赞 发布时间: 2021-02-23 13:37:20 立即查看
交流 收藏 目录