介绍
使用mysql_扩展的日子已经过去了,因为自PHP 5.5以来它的方法已被弃用,并且从PHP 7开始被删除。但是互联网上仍然充斥着大量的旧教程,初学者只需复制/粘贴并在共享主机平台上使用旧版本的PHP即可。
如果你在PHP中使用MySQL或MariaDB,那么你现在可以选择MySQLi或PDO。前者只是一个改进版本,支持过程化和OOP,并添加了预处理语句,而后者是一个抽象层,允许你为它支持的所有12个数据库驱动程序使用统一的API。尽管MySQL是PHP世界中最流行的数据库。
理论上,我们不需要为存在的每种数据库类型都提供特定于供应商的API,因为只使用一种数据库要简单得多。虽然对此肯定有很多道理,但问题是PDO_MYSQL并没有MySQLi所具有的所有最新和最先进的特性。老实说,我不明白为什么会这样,因为这将完全消除使用特定于供应商的API的任何理由。尽管如此,我想大多数人并不需要这些额外的功能,但肯定有一些人需要。
PDO的优势
1.有用的获取方式
2.允许直接将变量和值传递给execute
3.能够自动检测变量类型(实际发生的情况是,发送到服务器时,所有内容都被视为字符串,但被转换为正确的类型。这在预处理语句中100%有效,但在某些边缘情况下无效,比如在模拟模式中。)
4.提供一个选项,使用预处理语句自动缓冲结果
5.命名参数(尽管在PDO中关闭模拟模式是无用的,因为你只能使用相同的名称一次)
MySQLi优势
1.异步查询
2.获取有关受影响行的更多信息的能力,比如更新具有相同值的行(可以在PDO中作为构造函数设置完成,以后无法更改)
3.正确的数据库关闭方法
4.一次多个查询(如果在PDO中打开模拟模式,则可以)
5.使用持久连接自动清除
代码的差异
PDO和MySQLi非常相似,但是在语法上略有不同。MySQLi遵循旧式的PHP snake_case约定,而PDO使用camelCase。此外,MySQLi的方法被用作对象属性,而PDO对函数使用传统语法。
PDO和MySQLi都要求你使用两个单独的方法来使用预处理语句,从而使事情变得复杂。不过PDO消除了使用专用绑定函数的需要。
例如,在特定于供应商的PostgreSQL API中,你可以这样做。
下面是一个示例,演示如何执行一个“non-prepared”查询来获取一个包含MySQLi和PDO的关联数组,以供参考。
$arr = $mysqli->query("SELECT * FROM myTable")->fetch_all(MYSQLI_ASSOC);
$arr = $pdo->query("SELECT * FROM myTable")->fetchAll(PDO::FETCH_ASSOC);
实际上,最好的方法是使用包装器、查询生成器或ORM。虽然PDO可以直接将值绑定到execute中,但它仍然不是理想的。在我创建的类中,你可以链接所有调用,同时传入值作为参数参数绑定。
$arr = $mysqli->query("SELECT * FROM myTable WHERE id > ?", [12])->fetchAll('assoc');
现在,在变量中以更简洁的方式存储了整个关联数组。
创建一个新的数据库连接
PDO
$dsn = "mysql:host=localhost;dbname=myDatabase;charset=utf8mb4";$options = [ PDO::ATTR_EMULATE_PREPARES => false, // turn off emulation mode for "real" prepared statements PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, //turn on errors in the form of exceptions PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, //make the default fetch be an associative array];try { $pdo = new PDO($dsn, "username", "password", $options);} catch (Exception $e) { error_log($e->getMessage()); exit('Something weird happened'); //something a user can understand}
MySQLi
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);try { $mysqli = new mysqli("localhost", "username", "password", "databaseName"); $mysqli->set_charset("utf8mb4");} catch(Exception $e) { error_log($e->getMessage()); exit('Error connecting to database'); //Should be a message a typical user could understand}
插入、更新、删除
PDO
$stmt = $pdo->prepare("INSERT INTO myTable (name, age) VALUES (?, ?)"); $stmt->execute([$_POST['name'], 29]); $stmt = null;
MySQLi
$stmt = $mysqli->prepare("UPDATE myTable SET name = ? WHERE id = ?"); $stmt->bind_param("si", $_POST['name'], $_SESSION['id']); $stmt->execute(); $stmt->close();
注意,使用PDO可以将prepare()和execute()链接起来。
获取受影响的行数
PDO
$stmt->rowCount();
MySQLi
$stmt->affected_rows;
插入最新的主键
注意,这两种方法都使用connection变量,而不是$stmt。
PDO
$pdo->lastInsertId();
MySQLi
$mysqli->insert_id;
得到匹配的行
PDO
在PDO中,实现这一点的唯一方法是将其设置为一个连接选项,以更改rowCount()的行为。这意味着rowCount()将为整个数据库连接返回匹配的行或更改的行,但不能同时返回两者。
$options = [ PDO::MYSQL_ATTR_FOUND_ROWS => true];
MySQLi
$mysqli->info;
这将输出整个字符串的信息,如:
Rows matched: 1 Changed: 0 Warnings: 0
可以这样做
preg_match_all('/(\S[^:]+): (\d+)/', $mysqli->info, $matches); $infoArr = array_combine ($matches[1], $matches[2]); var_export($infoArr);
现在可以很容易地访问这些值。注意,该值是一个字符串,因此你可以将所有值转换为int,===可以使用,也可以严格检查==。
['Rows matched' => '1', 'Changed' => '0', 'Warnings' => '0']
抓取
获取关联数组
PDO
$stmt = $pdo->prepare("SELECT * FROM myTable WHERE id <= ?"); $stmt->execute([5]); $arr = $stmt->fetchAll(PDO::FETCH_ASSOC); if(!$arr) exit('No rows'); var_export($arr); $stmt = null;
MySQLi
$stmt = $mysqli->prepare("SELECT id, name, age FROM myTable WHERE name = ?"); $stmt->bind_param("s", $_POST['name']); $stmt->execute(); $arr = $stmt->get_result()->fetch_all(MYSQLI_ASSOC); if(!$arr) exit('No rows'); var_export($arr); $stmt->close();
获取单行
PDO
$stmt = $pdo->prepare("SELECT id, name, age FROM myTable WHERE name = ?"); $stmt->execute([$_POST['name']]); $arr = $stmt->fetch(PDO::FETCH_ASSOC); if(!$arr) exit('No rows'); var_export($arr); $stmt = null;
MySQLi
$stmt = $mysqli->prepare("SELECT id, name, age FROM myTable WHERE name = ?"); $stmt->bind_param("s", $_POST['name']); $stmt->execute(); $arr = $stmt->get_result()->fetch_assoc(); if(!$arr) exit('No rows'); var_export($arr); $stmt->close();
获取单个值(标量)
PDO
$stmt = $pdo->prepare("SELECT id, name, age FROM myTable WHERE name = ?"); $stmt->execute([$_POST['name']]); $arr = $stmt->fetch(PDO::FETCH_COLUMN); if(!$arr) exit('No rows'); var_export($arr); $stmt = null;
MySQLi
$stmt = $mysqli->prepare("SELECT id, name, age FROM myTable WHERE name = ?"); $stmt->bind_param("s", $_POST['name']); $stmt->execute(); $arr = $stmt->get_result()->fetch_row()[0]; if(!$arr) exit('No rows'); var_export($arr); $stmt->close();
获取对象数组
PDO
class myClass {} $stmt = $pdo->prepare("SELECT name, age, weight FROM myTable WHERE name = ?"); $stmt->execute(['Joe']); $arr = $stmt->fetchAll(PDO::FETCH_CLASS, 'myClass'); if(!$arr) exit('No rows'); var_export($arr); $stmt = null;
MySQLi
class myClass {} $arr = []; $stmt = $mysqli->prepare("SELECT id, name, age FROM myTable WHERE id = ?"); $stmt->bind_param("s", $_SESSION['id']); $stmt->execute(); $result = $stmt->get_result(); while($row = $result->fetch_object('myClass')) { $arr[] = $row; } if(!$arr) exit('No rows'); var_export($arr); $stmt->close();
正如你所看到的,PDO在这里非常出色。MySQLi没有像$mysqli_result->fetch_all(MYSQLI_OBJ)这样的东西。PDO甚至更进一步,通过使用fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'myClass')对它进行位元化,以处理在类构造函数之后调用它的默认行为。可以在MySQLi中复制这种行为,但是它依赖于省略构造函数,和魔术方法 _set(),或者只在构造函数中设置它(如果它不等于默认值)。
PDO
$search = "%{$_POST['search']}%"; $stmt = $pdo->prepare("SELECT id, name, age FROM myTable WHERE name LIKE ?"); $stmt->execute([$search]); $arr = $stmt->fetchAll(); if(!$arr) exit('No rows'); var_export($arr); $stmt = null; Copy
MySQLi
$search = "%{$_POST['search']}%"; $stmt = $mysqli->prepare("SELECT id, name, age FROM myTable WHERE name LIKE ?"); $stmt->bind_param("s", $search); $stmt->execute(); $arr = $stmt->get_result()->fetch_all(MYSQLI_ASSOC); if(!$arr) exit('No rows'); var_export($arr); $stmt->close();
获取模式
到目前为止,这是我最喜欢的PDO特性。PDO中的获取模式非常有用,而MySQLi还没有添加它们。
获取键/值对
PDO
$stmt = $pdo->prepare("SELECT event_name, location FROM events WHERE id < ?"); $stmt->execute([25]); $arr = $stmt->fetchAll(PDO::FETCH_KEY_PAIR); if(!$arr) exit('No rows'); var_export($arr); $stmt = null; Copy
MySQLi
$arr = []; $id = 25; $stmt = $con->prepare("SELECT event_name, location FROM events WHERE id < ?"); $stmt->bind_param("i", $id); $stmt->execute(); $result = $stmt->get_result(); while($row = $result->fetch_row()) { $arr[$row[0]] = $row[1]; } if(!$arr) exit('No rows'); var_export($arr); $stmt->close();
输出:
['Cool Event' => 'Seattle', 'Fun Event' => 'Dallas', 'Boring Event' => 'Chicago']
获取组列
PDO
$stmt = $pdo->prepare("SELECT hair_color, name FROM myTable WHERE id < ?"); $stmt->execute([10]); $arr = $stmt->fetchAll(PDO::FETCH_GROUP | PDO::FETCH_COLUMN); if(!$arr) exit('No rows'); var_export($arr); $stmt = null; Copy
MySQLi
$arr = []; $id = 10; $stmt = $con->prepare("SELECT hair_color, name FROM myTable WHERE id < ?"); $stmt->bind_param("i", $id); $stmt->execute(); $result = $stmt->get_result(); while($row = $result->fetch_row()) { $arr[$row[0]][] = $row[1]; } if(!$arr) exit('No rows'); var_export($arr); $stmt->close(); Copy
输出:
[ 'blonde' => ['Patrick', 'Olivia'], 'brunette' => ['Kyle', 'Ricky'], 'red' => ['Jordan', 'Eric'] ]
获取键/值对数组
PDO
$stmt = $pdo->prepare("SELECT id, max_bench, max_squat FROM myTable WHERE weight < ?"); $stmt->execute([200]); $arr = $stmt->fetchAll(PDO::FETCH_UNIQUE); if(!$arr) exit('No rows'); var_export($arr); $stmt = null; Copy
MySQLi
$arr = []; $weight = 200; $stmt = $con->prepare("SELECT id, max_bench, max_squat FROM myTable WHERE weight < ?"); $stmt->bind_param("i", $weight); $stmt->execute(); $result = $stmt->get_result(); $firstColName = $result->fetch_field_direct(0)->name; while($row = $stmtResult->fetch_assoc()) { $firstColVal = $row[$firstColName]; unset($row[$firstColName]); $arr[$firstColVal] = $row; } if(!$arr) exit('No rows'); var_export($arr); $stmt->close(); Copy
输出:
[ 17 => ['max_bench' => 230, 'max_squat' => 175], 84 => ['max_bench' => 195, 'max_squat' => 235], 136 => ['max_bench' => 135, 'max_squat' => 285] ]
获取组
PDO
$stmt = $pdo->prepare("SELECT hair_color, name, age FROM myTable WHERE id < ?"); $stmt->execute([12]); $arr = $stmt->fetchAll(PDO::FETCH_GROUP); if(!$arr) exit('No rows'); var_export($arr); $stmt = null; Copy
MySQLi
$arr = []; $id = 12; $stmt = $con->prepare("SELECT hair_color, name, age FROM myTable WHERE id < ?"); $stmt->bind_param("i", $id); $stmt->execute(); $result = $stmt->get_result(); $firstColName = $result->fetch_field_direct(0)->name; while($row = $stmtResult->fetch_assoc()) { $firstColVal = $row[$firstColName]; unset($row[$firstColName]); $arr[$firstColVal][] = $row; } if(!$arr) exit('No rows'); var_export($arr); $stmt->close(); Copy
输出:
[ 'blonde' => [ ['name' => 'Patrick', 'age' => 22], ['name' => 'Olivia', 'age' => 18] ], 'brunette' => [ ['name' => 'Kyle', 'age'=> 25], ['name' => 'Ricky', 'age' => 34] ], 'red' => [ ['name' => 'Jordan', 'age' => 17], ['name' => 'Eric', 'age' => 52] ] ]
在数组中的位置
PDO
$inArr = [1, 3, 5]; $clause = implode(',', array_fill(0, count($inArr), '?')); $stmt = $pdo->prepare("SELECT * FROM myTable WHERE id IN ($clause)"); $stmt->execute($inArr); $resArr = $stmt->fetchAll(); if(!$resArr) exit('No rows'); var_export($resArr); $stmt = null; Copy
MySQLi
$inArr = [12, 23, 44]; $clause = implode(',', array_fill(0, count($inArr), '?')); / $types = str_repeat('i', count($inArr)); / $stmt = $mysqli->prepare("SELECT id, name FROM myTable WHERE id IN ($clause)"); $stmt->bind_param($types, ...$inArr); $stmt->execute(); $resArr = $stmt->get_result()->fetch_all(MYSQLI_ASSOC); if(!$resArr) exit('No rows'); var_export($resArr); $stmt->close();
与其他占位符一起排列的位置
PDO
$inArr = [1, 3, 5]; $clause = implode(',', array_fill(0, count($inArr), '?')); $stmt = $pdo->prepare("SELECT * FROM myTable WHERE id IN ($clause) AND id < ?"); $fullArr = array_merge($inArr, [5]); $stmt->execute($fullArr); $resArr = $stmt->fetchAll(); if(!$resArr) exit('No rows'); var_export($resArr); $stmt = null; Copy
MySQLi
$inArr = [12, 23, 44]; $clause = implode(',', array_fill(0, count($inArr), '?')); $types = str_repeat('i', count($inArr)); $types .= 'i'; //add 1 more int type $fullArr = array_merge($inArr, [26]); $stmt = $mysqli->prepare("SELECT id, name FROM myTable WHERE id IN ($clause) AND age > ?"); $stmt->bind_param($types, ...$fullArr); $stmt->execute(); $resArr = $stmt->get_result()->fetch_all(MYSQLI_ASSOC); if(!$resArr) exit('No rows'); var_export($resArr); $stmt->close();
交易
PDO
try { $pdo->beginTransaction(); $stmt1 = $pdo->prepare("INSERT INTO myTable (name, state) VALUES (?, ?)"); $stmt2 = $pdo->prepare("UPDATE myTable SET age = ? WHERE id = ?"); if(!$stmt1->execute(['Rick', 'NY'])) throw new Exception('Stmt 1 Failed'); else if(!$stmt2->execute([27, 139])) throw new Exception('Stmt 2 Failed'); $stmt1 = null; $stmt2 = null; $pdo->commit(); } catch(Exception $e) { $pdo->rollback(); throw $e; }
MySQLi
try { $mysqli->autocommit(FALSE); $stmt1 = $mysqli->prepare("INSERT INTO myTable (name, age) VALUES (?, ?)"); $stmt2 = $mysqli->prepare("UPDATE myTable SET name = ? WHERE id = ?"); $stmt1->bind_param("si", $_POST['name'], $_POST['age']); $stmt2->bind_param("si", $_POST['name'], $_SESSION['id']); $stmt1->execute(); $stmt2->execute(); $stmt1->close(); $stmt2->close(); $mysqli->autocommit(TRUE); } catch(Exception $e) { $mysqli->rollback(); throw $e; }
MySQLi有一个问题,但是解决方案是使用全局处理程序将错误转换为异常。
命名为Paramters
$stmt = $pdo->prepare("UPDATE myTable SET name = :name WHERE id = :id"); $stmt->execute([':name' => 'David', ':id' => 3]); $stmt = null;
以上是PDO与MySQLi:PHP数据库API之战的详细内容。更多信息请关注PHP中文网其他相关文章!

