mysql_*
该问题的目标是在代码中使用扩展时提供一个或多个精心设计的答案作为参考。
在 Stackoverflow 上回答问题 我对继续维护包含 API 或扩展mysql_*
来处理数据的代码的用户数量感到惊讶,尽管在PHP 手册中它说如下:
此扩展自 PHP 5.5.0 起已弃用,因此自 PHP 7.0.0 起已将其删除。应使用mysqli或PDO_MySQL扩展名。另请参阅 MySQL API 概述以获取选择 MySQL API 的帮助。
这意味着功能:
mysql_result
mysql_select_db
mysql_num_rows
mysql_connect
mysql_db_query
mysql_fetch_assoc
mysql_*... todas las que empiecen así ...
.
应该避免所有这些功能以及此处列出的许多其他功能。
雪上加霜,功能与扩展的功能几乎相同mysqli
,建议与 PDO 结合使用。上面列出的不推荐使用的函数和 MySQLi 的唯一区别是i
下划线之前的字母_
。
所以问题是这样的:我应该停止使用扩展来查询我的数据的主要原因是什么?mysql_*
PS:我愿意奖励一个或几个好的答案。
函数的主要缺点
mysql_*
:mysql_real_escape_sting
,addslashes
或htmlspecialchars
解决了这个问题,但已经证明他们在某些情况下可能会失败(例如,使用不同的字符集或使用某些值)。MySQLi
它有过程模式和面向对象模式,PDO
它是面向对象的。现在我在评论中提出警告:如果使用这些函数
MySQLi
或PDO
以与它们相同的方式使用它们mysql_*
(连接字符串),它们完全一样危险。为了安全起见,您必须正确使用工具(准备好的语句)。考虑到代码更安全,只是为了使用MySQLi
或者PDO
是一个严重的错误。总结:and的最大优点是您可以使用准备好的或参数化的语句
mysqli_*
PDO
。多亏了这些,复杂性和责任转移到了数据库本身……但正确使用这些工具仍然是开发人员的责任。作为@AlvaroMontoro 回答的补充,我想展示PHP 提供的基于API
mysqli
和PDO 类的两种连接可能性。它们中的任何一个在必须迁移时都是有效的
mysql_
(从 PHP 7 开始是强制性的)。1.mysqli
它有两种风格的代码。面向对象的风格更清晰、更现代,程序风格更长、更冗长,因此产生的代码更难阅读1。
两种风格都可以,但不建议混合风格。
现在让我们看看如何使用这两种样式进行连接。
一个。以面向对象的方式连接到 mysqli
mysqli 是一个类,所以它可以用于面向对象的风格。在这种情况下,它被使用
new
,就像在所有类中一样。构造函数有四个参数:只需这样做,我们就已经有了一个可用于与数据库交互的连接对象:
现在我们只需要
$mysqli
在需要的地方使用我们的对象。湾。以程序样式连接到 mysqli
重要提示:尽管程序风格非常普遍,而且 PHP 手册也总是以这种风格显示示例(尽管最终如此),但应避免使用这种风格进行编程。它比面向对象的风格更冗长,更不清晰,除此之外,它的一些函数,包括 a
mysqli_connect
,在PHP 5 的弃用函数列表中。但是,我展示了如何连接。
连接几乎与面向对象的风格相同,具有相同的四个参数:
在连接中,上面提到的冗长不是很明显。当我们开始使用这些函数时,这个问题很明显,尤其是当我们必须使用准备好的查询并使用绑定方法时......等等。
现在让我们看一下字符集问题:
完成,现在我们只需要使用
$mysqli
.2.PDO
PDO 只有面向对象的风格。PDO 的一大优点是,使用几乎相同的代码,只更改 DSN 和连接凭据,我们可以从一个数据库管理器(Oracle、SQL Server、MySQL、Postgresql...)转到另一个数据库管理器,而无需更改所有在应用程序的不同点查询数据的内部代码。
如 (A) 所示,与 PDO 的连接是用
new
. 但是 PDO 构造函数更完整,并且支持几个有趣的参数:那么让我们看看连接是如何创建的。为了清楚起见,我们将使用变量。
存在的最简单的连接是这样的,它是 PHP 手册中显示的连接:
如您所见,连接是在 block 内处理的
try ... catch
,因为任何调用失败new PDO()
都会引发异常,从而破坏代码。这就是为什么你必须捕获异常。但是这个基本代码有几个问题,所以应该改进。PDO 很棒,但它有一些缺点需要在设置中解决:
echo 'Falló la conexión: ' . $e->getMessage();
好吧,当调用时$e->getMessage()
,在 PDO 异常之前,它会显示连接凭据,包括密码。这可以写在错误日志中,这是黑客最喜欢的文件之一......不要惊慌,我们稍后会解决这个问题。鉴于此,我们可以继续改善我们的联系。变化如下:
$dsn
我们将指示字符集。与 不同mysqli
,我们不必为此使用单独的函数。我们可以将它作为 DSN 的另一数据传递。$options
连接所需的所有配置的数组。由于 PDO 具有setAttribute
修改其配置的方法,因此许多用户首先创建连接,然后使用这些方法对其进行修改。从性能的角度来看,创建已经配置了我们想要的所有内容的连接比使用setAttributes
. 这正是 PDO 支持第四个选项参数的原因。catch
将避免公开内部错误消息。在任何情况下,关于密码,建议始终使用 30 到 50 个字符的长密码。因此,如果它在某些错误日志或屏幕上被错误地显示出来,很长,它会被截断。改进的连接:
现在我们只需要使用我们的对象
$pdo
。正如我们在 (1) 中推荐的那样。在一个类中管理到 PDO 的连接很方便,我们每次需要连接时都会调用它。
链接
成绩
mysql_
与不存在此参数的旧版本相比,这是一项重要的新颖性。在旧手册中,对mysql_select_db()
after connect 的使用进行了修复,许多用户在迁移到新手册时继续这种不必要的做法。mysqli