MySQL、MySQLi 和 PDO 之间有什么区别?
要了解 MySQL、MySQLi 和 PDO 之间的区别,我们必须分别了解它们中的每一个。
这些只不过是用于访问 MySQL 数据库和表的PHP API。开发人员可以为他们的项目选择其中之一,但是,必须知道 MySQLi 不能与PHP 7 及其更新版本一起使用。但是,开发人员可以将 MySQLi 与PHP 5 一起使用,该版本现已弃用。
让我们了解更多关于它们的信息:
- MySQL:这是旨在帮助PHP应用程序从 MySQL 数据库发送和接收数据的主要扩展。但是,从PHP 7 及其更新版本开始,不推荐使用并删除 MySQL。这就是为什么不推荐在新项目中使用它的原因,这也是为什么现在更多地使用 MySQLi 和 PDO 扩展的原因。
- MySQLi:MySQLi 中的“i”代表已改进。因此,这也称为 MySQL 的改进版本。它具有许多新功能,将在本文后面介绍。
- PDO – PHP数据对象:使用 PDO 的主要优点是它支持并提供了访问 11 种不同数据库的统一方法。
PDO 支持的数据库有:
- CUBRID
- 微软 SQL 服务器
- 火鸟/Interbase
- IBM
- Informix
- MySQL
- 甲骨文
- ODBC 和 DB2
- PostgreSQL
- SQLite
- 4D
但是,PDO 不允许使用当前版本的 MySQL 服务器中可用的所有功能。例如,PDO 不允许支持 MySQL 的多条语句。
比较 MySQL、MySQLi 和 PDO:
- 连接到数据库
- 错误处理
- 数据获取
- API 支持
- 安全
与数据库的连接:
- MySQL:连接数据库的MySQL代码为:
- MySQLi:在MySQLi 的情况下,只有一行代码。用户使用用户名、密码和数据库名称实例化 MySQLi 实例。
- PDO:在PDO 的情况下,必须创建一个新的 PDO 对象。
使用 PDO 的一大优势是它可以更简单地将项目切换到另一个数据库。因此,唯一要做的就是更改连接字符串和新数据库不支持的那些查询。
错误处理:错误处理是检测和解决应用程序、编程或通信错误。错误处理有助于维持程序执行的正常流程,因为程序中的错误被优雅地处理,从而使程序运行良好。
- MySQL:
'die' 方法用于 MySQL 中的错误处理,但它不被认为是错误处理的好方法。这是因为 die 会突然结束脚本,然后在屏幕上显示错误。这会使数据库容易受到黑客攻击。
- MySQLi:MySQLi 中的错误处理更容易一些。 mysqli::$error (mysqli_error) 返回最后一个错误的字符串描述。
query("SET a=1")) { printf("Errormessage: %s\n", $mysqli->error); } ?>
- PDO: PDO 具有这三种中最好的错误处理方法。这是因为 try-catch 块的可用性。此外,还有一些错误模式可用于错误处理。
- PDO::ERRMODE_SILENT:用于检查每个结果,然后检查 $db->errorInfo() 以获取错误详细信息。
- PDO::ERRMODE_WARNING:警告不会停止脚本。这提供了运行时警告而不是致命错误。
- PDO::ERRMODE_EXCEPTION:它抛出异常,显示 PDO 引发的错误。它不应该在您的代码中抛出 PDOException。当它没有被捕获时,它的行为很像 or die(mysql_error()) 。但是它可以捕获这些 PDOException 并根据需要进行处理。
我们可以设置这些错误模式如下:
setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT ); $db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING ); $db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); ?>
现在,可以按如下方式添加 try/catch 方法:
query('hello'); } catch (PDOException $ex) { // $ex->getMessage(); // Message to be displayed in // case of such an error echo "An Error has occurred"; } ?>
使用 try/catch 方法的一个优点是我们可以设置显示给用户的正常错误消息,而不是异常消息,因为一般用户可能难以理解。
数据获取:
- MySQL:通用编程循环,例如 for 或 while 循环可用于此类目的。假设数据库中有一个名为“data”的表,我们想从表的每一行输出用户名。可以通过以下方式使用 while 循环来完成工作。
- MySQLi: MySQLi 也为此目的使用循环。但是,代码会有些不同。
fetch_assoc()) { echo $row['username'] . '\n'; } ?>
- PDO: PDO 有许多内置语句可以帮助解决这种情况。
- PDOStatement::fetchAll():它以数组的形式返回结果,包含所有结果行。
- PDOStatement::fetchColumn():它从结果集的下一行中获取单个列。
- PDOStatement::fetchObject():首先获取下一行,然后将其作为对象返回。
- PDOStatement::setFetchMode():它设置语句的默认获取模式。
该查询还用于数据获取,因为它返回一个 PDOStatement 对象,该对象可用于通过使用 foreach 和 for 循环直接获取数据。
query('SELECT * FROM `data_table`'); // fetchAll is used $my_results = $stmt->fetchAll(PDO::FETCH_ASSOC); ?>
API 支持:在 API 支持方面,PDO 提供了一种面向对象的方法。 MySQLi 提供了一种程序化的方式,与 MySQL 非常相似。这就是来自 MySQL 背景的开发人员更喜欢使用 MySQLi 的原因。但是,面向对象的程序员更喜欢 PDO,因为它与大量数据库兼容。
因此,面向对象的程序员更喜欢 PDO,而过程程序员更喜欢 MySQL 和 MySQLi。
安全性:数据库安全性用于保护数据库及其包含的信息免受黑客及其攻击。黑客通常使用 SQL 注入来破坏数据库。因此,必须确保注射的安全性。
PDO 和 MySQLi 都提供 SQL 注入安全性。
假设黑客试图使用 POST 方法通过 'firstname' HTTP 查询参数注入 SQL 注入:
$_POST['firstname'] = "'; DELETE FROM users; /*"
如果注入逃脱,它将“按原样”添加到查询中。因此,它将删除用户表中的所有行。
在 PDO 中,手动转义是为了增加安全性。
$name = PDO::quote($_POST['name']);
$pdo->query("SELECT * FROM users WHERE name = $name");
PDO::quote() 和 mysqli_real_escape_string() 的区别在于前者对字符串和引号进行转义,而后者只会对字符串转义,并且引号必须手动添加。