PHP作为一种流行的Web开发语言,已经被使用了很长时间。PHP中集成的PDO(PHP数据对象)类是我们在开发Web应用程序过程中与数据库进行交互的一种常用方法。但是,一些PHP开发者经常遇到的问题是,当使用PDO类与数据库进行交互时,他们会收到这样的错误:PHPFatalerror:CalltoundefinedmethodPDO::prep

PHP作为一种流行的编程语言,在Web开发领域中有着广泛的应用。其中,PHP的PDO_PGSQL扩展是一种常用的PHP扩展,它提供了与PostgreSQL数据库的交互接口,可以实现PHP与PostgreSQL之间的数据传输和交互。本文将详细介绍如何使用PHP的PDO_PGSQL扩展。一、什么是PDO_PGSQL扩展?PDO_PGSQL是PHP的一个扩展库,它

PHP和PDO:如何执行批量插入和更新导言:在使用PHP编写数据库相关的应用程序时,经常会遇到需要批量插入和更新数据的情况。传统的做法是使用循环来执行多次数据库操作,但这样的方法效率较低。PHP的PDO(PHPDataObject)提供了一种更高效的方法来执行批量插入和更新操作,本文将介绍如何使用PDO来实现批量插入和更新。一、PDO简介:PDO是PH

PHP和PDO:如何处理数据库中的JSON数据在现代web开发中,处理和存储大量数据是一个非常重要的任务。随着移动应用和云计算的普及,越来越多的数据以JSON(JavaScriptObjectNotation)格式存储在数据库中。PHP作为一种常用的服务器端语言,它的PDO(PHPDataObject)扩展提供了一种方便的方式来处理和操作数据库。本

