如何用PDO代替MySQL函数? [英] How to replace MySQL functions with PDO?
问题描述
在 php.net 上阅读有关 MySQL函数的信息.我遇到了这个消息
警告 自PHP 5.5.0起不推荐使用此扩展,以后将删除.相反,应使用MySQLi或PDO_MySQL扩展.另请参见MySQL:选择API指南和相关的FAQ,以获取更多信息.此功能的替代方法包括:
我已经阅读了有关PDO的信息.如何使用MySQL或MSSQL将代码更新为PDO?
我看到在实现 my_sql函数的SO上发布了很多代码.以及其他人(包括我自己)的评论迫使提问者放弃 MySQL函数,并开始使用PDO或MySQLI.这篇文章对您有所帮助.您可以参考它,因为它提供了为什么不推荐使用它们以及 PDO 是什么的解释,以及实现PDO的最小代码示例.
首先:
从 mysql函数转换为 PDO 的不是搜索和替换的简单情况. PDO是PHP语言的一种面向对象编程插件. 这意味着与 mysql函数一样,另一种编写代码的方法.首先为什么要转换?
为什么不赞成使用 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 数据库,先决条件
ID EMAIL
1 someone@example.com
fetch
将其返回为:
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 ; >
fetchAll
获取单个数组中的所有行.使用与fetch
相同的默认选项.
$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'];
}
When reading on php.net about MySQL functions. I encountered this message
Warning This extension is deprecated as of PHP 5.5.0, and will be removed in the future. Instead, the MySQLi or PDO_MySQL extension should be used. See also MySQL: choosing an API guide and related FAQ for more information. Alternatives to this function include:
I've read about PDO. How can I update my code to PDO using either MySQL or MSSQL?
I see a lot of code posted on SO implementing my_sql functions. And comments from others (including myself) pressing the questioners to abandon MySQL functions and start using PDO or MySQLI. This post is here to help. You can refer to it as it provides explanation to why they are deprecated and what PDO is, plus a minimal code example to implement PDO.
First of all:
Conversion from mysql functions to PDO is not a simple case of search and replace. PDO is an Object Oriented Programming add on for the PHP language. That means an other approach in writing the code as with the mysql functions. First why convert?
Why are mysql functions deprecated?
The mysql extension is ancient and has been around since PHP 2.0, released 15 years ago (!!); which is a decidedly different beast than the modern PHP which tries to shed the bad practices of its past. The mysql extension is a very raw, low-level connector to MySQL which lacks many convenience features and is thereby hard to apply correctly in a secure fashion; it's therefore bad for noobs. Many developers do not understand SQL injection and the mysql API is fragile enough to make it hard to prevent it, even if you're aware of it. It is full of global state (implicit connection passing for instance), which makes it easy to write code that is hard to maintain. Since it's old, it may be unreasonably hard to maintain at the PHP core level.
The mysqli extension is a lot newer and fixes all the above problems. PDO is also rather new and fixes all those problems too, plus more.
Due to these reasons* the mysql extension will be removed sometime in the future.
source Deceze
How to implement PDO
PDO offers one solution for connecting to multiple databases. This answer covers only MySQL and MSSQL servers.
Connecting to a MySQL database, prerequisites
This is fairly simple and doesn't require any pre set-up of PHP. Modern PHP installations are standard shipped with a module that allows PDO connections to MySQL servers.
The module is
php_pdo_mysql.dll
Connecting to a MSSQL database, prerequisites
This is a more advanced set-up. You need php_pdo_sqlsrv_##_ts.dll
or php_pdo_sqlsrv_##_nts.dll drivers
. They are version specific hence the ##
. At the moment of writing, Microsoft has released
official drivers for PHP 5.5.x. The 5.6 drivers aren't yet officially released by Microsoft, but are available as non-official builds by others.
The module is
php_pdo_sqlsrv_##_ts.dll
for the thread safe variant The module isphp_pdo_sqlsrv_##_nts.dll
for the non-thread safe variant
Connecting to a database using PDO To connect to a database you need to create a new PDO instance from the PDO construct.
$connection = new PDO(arguments);
The PDO constructor takes 1 required arguments and 3 optional.
- DSN or Data Source Name, mostly this is a string containing information about the driver, host and database name. Since PHP 7.4 it can also include username and password.
- Username
- Password
- Options
Connecting to MySQL
$dsn = 'mysql:dbname=databasename;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
Let's take a look at $dsn
: First it defines the driver (mysql
). Then the database name and finally the host.
Connecting to MSSQL
$dsn = 'sqlsrv:Server=127.0.0.1;Database=databasename';
$user = 'dbuser';
$password = 'dbpass';
$dbh = new PDO($dsn, $user, $password);
Let's take a look at $dsn
: First it defines the driver (sqlsrv
). Then the host and finally the database name.
When you create the instance a connection is made to the database. You only have to do this once during the execution of a PHP script.
You need to wrap the PDO instance creation in a try-catch clause. If the creation fails a back trace is shown revealing critical information about your application, like username and password. To avoid this catch the errors.
try
{
$connection = new PDO($dsn, $user, $password);
}
catch( PDOException $Exception )
{
echo "Unable to connect to database.";
exit;
}
To throw errors returned by your SQL server add this options to your PDO instance using
setAttribute
:$connection->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
Performing queries
PDO uses prepared statements. This is a real difference between PDO's approach and mysql functions. The latter was very susceptible to SQL-INJECTION. One would build a query like this:
$SQL = 'SELECT ID FROM users WHERE user = '.$username ;
When a malicious website or person posts the username injector; DROP TABLE users
. The results will be devastating. You needed to proof your code by escaping and encapsulating strings and variables with quotes. This had to be done
for every query. On larger websites or poorly maintained code the risk of having a form that allowed SQL injection could become very high. Prepared statements eliminates the chance of first tier SQL injection like the example above.
The PDO drivers act as a man-in-the-middle between your PHP-server and database server, called a data-access abstraction layer. It doesn't rewrite your SQL queries, but do offer a generic way to connect to multiple database types and handles the insertion of variables into the query for you. Mysql functions constructed the query on execution of the PHP code. With PDO the query actually gets build on the database server.
A prepared SQL example:
$SQL = 'SELECT ID, EMAIL FROM users WHERE user = :username';
Note the difference; Instead of a PHP variable using $
outside the string, we introduce a variable using :
within the string. Another way is:
$SQL = 'SELECT ID, EMAIL FROM users WHERE user = ?';
How to perform the actual query
Your PDO instance provides two methods of executing a query. When you have no variables you can use query()
, with variables use prepare()
. query()
is immediately executed upon calling. Please note the object oriented way of the call (->
).
$result = $connection->query($SQL);
The prepare method
The prepare method takes two arguments. The first is the SQL string and the second are options in the form of an Array. A basic example
$connection->prepare($SQL, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
In our SQL string example we've used a named variable called :username
. We still need to bind a PHP variable, integer or string to it. We can do this in two ways. Either build an array containing the named variables as key
or use the method bindParam
or bindValue
.
I will explain the array variant and the method bindValue
for the sake of simplicity.
Array
You can do something like this for named variables, where you provide the variable as array key:
$queryArguments = array(':username' => $username);
And this for indexed variables (?
):
$queryArguments = array($username);
When you have added all the variables you need you can call upon the method execute()
to perform the query. Thereby passing the array as argument to the function execute
.
$result = $connection->execute($queryArguments);
bindValue
The bindValue method allows you to bind values to the PDO instance. The method takes two required arguments and one optional. The optional arguments set the data-type of the value.
For named variables:
$connection->bindValue(':username', $username);
For indexed variables:
$connection->bindValue(1, $username);
After binding the values to the instance, you can call upon execute
without passing any arguments.
$result = $connection->execute();
NOTE: You can only use a named variable once! Using them twice will result in a failure to execute the query. Depending on your settings this will or will not throw an error.
Fetching the results
Again I will only cover the basics for fetching results from the returned set. PDO is a fairly advanced add-on.
Using fetch
and fetchAll
If you did a select query or executed a stored procedure that returned a result set:
fetch
fetch
is a method that could take up to three optional arguments. It fetches a single row from the result set. By default it returns an array containing the column names as keys and indexed results.
Our example query could return something like
ID EMAIL
1 someone@example.com
fetch
will return this as:
Array
(
[ID] => 1
[0] => 1
[EMAIL] => someone@example.com
[1] => someone@example.com
)
To echo all output of a result set:
while($row = $result->fetch())
{
echo $row['ID'];
echo $row['EMAIL'];
}
There are other options you can find here: fetch_style;
fetchAll
Fetches all rows in a single array. Using the same default option as fetch
.
$rows = $result->fetchAll();
If you used a query that didn't return results like a insert or update query you can use the method rowCount
to retrieve the amount of rows affected.
A simple class:
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());
}
}
}
How to use:
$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'];
}
这篇关于如何用PDO代替MySQL函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!