我看到了很多关于SO实现的代码
my_sql函数
。其他人(包括我自己)的评论迫使提问者放弃
MySQL函数
并开始使用PDO或MySQLI。本文旨在帮助您。你可以参考它,因为它解释了为什么它们被弃用,以及什么
个人数字助理
加上实现PDO的最小代码示例。
首先:
转换自
mysql函数
到
个人数字助理
不是简单的搜索和替换。PDO是PHP语言的面向对象编程插件。
这意味着编写代码的另一种方法与
mysql函数
。首先,为什么要转换?
为什么
mysql函数
已弃用?
mysql扩展很古老,自15年前发布的PHP2.0(!!)以来就一直存在;这与试图摆脱过去不良做法的现代PHP截然不同。mysql扩展是mysql的一个非常原始、低级的连接器,它缺乏许多方便的特性,因此很难以安全的方式正确应用;因此,这不利于任何人。许多开发人员不理解SQL注入,而mysql API非常脆弱,即使你知道,也很难阻止它。它充满了全局状态(例如隐式连接传递),这使得编写难以维护的代码变得容易。由于它已经过时了,在PHP核心级别维护它可能是不合理的困难。
mysqli扩展更新了很多,并修复了上述所有问题。PDO也很新,也解决了所有这些问题,还有更多问题。
由于这些原因,mysql扩展将在未来某个时候删除。
来源
Deceze
如何实施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
。它们是特定于版本的,因此
##
。在撰写本文时,微软发布了
PHP 5.5.x的官方驱动程序。5.6驱动程序尚未由Microsoft正式发布,但可以通过
others
.
模块为
php_pdo_sqlsrv###_ts.dll
对于线程安全变体
模块为
php_pdo_sqlsrv_##_nts.dll
对于非线程安全变体
使用PDO连接到数据库
要连接到数据库,需要创建
新PDO实例
来自
PDO构造
.
$connection = new PDO(arguments);
PDO构造函数接受1个必需参数和3个可选参数。
-
DSN或
数字资源命名
,通常这是一个字符串,包含有关驱动程序、主机和数据库名称的信息。从PHP 7.4开始,它还可以包括用户名和密码。
-
用户名
-
暗语
-
选项
正在连接到
MySQL数据库
$dsn = 'mysql:dbname=databasename;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
让我们来看看
$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脚本期间,只需执行一次。
您需要将PDO实例创建包装在
try-catch条款
。如果创建失败,将显示一个回溯跟踪,显示有关应用程序的关键信息,如用户名和密码。为了避免这种情况,请抓住错误。
try
{
$connection = new PDO($dsn, $user, $password);
}
catch( PDOException $Exception )
{
echo "Unable to connect to database.";
exit;
}
要抛出SQL server返回的错误,请使用
setAttribute
:
$connection->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
正在执行查询
PDO使用
编制的报表
。这是
PDO的
方法和
mysql函数
后者非常容易受到
SQL注入
。可以构建如下查询:
$SQL = 'SELECT ID FROM users WHERE user = '.$username ;
当恶意网站或个人发布用户名时
injector; DROP TABLE users
。结果将是毁灭性的。您需要通过用引号转义和封装字符串和变量来验证代码。这是必须做的
对于每个查询。在较大的网站或维护较差的代码上,使用允许SQL注入的表单的风险可能会非常高。准备好的语句消除了像上面的示例一样的第一层SQL注入的机会。
PDO驱动程序充当PHP服务器和数据库服务器之间的中间人,称为
数据访问抽象
层它不会重写SQL查询,但提供了一种连接到多个数据库类型的通用方法
并为您处理向查询中插入变量。
Mysql函数
构造了PHP代码执行的查询。使用PDO,查询实际上是在数据库服务器上构建的。
准备好的SQL示例:
$SQL = 'SELECT ID, EMAIL FROM users WHERE user = :username';
注意差异;而不是使用PHP变量
$
在字符串之外,我们使用
:
在字符串中。另一种方法是:
$SQL = 'SELECT ID, EMAIL FROM users WHERE user = ?';
如何执行实际查询
PDO实例提供了两种执行查询的方法。当您没有变量时,可以使用
query()
,使用变量
prepare()
.
查询()
在调用时立即执行。请注意呼叫的面向对象方式(
->
).
$result = $connection->query($SQL);
制备方法
这个
制备方法
有两个参数。第一个是SQL字符串,第二个是数组形式的选项。一个基本的例子
$connection->prepare($SQL, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
在我们的SQL字符串示例中,我们使用了一个名为
:username
。我们仍然需要将一个PHP变量、整数或字符串绑定到它。我们可以通过两种方式实现。将包含命名变量的数组构建为
key
或使用该方法
bindParam
或
bindValue
.
我将解释数组变量和方法
bindValue(绑定值)
为了简单起见。
Array
您可以对命名变量执行类似的操作,其中提供
变量
像
数组关键字
:
$queryArguments = array(':username' => $username);
对于索引变量(
?
):
$queryArguments = array($username);
添加完所需的所有变量后,可以调用该方法
execute()
以执行查询。从而将数组作为参数传递给函数
execute
.
$result = $connection->execute($queryArguments);
bindValue(绑定值)
这个
bindValue(绑定值)
方法允许您将值绑定到
PDO实例
。该方法接受两个必需参数和一个可选参数。可选参数设置值的数据类型。
对于命名变量:
$connection->bindValue(':username', $username);
对于索引变量:
$connection->bindValue(1, $username);
将值绑定到实例后,可以调用
处决
而不传递任何参数。
$result = $connection->execute();
注意:只能使用一次命名变量!两次使用它们将导致执行查询失败。根据您的设置,这将或不会引发错误。
正在获取结果
再次,我将只介绍从返回集获取结果的基本知识。PDO是一个相当高级的插件。
使用
fetch
和
fetchAll
如果你做了
选择查询
或执行
存储过程
返回了一个结果集:
取来
取来
是一个最多可以使用三个可选参数的方法。它从结果集中提取一行。默认情况下,它返回
大堆
包含列名称作为关键字和索引结果。
我们的示例查询可能返回如下内容
ID EMAIL
1 someone@example.com
取来
将返回为:
Array
(
[ID] => 1
[0] => 1
[EMAIL] => someone@example.com
[1] => someone@example.com
)
要回显结果集的所有输出,请执行以下操作:
while($row = $result->fetch())
{
echo $row['ID'];
echo $row['EMAIL'];
}
您可以在此处找到其他选项:
fetch_style
;
全部获取
获取单个数组中的所有行。使用与相同的默认选项
取来
.
$rows = $result->fetchAll();
如果使用的查询不返回结果,例如插入或更新查询,则可以使用该方法
rowCount
检索受影响的行数。
一个简单的类:
class pdoConnection {
public $isConnected;
protected $connection;
public function __construct($dsn, $username, $password, $options = array()) {
$this->isConnected = true;
try {
$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.
} catch (PDOException $e) {
$this->isConnected = false;
throw new Exception($e->getMessage());
}
}
public function disconnect() {
$this->connection = null;
$this->isConnected = false;
}
public function query($SQL) {
try {
$result = $this->connection->query($SQL);
return $result;
} catch (PDOException $e) {
throw new PDOException($e->getMessage());
}
}
public function prepare($SQL, $params = array()) {
try {
$result = $this->connection->prepare($SQL);
$result->execute($params);
return $result;
} catch (PDOException $e) {
throw new PDOException($e->getMessage());
}
}
}
如何使用:
$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'];
}