PHP和PDO:如何进行分页查询和显示数据在开发Web应用程序时,分页查询和显示数据是一个非常常见的需求。通过分页,我们可以一次显示一定数量的数据,提高页面加载速度和用户体验。在PHP中,使用PHP数据对象(PDO)库可以轻松实现分页查询和显示数据的功能。本文将介绍如何在PHP中使用PDO进行分页查询和显示数据,并提供相应的代码示例。一、创建数据库和数据表

如何使用PDO连接到Redis数据库Redis是一个开源的高性能、内存存储的键值数据库,常用于缓存、队列等场景。在PHP开发中,使用Redis可以有效提升应用的性能和稳定性。而通过PDO(PHPDataObjects)扩展,我们可以更方便地连接和操作Redis数据库。本文将介绍如何使用PDO连接到Redis数据库,并附带代码示例。安装Redis扩展在开始

PHP和PDO:如何执行数据库备份和还原操作在开发Web应用程序时,数据库的备份和还原是非常重要的任务。PHP作为一门流行的服务器端脚本语言,提供了丰富的库和扩展,其中PDO(PHP数据对象)是一款强大的数据库访问抽象层。本文将介绍如何使用PHP和PDO来执行数据库备份和还原操作。第一步:连接数据库在实际操作之前,我们需要建立与数据库的连接。使用PDO对

如何使用PDO绑定和获取绑定参数值在开发Web应用程序时,处理数据库查询是很常见的任务之一。为了保证应用程序的安全性和可靠性,我们应该使用参数绑定来处理SQL查询,而不是直接将变量值插入SQL语句中。PDO(PHP数据对象)提供了一种方便且安全的方式来绑定参数和获取绑定参数的值。下面,我们将介绍如何使用PDO进行参数绑定和获取绑定参数的


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

SublimeText3汉化版
中文版,非常好用

Dreamweaver Mac版
视觉化网页开发工具

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

安全考试浏览器
Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。