当阅读php.net关于 *MySQL函数 *.我遇到了这个消息警告此扩展自PHP 5.5.0起已被弃用,将来将被删除。应使用MySQLi或PDO_MySQL扩展。另请参阅MySQL:选择API指南和相关FAQ以获取更多信息。此函数的替代方法包括:
我读过关于PDO的文章。我如何使用MySQL或MSSQL将我的代码更新为PDO?
relj7zay1#
我在SO上看到了很多实现 *my_sql函数 * 的代码。其他人(包括我自己)的评论敦促提问者放弃 *MySQL函数 *,开始使用PDO或MySQLI。这篇文章是为了帮助你。你可以参考它,因为它解释了为什么它们被弃用,PDO 是什么,加上一个实现PDO的最小代码示例。
从 mysql functions 到 PDO 的转换并不是一个简单的搜索和替换的情况。PDO是PHP语言的一个面向对象编程插件。这意味着编写代码的另一种方法,就像编写 mysql functions 一样。首先,为什么要转换?
mysql扩展是一个古老的扩展,从15年前发布的PHP 2.0开始就存在了(!!);它与试图摆脱过去的坏习惯的现代PHP完全不同。mysql扩展是一个非常原始的,低级的MySQL连接器,缺乏许多方便的功能,因此很难以安全的方式正确应用;因此,这对新手来说是不好的。许多开发人员不了解SQL注入,而且mysql API非常脆弱,即使你意识到了,也很难阻止它。它充满了全局状态(例如隐式连接传递),这使得编写难以维护的代码变得容易。由于它很旧,在PHP核心级别维护可能会非常困难。mysqli扩展更新了很多,修复了所有上述问题。PDO也是相当新的,修复了所有这些问题,还有更多。由于这些原因,mysql扩展将在未来的某个时候被删除。
PDO提供了一个连接到多个数据库的解决方案。这个答案只包括 MySQL 和 MSSQL 服务器。
连接到 MySQL 数据库,前提条件
这相当简单,不需要任何PHP的预先设置。现代PHP安装标准附带一个模块,允许PDO连接到MySQL服务器。模块为php_pdo_mysql.dll
php_pdo_mysql.dll
连接到 MSSQL 数据库,前提条件
这是一个更高级的设置。您需要php_pdo_sqlsrv_##_ts.dll或php_pdo_sqlsrv_##_nts.dll drivers。它们是特定于版本的,因此使用##。在撰写本文时,Microsoft已经发布了PHP 5.5.x的官方驱动程序。5.6驱动程序尚未由Microsoft正式发布,但可以作为others的非官方版本使用。对于线程安全变体,模块为php_pdo_sqlsrv_##_ts.dll对于非线程安全变体,模块为php_pdo_sqlsrv_##_nts.dll
php_pdo_sqlsrv_##_ts.dll
php_pdo_sqlsrv_##_nts.dll drivers
##
php_pdo_sqlsrv_##_nts.dll
使用PDO连接到数据库要连接到数据库,您需要从 *PDO构造 * 创建 * 新的PDO示例 *。
$connection = new PDO(arguments);
字符串PDO构造函数接受1个必需参数和3个可选参数。
**正在连接 MySQL
$dsn = 'mysql:dbname=databasename;host=127.0.0.1'; $user = 'dbuser'; $password = 'dbpass'; $dbh = new PDO($dsn, $user, $password);
型让我们来看看$dsn:首先它定义了驱动程序(mysql),然后是数据库名,最后是主机。
$dsn
mysql
**连接到 MSSQL
$dsn = 'sqlsrv:Server=127.0.0.1;Database=databasename'; $user = 'dbuser'; $password = 'dbpass'; $dbh = new PDO($dsn, $user, $password);
型让我们来看看$dsn:首先它定义了驱动程序(sqlsrv),然后是主机,最后是数据库名。当你创建一个示例的时候,你会建立一个到数据库的连接。你只需要在PHP脚本执行的时候做一次。要抛出SQL服务器返回的错误,请使用setAttribute将以下选项添加到PDO示例:$connection->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
sqlsrv
setAttribute
$connection->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
PDO使用 prepared statements。这是 *PDO的 * 方法和 *mysql函数 * 之间的真实的区别。后者非常容易受到 SQL-INJECTION 的影响。可以这样构建查询:
$SQL = 'SELECT ID FROM users WHERE user = '.$username ;
型当恶意网站或个人发布用户名injector; DROP TABLE users时。结果将是毁灭性的。您需要通过转义和用引号封装字符串和变量来验证代码。必须对每个查询执行此操作。在较大的网站或维护较差的代码中,允许SQL注入的表单的风险可能会变得非常高。准备语句消除了第一层SQL注入的机会,如上面的例子。PDO驱动程序充当PHP服务器和数据库服务器之间的中间人,称为 * 数据访问抽象 * 层。它不会重写SQL查询,但提供了一种通用的方式来连接到多个数据库类型,并为您处理变量插入查询。*Mysql函数 * 在执行PHP代码时构造查询。使用PDO,查询实际上是在数据库服务器上构建的。一个准备好的SQL示例:
injector; DROP TABLE users
$SQL = 'SELECT ID, EMAIL FROM users WHERE user = :username';
型注意区别;我们在字符串内引入一个使用:的变量,而不是在字符串外使用$的PHP变量。另一种方法是:
:
$
$SQL = 'SELECT ID, EMAIL FROM users WHERE user = ?';
型
如何进行实际查询
您的PDO执行严修提供两种执行查询的方法。如果没有变数,您可以使用query(),如果有变数,则使用prepare()。query()会在呼叫时立即执行。请注意呼叫的对象导向方式(->)。
query()
prepare()
->
$result = $connection->query($SQL);
制备方法
方法 * prepare * 有两个参数。第一个是SQL字符串,第二个是数组形式的选项。
$connection->prepare($SQL, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
型在我们的SQL字符串示例中,我们使用了一个名为:username的命名变量,我们可以用两种方法来实现这一点。要么构建一个包含命名变量的数组,如key,要么使用方法bindParam或bindValue。我将解释数组变量和方法bindValue,以便简单易用。
:username
key
bindParam
bindValue
您可以对命名变量执行类似的操作,其中您将 * 变量 * 作为 * 数组键 * 提供:
$queryArguments = array(':username' => $username);
型对于索引变量(?):
?
$queryArguments = array($username);
型当你添加了所有你需要的变量后,你可以调用方法execute()来执行查询,从而将数组作为参数传递给函数execute。
execute()
execute
$result = $connection->execute($queryArguments);
bindValue 方法允许您将值绑定到 *PDO示例 *。该方法采用两个必需参数和一个可选参数。可选参数用于设置值的数据类型。对于命名变量:
$connection->bindValue(':username', $username);
型对于索引变量:
$connection->bindValue(1, $username);
型在将值系结至执行严修之后,您可以在不传递任何参数的情况下呼叫execute。
$result = $connection->execute();
型注意事项:命名变量只能使用一次!使用两次将导致查询执行失败。根据您的设置,这是否会引发错误将取决于您的设置。
同样,我将只介绍从返回的集合中获取结果的基础知识。PDO是一个相当高级的插件。
使用fetch和fetchAll
fetch
fetchAll
如果执行了返回结果集的 * 选择查询 * 或执行了 * 存储过程 *:
fetch是一个最多可以使用三个可选参数的方法。它从结果集中提取一行。默认情况下,它返回一个 * 数组 *,其中包含作为键和索引结果的列名。我们的示例查询可以返回如下内容
ID EMAIL 1 [email protected]
型fetch将返回如下内容:
Array ( [ID] => 1 [0] => 1 [EMAIL] => [email protected] [1] => [email protected] )
型要回显结果集得所有输出,请执行以下操作:
while($row = $result->fetch()) { echo $row['ID']; echo $row['EMAIL']; }
型您可以在此处找到其他选项:fetch_style;
提取单个数组中的所有行。使用与fetch相同的默认选项。
$rows = $result->fetchAll();
型如果您使用的查询没有传回结果,例如插入或更新查询,您可以使用方法rowCount来撷取受影响的数据列数量。
rowCount
class pdoConnection { public $isConnected; protected $connection; public function __construct($dsn, $username, $password, $options = array()) { $this->isConnected = true; $this->connection = new PDO($dsn, $username, $password, $options); $this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $this->connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); //sets the default to return 'named' properties in array. } public function disconnect() { $this->connection = null; $this->isConnected = false; } public function query($SQL) { return $this->connection->query($SQL); } public function prepare($SQL, $params = array()) { $result = $this->connection->prepare($SQL); $result->execute($params); return $result; } }
型使用方法:
$dsn = 'mysql:dbname=databasename;host=127.0.0.1'; $user = 'dbuser'; $password = 'dbpass'; $db = new pdoConnection($dsn, $user, $password); $SQL = 'SELECT ID, EMAIL FROM users WHERE user = :username'; $result = $db->prepare($SQL, array(":username" => 'someone')); while($row = $result->fetch()) { echo $row['ID']; echo $row['EMAIL']; }
1条答案
按热度按时间relj7zay1#
我在SO上看到了很多实现 *my_sql函数 * 的代码。其他人(包括我自己)的评论敦促提问者放弃 *MySQL函数 *,开始使用PDO或MySQLI。这篇文章是为了帮助你。你可以参考它,因为它解释了为什么它们被弃用,PDO 是什么,加上一个实现PDO的最小代码示例。
从 mysql functions 到 PDO 的转换并不是一个简单的搜索和替换的情况。PDO是PHP语言的一个面向对象编程插件。这意味着编写代码的另一种方法,就像编写 mysql functions 一样。首先,为什么要转换?
为什么 *mysql函数 * 被弃用?
mysql扩展是一个古老的扩展,从15年前发布的PHP 2.0开始就存在了(!!);它与试图摆脱过去的坏习惯的现代PHP完全不同。mysql扩展是一个非常原始的,低级的MySQL连接器,缺乏许多方便的功能,因此很难以安全的方式正确应用;因此,这对新手来说是不好的。许多开发人员不了解SQL注入,而且mysql API非常脆弱,即使你意识到了,也很难阻止它。它充满了全局状态(例如隐式连接传递),这使得编写难以维护的代码变得容易。由于它很旧,在PHP核心级别维护可能会非常困难。
mysqli扩展更新了很多,修复了所有上述问题。PDO也是相当新的,修复了所有这些问题,还有更多。
由于这些原因,mysql扩展将在未来的某个时候被删除。
如何实现PDO
PDO提供了一个连接到多个数据库的解决方案。这个答案只包括 MySQL 和 MSSQL 服务器。
连接到 MySQL 数据库,前提条件
这相当简单,不需要任何PHP的预先设置。现代PHP安装标准附带一个模块,允许PDO连接到MySQL服务器。
模块为
php_pdo_mysql.dll
连接到 MSSQL 数据库,前提条件
这是一个更高级的设置。您需要
php_pdo_sqlsrv_##_ts.dll
或php_pdo_sqlsrv_##_nts.dll drivers
。它们是特定于版本的,因此使用##
。在撰写本文时,Microsoft已经发布了PHP 5.5.x的官方驱动程序。5.6驱动程序尚未由Microsoft正式发布,但可以作为others的非官方版本使用。对于线程安全变体,模块为
php_pdo_sqlsrv_##_ts.dll
对于非线程安全变体,模块为php_pdo_sqlsrv_##_nts.dll
使用PDO连接到数据库要连接到数据库,您需要从 *PDO构造 * 创建 * 新的PDO示例 *。
字符串
PDO构造函数接受1个必需参数和3个可选参数。
1.用户名
1.密码
1.选项
**正在连接 MySQL
型
让我们来看看
$dsn
:首先它定义了驱动程序(mysql
),然后是数据库名,最后是主机。**连接到 MSSQL
型
让我们来看看
$dsn
:首先它定义了驱动程序(sqlsrv
),然后是主机,最后是数据库名。当你创建一个示例的时候,你会建立一个到数据库的连接。你只需要在PHP脚本执行的时候做一次。
要抛出SQL服务器返回的错误,请使用
setAttribute
将以下选项添加到PDO示例:$connection->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
执行查询
PDO使用 prepared statements。这是 *PDO的 * 方法和 *mysql函数 * 之间的真实的区别。后者非常容易受到 SQL-INJECTION 的影响。可以这样构建查询:
型
当恶意网站或个人发布用户名
injector; DROP TABLE users
时。结果将是毁灭性的。您需要通过转义和用引号封装字符串和变量来验证代码。必须对每个查询执行此操作。在较大的网站或维护较差的代码中,允许SQL注入的表单的风险可能会变得非常高。准备语句消除了第一层SQL注入的机会,如上面的例子。PDO驱动程序充当PHP服务器和数据库服务器之间的中间人,称为 * 数据访问抽象 * 层。它不会重写SQL查询,但提供了一种通用的方式来连接到多个数据库类型,并为您处理变量插入查询。*Mysql函数 * 在执行PHP代码时构造查询。使用PDO,查询实际上是在数据库服务器上构建的。
一个准备好的SQL示例:
型
注意区别;我们在字符串内引入一个使用
:
的变量,而不是在字符串外使用$
的PHP变量。另一种方法是:型
如何进行实际查询
您的PDO执行严修提供两种执行查询的方法。如果没有变数,您可以使用
query()
,如果有变数,则使用prepare()
。query()
会在呼叫时立即执行。请注意呼叫的对象导向方式(->
)。型
制备方法
方法 * prepare * 有两个参数。第一个是SQL字符串,第二个是数组形式的选项。
型
在我们的SQL字符串示例中,我们使用了一个名为
:username
的命名变量,我们可以用两种方法来实现这一点。要么构建一个包含命名变量的数组,如key
,要么使用方法bindParam
或bindValue
。我将解释数组变量和方法bindValue
,以便简单易用。您可以对命名变量执行类似的操作,其中您将 * 变量 * 作为 * 数组键 * 提供:
型
对于索引变量(
?
):型
当你添加了所有你需要的变量后,你可以调用方法
execute()
来执行查询,从而将数组作为参数传递给函数execute
。型
bindValue 方法允许您将值绑定到 *PDO示例 *。该方法采用两个必需参数和一个可选参数。可选参数用于设置值的数据类型。
对于命名变量:
型
对于索引变量:
型
在将值系结至执行严修之后,您可以在不传递任何参数的情况下呼叫
execute
。型
注意事项:命名变量只能使用一次!使用两次将导致查询执行失败。根据您的设置,这是否会引发错误将取决于您的设置。
正在获取结果
同样,我将只介绍从返回的集合中获取结果的基础知识。PDO是一个相当高级的插件。
使用
fetch
和fetchAll
如果执行了返回结果集的 * 选择查询 * 或执行了 * 存储过程 *:
fetch
是一个最多可以使用三个可选参数的方法。它从结果集中提取一行。默认情况下,它返回一个 * 数组 *,其中包含作为键和索引结果的列名。我们的示例查询可以返回如下内容型
fetch
将返回如下内容:型
要回显结果集得所有输出,请执行以下操作:
型
您可以在此处找到其他选项:fetch_style;
提取单个数组中的所有行。使用与
fetch
相同的默认选项。型
如果您使用的查询没有传回结果,例如插入或更新查询,您可以使用方法
rowCount
来撷取受影响的数据列数量。一个简单的类:
型
使用方法:
型