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

  • 如何在php中正确显示另一种语言的mysql表数据

    我有一个 mySQL 表 其中一列中的数据采用英语以外的语言 波斯语 当我在表中输入数据时 它会正确显示 但是当我想在 php 文件中显示数据时 它会显示如下 好吧 我应该怎么做才能以正确的形式显示数据 由于我经常使用 非英语 字符 因此要
  • PHP实现的机票预订系统

    如何防止预订系统中的座位被重复预订 我正在用 PHP 和 MYSQL 制作一个航空旅行预订系统模型作为一个项目 我有一个小问题 仅在付款后 门票和座位详细信息才会永久存储在此处 座位号在付款前分配 假设人 1 预订了飞机上的座位 x 并支付
  • grails/mysql 时区更改

    完成更改应用程序时区的最佳方法是什么 在我看来 必须发生以下情况 服务器 TZ 已被系统管理员更改 mysql必须重新启动 数据库中每个基于时间的列都必须使用convert tz 或等效方法更新所有值 因此 要么必须编写一个 mysql 脚
  • 数据库中的持久日期不等于检索日期

    我有一个具有 Date 属性的简单实体类 此属性对应于 MySQL 日期时间列 Entity public class Entity Column name start date Temporal TemporalType TIMESTAM
  • #1115 - 未知字符集:'utf8mb4'

    我的电脑上运行着一个本地网络服务器 用于本地开发 我现在正处于导出数据库并导入到我的托管 VPS 的阶段 导出然后导入时出现以下错误 1115 未知字符集 utf8mb4 有人能指出我正确的方向吗 该错误明确表明您没有utf8mb4您的阶段
  • 无法删除数据库 mysql:错误 3664 (HY000)

    我的应用程序中有一个名为X Files 我想要drop它 但每当我运行命令时drop database X Files我收到以下错误 mysql gt drop database X Files ERROR 3664 HY000 Faile
  • MySQL 帮助:如何查找客户的所有订单,直到价格 <= 20 且状态='未付款'

    我认为通过提供以下示例可以更好地理解我的问题 我有一个包含以下数据的表 orderid Price username paymentstatus 1 10 john unpaid 2 10 john unpaid 4 10 john unp
  • 如何检查 $row['column_name'] 是否返回空 php mysql

    我有一个带有列的表格 id name phone describe 当我从这个表中获取值时 我正在使用 row mysql fetch array query 现在我想检查是否 row describe 返回空值 如何查看php 您可以使用
  • 日志中每天的每周活跃用户数

    我想知道是否有人可以帮助我使用一些 SQL 来返回两天或更长时间内登录到数据库表的唯一用户数量 让我们使用 7 天作为参考 我的日志表在每一行中包含时间戳 ts 和 user id 表示该用户当时的活动 以下查询返回此日志中的每日活跃用户数
  • 如何在php中根据url从mysql获取数据?

    我在 mysql 数据库中有一个页表 其中包含 page name title content author 字段 我想用 php 来获取它http www domain com index php page page name http
  • 数据库级别的别名列名 [MySQL]

    别名 可能是错误的词 因为它是在将列 表名称作为查询中的其他名称引用的上下文中使用的 我感兴趣的是是否有一种方法可以在数据库中为列指定两个名称 如果我要打印这样的表格 它看起来会是这样的 mysql gt SELECT FROM User
  • 使用数据库进行日志记录

    大多数日志似乎都是纯文本形式 而不是放入 MySQL 其他类型的数据库中 这是否有原因 在我看来 将它们放入数据库将使分析变得非常非常容易 但这会以牺牲速度还是其他什么为代价 我不太关心可移植性 显然你会有数据库连接的文本日志 我能想到两大
  • php无法在docker-compose中连接到mysql

    这是我的 docker compose version 2 services nginx image nginx 1 11 8 alpine ports 8081 80 volumes code usr share nginx html h
  • 更新 SQLAlchemy 中的特定行

    我将 SQLAlchemy 与 python 一起使用 我想更新表中等于此查询的特定行 UPDATE User SET name user WHERE id 3 我通过 sql alchemy 编写了这段代码 但它不起作用 session
  • mysql 数据库正在复制,但在主服务器上创建的用户未在从服务器上复制

    在主从复制中 我们使用 mysql DB 在从服务器上复制少量数据库 我在主服务器上创建了一个用户 不幸的是它没有在从服务器上复制 Replicate Do DB app1 app2 mysql 用户创建命令 GRANT SELECT on
  • R:ifelse 中的字符串列表

    我正在寻找与 MySQL 中的 where var in 语句类似的东西 我的代码如下 data lt data frame id 10001 10030 cc1 rep c a b c 10 attach data data new lt
  • 拉拉维尔; “SQLSTATE[HY000] [2002] 连接被拒绝”

    我在 OSX 主机上设置了 homestead 2 0 并使用 Sequel Pro 我可以进行迁移并确认数据已在Sequel Pro中迁移 因此看起来数据库连接没有问题 但是 一旦我尝试从 Laravel 4 2 应用程序获取数据 它就无
  • MySQL:所有表都正常,但仍然错误 1577(发现事件调度程序使用的系统表已损坏)

    从我的系统日志 mysql 1663 ERROR 1577 HY000 at line 1 Cannot proceed because system tables used by Event Scheduler were found da
  • 打印表数据mysql php

    我在尝试打印表格的一些数据时遇到问题 我是 php mysql 的新手 但我认为我的代码是正确的 这里是 h1 Lista de usu rios h1
  • MYSQL 的 Google OAuth 2.0 用户 ID 数据类型

    我正在实施 Google OAuth 2 0 并注意到 Google OAuth 返回的唯一用户 ID 是21位数字长的 我想大整数 20 足以满足这种需求 但我现在看到 Google OAuth 返回的用户 ID 的长度感到困惑 关于我应

随机推荐

  • 单词博弈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驱