pdo-mysql

2023-05-16

pdo-mysql

PHP连接数据库推荐使用PDO,PDO扩展为PHP访问数据库定义了一个轻量级接口。我们可以通过实现PDO接口的每个数据库驱动来访问数据库服务。

访问mysql数据库服务,我们使用PDO_MYSQL驱动

1.PDO实现CRUD

192.168.1.13:3306的mysql实例上创建数据库roach,创建roach用户并授权,在roach库中创建表t_user,sql如下

CREATE TABLE `t_user` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `user_name` varchar(32) CHARACTER SET utf8 DEFAULT 'NULL' COMMENT '登录名',
  `true_name` varchar(32) CHARACTER SET utf8 DEFAULT '' COMMENT '真实姓名',
  `password` char(32) CHARACTER SET utf8 DEFAULT '' COMMENT '密码',
  `is_on` tinyint(3) unsigned DEFAULT '0' COMMENT '是否启用(0禁用1启用)',
  `last_login_ip` bigint(20) unsigned DEFAULT '0' COMMENT '上次登录ip',
  `add_time` int(10) unsigned DEFAULT '0' COMMENT '添加时间',
  `update_time` int(10) unsigned DEFAULT '0' COMMENT '修改时间',
  `version` int(10) unsigned DEFAULT '0' COMMENT '乐观锁版本',
  PRIMARY KEY (`id`),
  UNIQUE KEY `user_name` (`user_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=COMPACT COMMENT='用户表';

使用PDO操作t_user

<?php
//\PDO构造函数有四个参数,第一个参数是dsn,第二个参数是用户名,第三个参数是密码,第四个参数是连接选项
//mysql数据库服务的dsn示例如下
$pdo = new \PDO('mysql:host=192.168.1.13;port=3306;dbname=roach;charset=utf8', 'roach', 'roach', [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);

//1.insert
/**
 * @var \PDOStatement $stmt
 */
$stmt = $pdo->query("INSERT INTO `t_user`(`user_name`,`true_name`,`add_time`) VALUES('".uniqid('u')."','".uniqid('t')."',".time().")");

$userId = $pdo->lastInsertId();
//输出受影响行数和lastInsertId
echo 'insert受影响行数:'.$stmt->rowCount().';插入的用户id:'.$userId.PHP_EOL;

//2.update
$stmt = $pdo->query('UPDATE `t_user` SET `user_name`=\'pdo-mysql\' WHERE id='.$userId);
echo 'update受影响行数:'.$stmt->rowCount().PHP_EOL;

//3.select
$stmt = $pdo->query('SELECT * FROM `t_user` WHERE `id`='.$userId);
echo 'select查询结果:'.json_encode($stmt->fetchAll(\PDO::FETCH_ASSOC), JSON_UNESCAPED_UNICODE).PHP_EOL;

//4.delete
$stmt = $pdo->query('DELETE FROM `t_user` WHERE id='.$userId);
echo 'delete受影响行数:'.$stmt->rowCount().PHP_EOL;

以上例程输出

insert受影响行数:1;插入的用户id:1
update受影响行数:1
select查询结果:[{"id":"1","user_name":"pdo-mysql","true_name":"t5f2d341bc4b43","password":"","is_on":"0","last_login_ip":"add_time":"0000-00-00 00:00:00","update_time":"0","version":"0"}]
delete受影响行数:1

2.防sql注入

以上例程我们可以看到,并未做sql注入安全防范处理,使用PDO操作mysql数据库一般使用参数绑定来防止sql注入,参数绑定有以下两种方式

2.1 ?占位符绑定

1例程中的CRUD代码通过?参数绑定修改后的代码

<?php
//\PDO构造函数有四个参数,第一个参数是dsn,第二个参数是用户名,第三个参数是密码,第四个参数是连接选项
//mysql数据库服务的dsn示例如下
$pdo = new \PDO('mysql:host=192.168.1.13;port=3306;dbname=roach;charset=utf8', 'roach', 'roach', [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);

//1.insert
/**
 * @var \PDOStatement $stmt
 */
//$stmt = $pdo->query("INSERT INTO `t_user`(`user_name`,`true_name`,`add_time`) VALUES('".uniqid('u')."','".uniqid('t')."',".time().")");

$stmt = $pdo->prepare("INSERT INTO `t_user`(`user_name`,`true_name`,`add_time`) VALUES(?, ?, ?)");

$stmt->bindValue(1, uniqid('u'), \PDO::PARAM_STR);
$stmt->bindValue(2, uniqid('t'), \PDO::PARAM_STR);
$stmt->bindValue(3, time(), \PDO::PARAM_INT);
$stmt->execute();

//以上四行可以简写成
//$stmt->execute([uniqid('u'), uniqid('t'), time()]);

$userId = $pdo->lastInsertId();
//输出受影响行数和lastInsertId
echo 'insert受影响行数:'.$stmt->rowCount().';插入的用户id:'.$userId.PHP_EOL;

//2.update
//$stmt = $pdo->query('UPDATE `t_user` SET `user_name`=\'pdo-mysql\' WHERE id='.$userId);
$stmt = $pdo->prepare('UPDATE `t_user` SET `user_name`=? WHERE id=?');

$stmt->bindValue(1, 'pdo-msyql');
$stmt->bindValue(2, $userId, \PDO::PARAM_INT);
$stmt->execute();

//以上三句可以简写成
//$stmt->execute(['pdo-mysql', $userId]);

echo 'update受影响行数:'.$stmt->rowCount().PHP_EOL;

//3.select
//$stmt = $pdo->query('SELECT * FROM `t_user` WHERE `id`='.$userId);
$stmt = $pdo->prepare('SELECT * FROM `t_user` WHERE `id`=?');

$stmt->bindValue(1, $userId, \PDO::PARAM_INT);
$stmt->execute();

//以上两句可以简写成
//$stmt->execute([$userId]);

echo 'select查询结果:'.json_encode($stmt->fetchAll(\PDO::FETCH_ASSOC), JSON_UNESCAPED_UNICODE).PHP_EOL;

//4.delete
//$stmt = $pdo->query('DELETE FROM `t_user` WHERE id='.$userId);

$stmt = $pdo->prepare('DELETE FROM `t_user` WHERE id=?');

$stmt->bindValue(1, $userId, \PDO::PARAM_INT);
$stmt->execute();

//以上两句可以简写成
//$stmt->execute([$userId]);

echo 'delete受影响行数:'.$stmt->rowCount().PHP_EOL;

例程的执行结果是一致的

2.2 自定义占位符绑定

参数绑定也可以自定义占位符,如一下例程

<?php
//\PDO构造函数有四个参数,第一个参数是dsn,第二个参数是用户名,第三个参数是密码,第四个参数是连接选项
//mysql数据库服务的dsn示例如下
$pdo = new \PDO('mysql:host=192.168.1.13;port=3306;dbname=roach;charset=utf8', 'roach', 'roach', [\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION]);
                                                                                               
//1.insert
/**
 * @var \PDOStatement $stmt
 */
//$stmt = $pdo->query("INSERT INTO `t_user`(`user_name`,`true_name`,`add_time`) VALUES('".uniqid('u')."','".uniqid('t')."',".time().")");
$stmt = $pdo->prepare("INSERT INTO `t_user`(`user_name`,`true_name`,`add_time`) VALUES(:user_name, :true_name, :add_time)");

$stmt->bindValue(':user_name', uniqid('u'), \PDO::PARAM_STR);
$stmt->bindValue(':true_name', uniqid('t'), \PDO::PARAM_STR);
$stmt->bindValue(':add_time', time(), \PDO::PARAM_INT);
$stmt->execute();

$userId = $pdo->lastInsertId();
//输出受影响行数和lastInsertId
echo 'insert受影响行数:'.$stmt->rowCount().';插入的用户id:'.$userId.PHP_EOL;

//2.update
//$stmt = $pdo->query('UPDATE `t_user` SET `user_name`=\'pdo-mysql\' WHERE id='.$userId);
$stmt = $pdo->prepare('UPDATE `t_user` SET `user_name`=:user_name WHERE id=:id');

$stmt->bindValue(':user_name', 'pdo-msyql');
$stmt->bindValue(':id', $userId, \PDO::PARAM_INT);
$stmt->execute();

echo 'update受影响行数:'.$stmt->rowCount().PHP_EOL;

//3.select
//$stmt = $pdo->query('SELECT * FROM `t_user` WHERE `id`='.$userId);
$stmt = $pdo->prepare('SELECT * FROM `t_user` WHERE `id`=:id');

$stmt->bindValue(':id', $userId, \PDO::PARAM_INT);
$stmt->execute();

echo 'select查询结果:'.json_encode($stmt->fetchAll(\PDO::FETCH_ASSOC), JSON_UNESCAPED_UNICODE).PHP_EOL;

//4.delete
//$stmt = $pdo->query('DELETE FROM `t_user` WHERE id='.$userId);
$stmt = $pdo->prepare('DELETE FROM `t_user` WHERE id=:id');

$stmt->bindValue(':id', $userId, \PDO::PARAM_INT);
$stmt->execute();

echo 'delete受影响行数:'.$stmt->rowCount().PHP_EOL;

例程执行结果也是一致的

3.事务

以下例程演示用户id只能为奇数,否则回滚事务的示例

<?php
//\PDO构造函数有四个参数,第一个参数是dsn,第二个参数是用户名,第三个参数是密码,第四个参数是连接选项
//mysql数据库服务的dsn示例如下
$pdo = new \PDO('mysql:host=192.168.1.13;port=3306;dbname=roach;charset=utf8', 'roach', 'roach');

//开启事务
$pdo->beginTransaction();

try {
    $stmt = $pdo->prepare("INSERT INTO `t_user`(`user_name`,`true_name`,`add_time`) VALUES(:user_name, :true_name, :add_time)");
    $stmt->bindValue(':user_name', uniqid('u'), \PDO::PARAM_STR);
    $stmt->bindValue(':true_name', uniqid('t'), \PDO::PARAM_STR);
    $stmt->bindValue(':add_time', time(), \PDO::PARAM_INT);
    $stmt->execute();
    $userId = $pdo->lastInsertId();
    //仅用于演示
    if($userId % 2 === 0) {
        throw new \Exception('用户id不能为偶数');
    }

    //update
    $stmt = $pdo->prepare('UPDATE `t_user` SET `user_name`=:user_name WHERE id=:id');
    $stmt->bindValue(':user_name', 'pdo-msyql'.uniqid());
    $stmt->bindValue(':id', $userId, \PDO::PARAM_INT);
    $stmt->execute();

    //select
    $stmt = $pdo->prepare('SELECT * FROM `t_user` WHERE `id`=:id');
    $stmt->bindValue(':id', $userId, \PDO::PARAM_INT);
    $stmt->execute();

    //提交事务
    $pdo->commit();

    echo '刚刚插入并修改的记录为:'.json_encode($stmt->fetchAll(\PDO::FETCH_ASSOC), JSON_UNESCAPED_UNICODE).PHP_EOL;
}catch (\Exception $exception) {
    $pdo->rollBack();
    exit($exception->getMessage());
}
  • 注意:此处的try...catch是必须的,因为\PDO::ATTR_ERRMODE设置为\PDO::ERRMODE_EXCEPTION,当出现异常时会被catch捕捉到,并回滚事务。

学习更多内容: https://404.360tryst.com

我的视频课程: https://edu.csdn.net/course/detail/9933

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

pdo-mysql 的相关文章

随机推荐

  • 新产品开发之C流程 (C-flow)

    关于新产品开发的C流程 C flow xff0c 是世界上大公司采用的标准开发流程 xff0c 十分基本也十分重要 xff0c 但是网上关于C流程介绍相关的资料很少 xff0c 所以花点时间整理一下相关的资料 下面以软件BSP开发为例 xf
  • Arduino的Stepper库函数及其控制步进电机(ULN2003)调速

    问题来源 最近自学Arduino xff0c 在使用步进电机时开始没能使步进电机转起来 xff0c 转起来后感觉没法调速 xff0c 遂完成此篇笔记供自己后续查阅以及方便遇到相同问题的诸君寻找灵感 对于如何使步进电机转动就不详述 xff0c
  • 一、电脑端实现单片机与ESP8266的通信

    1 准备工具 xff08 硬件 软件 xff09 硬件 xff1a 51单片机开发板 ESP8266无线模块 xff08 ESP8266 01 xff09 TTL USB串口 杜邦线 数据线 xff1b 软件 xff1a keil uv4单
  • 错误 LNK2038 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“2”不匹配值“0”(main.obj 中)

    前言 vs2019报错如下图 xff1a 错误 LNK2038 检测到 ITERATOR DEBUG LEVEL 的不匹配项 值 2 不匹配值 0 main obj 中 错误原因 1 产生这个问题的原因是当前工程是Debug版本 xff0c
  • 三种获取字节码对象的方式及区别

    方式一 xff1a 对象 getClass 方法是 根对象Object的方法 是其他类继承Object的getClass方法 方式二 xff1a 类名 class xff0c 你可以理解为字节码本身就是静态的 xff0c 类加载的时字节码就
  • 关于接口与Object 类的关系

    看到这个标题 xff0c 你或许就会想好自己的那份答案 但事实上这个确实没有答案 xff0c 至少没官方证明它们之间的基友关系 看法一 xff1a 因为老师说 xff0c 你可以把接口看作是特殊的类 xff0c 所以不假思索的就认为接口也
  • 单词博弈Java实现(借鉴“miss若尘”博客中写的解题思路)

    单词博弈Java实现 xff0c 已经通过庞果网的用例测试 代码如下 import java util HashMap public class WordGameFinalTest public static int who String
  • 我的2013,梦在路上

    我的2013 xff0c 在路上 今年最后一次给姐姐打电话 xff0c 她在那里像我炫耀自己和爸爸妈妈一起跨年 xff0c 说1314的意义 xff0c 而我还在北京苦逼着 回想2013年对于我来说 xff0c 或许是不错的一年 这一年我进
  • mysql安装时的粗心错误:last error unable to update security settings. access denied for user 'root' @ 'localh

    来自 梦想家haima 39 s blog gt http blog dreamwe cn 这个报错出现在mysql最后 当你看到mysql的最后一步需要设置密码可能你开心得很 Mysql就快安装好了 赶快输入三行密码都是root 结果报下
  • @SuppressWarnings

    简介 xff1a java lang SuppressWarnings是J2SE 5 0中标准的Annotation之一 可以标注在类 字段 方法 参数 构造方法 xff0c 以及局部变量上 作用 xff1a 告诉编译器忽略指定的警告 xf
  • 欢迎使用CSDN-markdown编辑器

    欢迎使用Markdown编辑器写博客 本Markdown编辑器使用StackEdit修改而来 xff0c 用它写博客 xff0c 将会带来全新的体验哦 xff1a Markdown和扩展Markdown简洁的语法代码块高亮图片链接和图片上传
  • Linux之强大的awk

    来自 梦想家 Haima s blog gt http blog dreamwe cn awk简介 awk是Linux中的一个命令 xff0c 用来做文本处理与分析 xff0c 功能简单强悍 xff0c 同时它也是一门编程语言 awk处理文
  • ucos源码分析(一)

    时间 2018 01 27 本人目前是大三学生 电子信息工程专业 xff0c 在大学前俩年的时间 xff0c 一直在使用和学习单片机 xff0c 不过也仅仅是从 xff15 xff11 到 xff13 xff12 xff0c 马上要面临就业
  • 随笔——Python & C++ 混用——使用cmake生成c++动态库

    Python amp C 43 43 混用 xff0c 使用cmake 生成c 43 43 动态库 xff0c 可供python调用 说明 xff1a test cpp为源文件 add h为头文件 源文件使用第三方库opencv CMake
  • 机会都是留给有准备的人,你在准备什么?| 每天成就更大成功

    最近养成一个习惯 xff0c 就是每晚抄书 xff0c 大概200字左右 xff0c 在抄书的过程中反思了一个问题 xff1a 因为字写的不漂亮 xff0c 于是就在抄书的时候就有意的去练字 xff0c 这样抄书的精力就被分散了一部分出去
  • 《SQL Server 2005开发技术大全》分享一本书

    数据库是一个非常重要的领域 xff0c 不管是什么样的系统 xff0c 都必须要与数据库打交道 xff0c 因此作为一个程序员来讲 xff0c 数据库的基本知识技能是必须要掌握的 我接触C 已经有两年半的时间了吧 xff0c 在学习之初是接
  • golang语言rsa加解密及签名验签

    golang语言rsa加解密及签名验签 96 rsa 96 算法概述 96 Rsa 96 结构体封装封装的优点使用案例 rsa算法 概述 rsa是一种非对称的可逆的加密算法 xff0c 对加密数据长度有限制 xff0c 同时rsa也提供了数
  • 异常与错误处理

    异常与错误处理 PHP的异常与错误是分开的 xff0c 当程序出现异常时会throw一个 Exception 或子类 对象 xff0c 但是当出现错误时会触发一个错误 1 异常处理 1 1 通过try catch主动处理异常 span cl
  • 设计模式

    1 什么是模式 设计模式是对某些典型易变问题的特定解决方案 xff0c 这些问题和解决方案经过分类总结 xff0c 并且为了方便交流给每个解决方案都起了特定的名字 模式是为了解决变化的问题 xff0c 将变化的问题进行封装 xff0c 让变
  • pdo-mysql

    pdo mysql PHP连接数据库推荐使用PDO xff0c PDO扩展为PHP访问数据库定义了一个轻量级接口 我们可以通过实现PDO接口的每个数据库驱动来访问数据库服务 访问mysql数据库服务 xff0c 我们使用PDO MYSQL驱