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 的相关文章

  • 映射 mysql 中同一个表的多个值

    您好 我必须使用另一个表中的值 id 获取文本值 表 1 包含值 ID 表 2 包含名称和值 ID 表 1 SEVERITY OCCURENCE DETECTABILITY 2 3 4 表 2 id name value 1 Very Hi
  • 在 MySQL 中存储表情符号的编码问题:如何使用 Prisma ORM 在 NodeJS 中定义字符排序规则?

    亲爱的 Nodejs 专家和数据库专家 我们在 MySQL 数据库中存储表情符号和其他特殊字符时遇到问题 我们使用 Prisma 得到一个错误 这是我们使用的 ORM 参数无法从排序规则 utf8 general ci 转换为 utf8mb
  • POINT 列上的 MySQL INSERT/UPDATE

    我正在尝试用我国家的地理位置填充我的数据库 我的一张表有 4 个字段 ID PK 纬度 经度和地理点 EDIT SCDBs Punto Geografico SET lat 18 469692 SET lon 63 93212 SET g
  • MySql - 复制监控工具[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有一个主 从 MySql 复制 我正在寻找一个允许我监视复制的工具 查看它没有错误 检查滞后等 我更喜
  • Galera 集群问题

    我想在我们的生产环境中使用Galera集群 但我有一些顾虑 每个表必须至少定义一个显式主键 每个表必须运行在InnoDB或XtraDB存储引擎下 分批处理您的大额交易 例如 不要让一个事务插入 100 000 行 而是将其分成更小的块 例如
  • 在 C# 中,当有人插入、删除或修改记录时,如何从 MySQL 获取事件?

    我正在 WPF Net 中开发一个程序 我需要知道何时有人对数据库的任何表进行更改 这个想法是在数据库发生更改时从数据库接收一个事件 我读了很多文章 但找不到解决我的问题的方法 亲切的问候 最好的解决方案是使用消息队列 在您的应用程序向数据
  • 连接 Netbeans 和 MySQL 但出现大整数错误

    所以我正在尝试向我的 Netbeans 数据库 即 MySQL 添加新连接 但我遇到了大整数转换错误 有人可以帮助我吗 详细地 我右键单击现有的MySQL 服务器位于 localhost 3306 root 已断开连接 gt gt 选择co
  • 如何优化这个MySQL慢(非常慢)查询?

    我有一个 2 GB 的 mysql 表 包含 500k 行 我在没有负载的系统上运行以下查询 select from mytable where name in n1 n2 n3 n4 bunch more order by salary
  • MySQL 通过 current_timestamp 选择上个月的数据

    直到今天 当我使用 MySQL 并需要对日期 时间执行操作时 我使用带有 unix 时间戳的 int 列 没有出现任何问题 但今天在阅读了一些指南后 我决定默认使用 current timestamp 测试时间戳列 所以我感兴趣如何按列选择
  • PHP PDO 使用 bindParam 第一个参数(不带冒号)[重复]

    这个问题在这里已经有答案了 请检查这个 user id int GET user id sql DELETE FROM users WHERE user id user id query db gt prepare sql query gt
  • SQL Join 列上类似于另一列[重复]

    这个问题在这里已经有答案了 可能的重复 mysql连接查询使用like https stackoverflow com questions 1930809 mysql join query using like 我想要进行连接 其中一列包含
  • 什么时候应该使用 C++ 而不是 SQL?

    我是一名 C 程序员 偶尔使用 MySQL 来处理数据库 但我的 SQL 知识相当有限 但我肯定愿意改变这一点 目前 我正在尝试仅使用 SQL 查询对数据库中的数据进行分析 但我准备放弃了 转而将数据导入到C 中 用C 代码进行分析 我和同
  • 慢速自动增量重置

    我有很多表 由于某些原因 我需要在应用程序启动时调整这些表的自动增量值 我尝试这样做 mysql gt select max id from item max id 97972232 1 row in set 0 05 sec mysql
  • 非常大的字段会对 MySQL 数据库产生负面影响吗?

    我目前正在使用 Django 构建一个网站 并希望托管用户生物样式页面 该页面可能长达几 KB 这些字段不一定需要搜索 但在查找用户名时确实需要提供 将这些数据存储在数据库中会产生负面影响吗 如果我使用带有数据库链接的静态文本文件 我的服务
  • PHP MySql 百分比

    我的问题是关于百分比 我不是专家 所以我会尽力以更好的方式进行解释 我的 mysql 服务器中有一个表 假设有 700 条记录 如下所示 Name country language Birth Lucy UK EN 1980 Mari Ca
  • PHP MySQL 使用选项/选择 HTML 表单标签进行多重搜索查询

    我正在尝试使用两个搜索字段设置基本的 MySQL LIKE 搜索 我不想拥有它 所以它有多个可选搜索字段 例如if isset POST city isset POST name 我不知道如何用 HTML 来做到这一点
  • 删除行导致锁超时

    当我尝试从表中删除行时 我不断收到这些错误 这里的特殊情况是我可能同时运行5个进程 该表本身是一个 Innodb 表 约有 450 万行 我的 WHERE 子句中使用的列没有索引 其他指数按预期运行 这是在事务中完成的 首先删除记录 然后插
  • PHP 与 MySQL 查询性能( if 、 函数 )

    我只看到这个artice http www onextrapixel com 2010 06 23 mysql has functions part 5 php vs mysql performance 我需要知道在这种情况下什么是最好的表
  • SQL 最近日期

    我需要在 php 中获取诸如 2010 04 27 之类的日期作为字符串 并在表中找到最近的 5 个日期 表中的日期保存为日期类型 您可以使用DATEDIFF http dev mysql com doc refman 5 1 en dat
  • 内部 while 循环不工作

    这是我项目网页上的代码片段 这里我想显示用户选择的类别 然后想显示属于该类别的主题 在那里 用户可以拥有多个类别 这没有问题 我可以在第一个 while 循环中打印所有这些类别 问题是当我尝试打印主题时 结果只显示一行 但每个类别中有更多主

随机推荐

  • 单词博弈Java实现(借鉴“miss若尘”博客中写的解题思路)

    单词博弈Java实现 xff0c 已经通过庞果网的用例测试 代码如下 import java util HashMap public class WordGameFinalTest public static int who String
  • 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处理文
  • 手机抓包charles使用

    使用的是charles window 之前使过fiddler但是感觉并没有charles好用以及一目了然 链接 https pan baidu com s 1NMNXa8M4niLObQKIsCNL3A 提取码 2wsa 安装包可以通过连接
  • 安卓Tinker热更新接入踩坑(minSdkVersion 21)

    哎哟 xff0c 这个坑啊 我项目采用的是ARouter 43 Tinker 我接入的是tinkerpathchttp www tinkerpatch com Docs intro按照文档对接 xff0c 我采用的是reflectAppli
  • Android 解压和重新打包system.img

    开始我们的工作前 xff0c 请记住 xff0c Linux一定要学会用file命令分析文件类型 xff0c 这样才好入手 xff0c 否则错了都不知道怎么回事 xff01 xff01 xff01 1 解压system img 先用file
  • Jetpack系列学习笔记整理一 之LifeCycles

    学习最好的途径就是官网和github Demo xff0c 先放链接 xff0c 想看自行跳转 xff1a 官网 xff1a https developer android com topic libraries architecture
  • 获取安卓位置信息

    别忘了添加权限 xff1a lt uses permission android name 61 34 android permission INTERNET 34 gt lt uses permission android name 61
  • 安卓与html混合开发之原生与js相互调用

    原生和html的优缺点就不多说了 xff0c 有些特定条件下用html页面可以很方便 xff0c 也很容易更新和维护 xff0c 那么这就涉及到html与安卓原生的交互和通信 接下来我要分享的是html调用原生的弹窗和位置信息 xff0c
  • 应用保活--杀死进程也能收到推送消息

    我选取的是极光推送 xff0c 当把进程杀死时候就接受不到推送过来的消息 这是因为我使用的是小米手机 xff0c 小米和华为手机属于那种深度定制安卓系统 xff0c 需要用户的操作才能够实现应用 保活 的目的 小米 MIUI 自启动管理 x
  • 安卓原生与vue前段相互调用

    之前写过一个博客是安卓原生与JS交互的博客 xff1a http blog csdn net jhl122 article details 53406623 那是正常情况下的交互 xff0c 但是如果前段人员使用vue开发就会产生一个问题
  • CMake 编译时报错 ninja: error: ......missing and no known rule to make it

    Build command failed Error while executing process F Android sdk cmake 3 6 4111459 bin cmake exe with arguments build E
  • 数据类型和Json格式

    1 前几天 xff0c 我才知道有一种简化的数据交换格式 xff0c 叫做yaml 我翻了一遍它的文档 xff0c 看懂的地方不多 xff0c 但是有一句话令我茅塞顿开 它说 xff0c 从结构上看 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 让变
  • 最新完美解决Python第三方库安装出现Microsoft Visual C++ 14.0 is required的问题

    安装库出现报错 xff1a Microsoft Visual 14 0 or greater is required 怎么办 xff1f 使用Python下载第三方库 xff0c pip也更新了 xff0c 镜像也使用了 xff0c 网络也
  • pdo-mysql

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