php pdo数据库_重新引入PDO-用PHP访问数据库的正确方法

php pdo数据库

PDO is the acronym of PHP Data Objects. As the name implies, this extension gives you the ability to interact with your database through objects.

PDO是PHP数据对象的首字母缩写。 顾名思义,此扩展使您能够通过对象与数据库进行交互。

Stock graphic of database icon branching into other icons

为什么不使用mysqlmysqli(Why not mysql and mysqli?)

The very valid question people ask when confronted by a new technology is simply, why should they upgrade? What does this new technology give them that is worth the effort of going through their entire application and converting everything to this new library, extension, or whatever?

人们在面对新技术时提出的一个非常有效的问题就是,为什么要升级? 这项新技术给他们带来什么,值得他们遍历整个应用程序并将所有内容都转换为新的库,扩展或其他内容?

It’s a very valid concern. We’ve written about this to some degree before, but let’s go through why we think it’s worth it to upgrade.

这是一个非常有效的担忧。 之前我们已经对此进行了一定程度的介绍 ,但是让我们来探讨为什么我们认为值得进行升级。

PDO是面向对象的 (PDO is object-oriented)

Let’s face it: PHP is rapidly growing, and it is moving toward becoming a better programming language. Usually, when this happens in a dynamic language, the language increases its strictness in order to allow programmers to write enterprise applications with peace of mind.

让我们面对现实:PHP正在Swift发展,并且正朝着成为更好的编程语言迈进。 通常,当这种情况以动态语言发生时,该语言会提高其严格性,以使程序员可以放心地编写企业应用程序。

In case of PHP, better PHP means object-oriented PHP. This means the more you get to use objects, the better you can test your code, write reusable components, and, usually, increase your salary.

对于PHP,更好PHP意味着面向对象PHP 。 这意味着您使用对象的次数越多,测试代码,编写可重用组件的能力就越好,并且通常会增加薪水。

Using PDO is the first step in making the database layer of your application object-oriented and reusable. As you will see in the rest of this article, writing object-oriented code with PDO is much simpler than you may think.

使用PDO是使应用程序的数据库层面向对象和可重用的第一步。 正如您将在本文的其余部分中看到的那样,用PDO编写面向对象的代码比您想象的要简单得多。

抽象化 (Abstraction)

Imagine that you have written a killer application using MySQL at your current workplace. All of a sudden, someone up the chain decides that you must migrate your application to use Postgres. What are you going to do?

想象一下,您在当前的工作场所使用MySQL编写了一个杀手级应用程序。 突然之间,连锁企业的某个人决定您必须迁移应用程序才能使用Postgres 。 你会怎样做?

You have to do a lot of messy replaces, like converting mysql_connect or mysqli_connect to pg_connect, not to mention all the other functions you used for running queries and fetching results. If you were using PDO, it would be very simple. Just a few parameters in the main configuration file would need changing, and you’d be done.

您必须进行很多麻烦的替换,例如将mysql_connectmysqli_connect转换为pg_connect ,更不用说用于运行查询和获取结果的所有其他功能。 如果您使用的是PDO,那将非常简单。 您只需更改主配置文件中的几个参数即可。

它允许参数绑定 (It allows parameter binding)

Parameter binding is a feature that allows you to replace placeholders in your query with the value of a variable. It means:

参数绑定是一项功能,使您可以用变量的值替换查询中的占位符。 它的意思是:

  • You don’t have to know, at runtime, how many placeholders you will have.

    您不必在运行时知道将有多少个占位符。
  • Your application will be much safer against SQL injection.

    您的应用程序将更安全地防止SQL注入。

您可以将数据提取到对象中 (You can fetch data into objects)

People who have used ORMs like Doctrine know the value of being able to represent data in your tables with objects. If you would like to have this feature, but don’t want to learn an ORM, or don’t want to integrate it into an already existing application, PDO will allow you to fetch the data in your table into an object.

使用过诸如Doctrine之类的ORM的人都知道能够用对象表示表中数据的价值。 如果您想拥有此功能,但又不想学习ORM,或者不想将其集成到已经存在的应用程序中,则PDO将允许您将表中的数据提取到一个对象中。

不再支持mysql扩展! (The mysql extension is no longer supported!)

Yes, the mysql extension is finally removed from PHP 7. That means if you’re going to use PHP 7, you need to change all those functions to mysqli_* instead of mysql_*. This is a great time to just upgrade straight to PDO because of how much it helps you in writing maintainable, portable code with much less effort.

是的, mysql扩展最终已从PHP 7中删除 。 这意味着,如果您要使用PHP 7,则需要将所有这些功能更改为mysqli_*而不是mysql_* 。 这是直接升级到PDO的绝佳时机,因为它在很大程度上帮助您编写可维护的可移植代码,而工作量却大大减少。

I hope the reasons above have convinced you to start integrating PDO into your application. Don’t worry about setting it up; you may already have it on your system!

我希望以上原因使您相信可以开始将PDO集成到您的应用程序中。 不用担心进行设置; 您可能已经在系统上安装了它!

验证PDO的存在 (Verifying the Existence of PDO)

If you are using PHP 5.5.X and above, chances are that your installation already includes PDO. To verify, simply open the terminal on Linux and Mac OS X, or the command prompt on Windows, and type the following command:

如果您使用的是PHP 5.5.X及更高版本,则可能是您的安装中已经包含PDO。 要进行验证,只需在Linux和Mac OS X上打开终端,或在Windows上打开命令提示符,然后键入以下命令:

php -i | grep 'pdo'

You can also create a php file under your webroot, and insert a phpinfo() statement inside it:

您还可以在webroot下创建一个php文件,并在其中插入phpinfo()语句:

<?php
phpinfo();

Now, open this page in your browser and search for the pdo string.

现在,在浏览器中打开此页面并搜索pdo字符串。

If you have PDO and MySQL, skip the installation instructions. If you have PDO but don’t have it for MySQL, you merely need to install the mysqlnd extension per the instructions below. However, if you don’t have PDO at all, your path is longer, but not harder! Keep on reading and we’ll tell you how to gear up by installing PDO and mysqlnd!

如果您具有PDO和MySQL,请跳过安装说明。 如果您拥有PDO,但没有MySQL专用的PDO,则只需按照以下说明安装mysqlnd扩展。 但是,如果您根本没有PDO,那么您的路径会更长,但并不困难! 继续阅读,我们将告诉您如何通过安装PDO和mysqlnd

安装PDO (Installation of PDO)

If you have already installed PHP from a repository through a package manager (e.g. apt, yum, pacman, and so on), installing PDO is very simple and straightforward; just run the installation command that is listed under your respective operating system and distribution below. If you haven’t, though, I have also included my recommended methods for starting from scratch.

如果您已经通过软件包管理器(例如apt,yum,pacman等)从存储库中安装了PHP,则安装PDO非常简单明了。 只需运行下面各自操作系统和发行版下列出的安装命令即可。 但是,如果您还没有的话,我也提供了我推荐的从头开始的方法。

Fedora,RedHat和CentOS (Fedora, RedHat and CentOS)

First, if you don’t have it already, add the Remi repository using the instructions provided on their blog. When that’s done, you can easily install php-pdo using the following command:

首先,如果您还没有Remi仓库,请按照其博客上的说明添加Remi仓库。 完成后,您可以使用以下命令轻松安装php-pdo

sudo yum --enablerepo=remi,remi-php56 install php-pdo

Note: Although having the remi repository enabled is required, you need to replace remi-php56 with your desired repository in the command above.

:虽然具有remi库需要启用,需要更换remi-php56在上面的命令中你所需的存储库。

Of course, if you don’t have it already, you also need to install the mysqlnd extension using the following command:

当然,如果还没有,还需要使用以下命令安装mysqlnd扩展:

sudo yum --enablerepo=remi,remi-php56 install php-mysqlnd

Debian和Ubuntu (Debian and Ubuntu)

On Ubuntu, you need to add the Ondrej repository. This link points to the PPA for 5.6, but you can find links to previous versions there as well.

在Ubuntu上,您需要添加Ondrej存储库。 该链接指向5.6的PPA,但您也可以在此处找到以前版本的链接。

On Debian, you should add the Dotdeb repository to your system.

在Debian上,您应该将Dotdeb存储库添加到系统中。

On both of these distributions, once you’ve installed the php5 metapackage, you already have PDO ready and configured. All you need to do is to simply install the mysqlnd extension:

在这两个发行版中,一旦安装了php5元软件包,就已经准备好并配置了PDO。 您需要做的就是简单地安装mysqlnd扩展名:

sudo apt-get install php5-mysqlnd

视窗 (Windows)

You should try and use a Linux virtual machine for development on Windows, but in case you’re not up for it, follow the instructions below.

应该尝试使用 Linux虚拟机在Windows上进行开发,但是如果您不愿意使用它,请按照以下说明进行操作。

On Windows, you usually get the full lamp stack using Wamp or Xampp. You can also just download PHP straight from windows.php.net. Obviously, if you do the latter, you will only have PHP, and not the whole stack.

在Windows上,通常使用WampXampp获得完整的灯泡堆栈。 您也可以直接从windows.php.net下载PHP。 显然,如果您使用后者,则只会使用PHP,而不会使用整个堆栈。

In either case, if PDO isn’t already activated, you just need to uncomment it in your php.ini. Use the facilities provided in your lamp stack to edit php.ini, or in case of having downloaded PHP from windows.php.net, just open the folder you chose as your installation directory and edit php.ini. Once you do, uncomment this line:

无论哪种情况,如果尚未激活PDO,只需在php.ini取消注释即可。 使用灯架中提供的功能来编辑php.ini ,或者从windows.php.net下载PHP的情况下,只需打开您选择的文件夹作为安装目录并编辑php.ini 。 完成后,取消注释此行:

;extension=php_pdo_mysql.dll

从PDO开始:概述 (Beginning with PDO: a High-level Overview)

When querying your database using PDO, your workflow doesn’t change much. However, there are a few habits you must learn to drop, and others that you have to learn. Below are the steps you need to perform in your application to use PDO. We will explain each one in more detail below.

使用PDO查询数据库时,您的工作流不会有太大变化。 但是,您必须学习一些习惯,以及一些必须学习的习惯。 以下是您需要在应用程序中执行才能使用PDO的步骤。 我们将在下面更详细地解释每一个。

  • Connecting to your database

    连接到数据库
  • Optionally, preparing a statement and binding parameters

    (可选)准备语句和绑定参数
  • Executing the query

    执行查询

连接到数据库 (Connecting to your database)

To connect to your database, you need to Instantiate a new PDO object and pass it a data source name, also known as a DSN.

要连接到数据库,您需要实例化一个新的PDO对象 ,并将其传递给数据源名称(也称为DSN)。

In general, a DSN consists of the PDO driver name, followed by a colon, followed by the PDO driver-specific connection syntax. Further information is available from the PDO driver-specific documentation.

通常,DSN由PDO驱动程序名称,后跟冒号,后跟PDO驱动程序特定的连接语法组成。 可从PDO驱动程序特定的文档中获取更多信息。

For example, here is how you can connect to a MySQL database:

例如,以下是如何连接到MySQL数据库:

$connection = new PDO('mysql:host=localhost;dbname=mydb;charset=utf8', 'root', 'root');

The function above contains the DSN, the username, and the password. As quoted above, the DSN contains the driver name (mysql), and driver-specific options. For mysql, those options are host (in the ip:port format), dbname, and charset.

上面的函数包含DSN,用户名和密码。 如上所述,DSN包含驱动程序名称( mysql )和特定于驱动程序的选项。 对于mysql ,这些选项是host (以ip:port格式), dbnamecharset

查询 (Queries)

Contrary to how mysql_query() and mysqli_query() work, there are two kinds of queries in PDO: ones that return a result (e.g. select and show), and ones that don’t (e.g. insert, delete, and so on). Let’s look at the simpler option first: the ones that don’t.

mysql_query()mysqli_query()工作方式相反,PDO中有两种查询:一种返回结果(例如selectshow ),另一种不返回结果(例如insertdelete等)。 首先让我们看一个更简单的选项:那些没有的选项。

执行查询 (Executing queries)

These queries are very simple to run. Let’s look at an insert.

这些查询非常容易运行。 让我们看看一个插入。

$connection->exec('INSERT INTO users VALUES (1, "somevalue"');

Technically, I lied when I said that these queries don’t return a result. If you change the code above to the following code, you will see that exec() returns the number of affected rows:

从技术上讲,当我说这些查询不返回结果时,我撒谎了。 如果将上面的代码更改为以下代码,您将看到exec()返回受影响的行数:

$affectedRows = $connection->exec('INSERT INTO users VALUES (1, "somevalue"');
echo $affectedRows;

As you can probably guess, for insert statements, this value is usually one. For other statements though, this number varies.

您可能会猜到,对于插入语句,此值通常为1。 但是对于其他语句,此数字有所不同。

获取查询结果 (Fetching Query Results)

With mysql_query() or mysqli_query(), here is how you would run a query:

使用mysql_query()mysqli_query() ,这是运行查询的方式:

$result = mysql_query('SELECT * FROM users');

while($row = mysql_fetch_assoc($result)) {
    echo $row['id'] . ' ' . $row['name'];
}

With PDO, however, things are much more intuitive:

但是,使用PDO,事情会更加直观:

foreach($connection->query('SELECT * FROM users') as $row) {
    echo $row['id'] . ' ' . $row['name'];
}
提取模式: AssocNumObjclass (Fetching Modes: Assoc, Num, Obj and class)

Just as with the mysql and mysqli extensions, you can fetch the results in different ways in PDO. To do this, you must pass in one of the PDO::fetch_* constants, explained in the help page for the fetch function. If you want to get all of your results at once, you can use the fetchAll function.

mysqlmysqli扩展一样,您可以在PDO以不同的方式获取结果。 为此,您必须传入一个PDO::fetch_*常量,如fetch函数的帮助页面所述。 如果要一次获取所有结果,可以使用fetchAll函数。

Below are a few of what we think are the most useful fetch modes.

以下是一些我们认为最有用的获取模式。

  • PDO::FETCH_ASSOC: returns an array indexed by column name. That is, in our previous example, you need to use $row['id'] to get the id.

    PDO :: FETCH_ASSOC:返回按列名索引的数组。 也就是说,在我们之前的示例中,您需要使用$row['id']来获取id

  • PDO::FETCH_NUM: returns an array indexed by column number. In our previous example, we’d get the id column by using $row[0] because it’s the first column.

    PDO :: FETCH_NUM:返回由列号索引的数组。 在前面的示例中,我们将使用$row[0]获得id列,因为它是第一列。

  • PDO::FETCH_OBJ: returns an anonymous object with property names that correspond to the column names returned in your result set. For example, $row->id would hold the value of the id column.

    PDO :: FETCH_OBJ:返回一个匿名对象,该对象的属性名称与结果集中返回的列名称相对应。 例如, $row->id将保存id列的值。

  • PDO::FETCH_CLASS: returns a new instance of the requested class, mapping the columns of the result set to named properties in the class. If fetch_style includes PDO::FETCH_CLASSTYPE (e.g. PDO::FETCH_CLASS | PDO::FETCH_CLASSTYPE) then the name of the class is determined from a value of the first column. If you remember, we noted that PDO, at its simplest form, can map column names into classes that you define. This constant is what you would use to do that.

    PDO :: FETCH_CLASS:返回所请求类的新实例,将结果集的列映射到该类中的命名属性。 如果fetch_style包括PDO :: FETCH_CLASSTYPE(例如PDO :: FETCH_CLASS | PDO :: FETCH_CLASSTYPE),则从第一列的值确定类的名称。 如果您还记得,我们注意到PDO以其最简单的形式可以将列名映射到您定义的类中。 该常数就是您将要使用的常数。

Note: this list is not complete, and we recommend checking the aforementioned help page to get all of the possible constants and combinations.

注意 :此列表不完整,我们建议您查看上述帮助页面以获取所有可能的常数和组合。

As an example, let’s get our rows as associative arrays:

例如,让我们将行作为关联数组:

$statement = $connection->query('SELECT * FROM users');

while($row = $statement->fetch(PDO::FETCH_ASSOC)) {
    echo $row['id'] . ' ' . $row['name'];
}

Note: We recommend always choosing a fetch mode, because fetching the results as PDO::FETCH_BOTH (the default) takes twice as much memory, since PHP provides access to different column values both through an associative array and a normal array.

注意 :我们建议始终选择获取模式,因为将结果作为PDO::FETCH_BOTH (默认)来获取会占用两倍的内存,因为PHP可以通过关联数组和普通数组访问不同的列值。

As you might remember, above, when we were listing the advantages of PDO, we mentioned that there’s a way to make PDO store the current row in a class you have previously defined. You have probably also seen the PDO::FETCH_CLASS constant explained above. Now, let’s use it to retrieve the data from our database into instances of a User class. Here is our User class:

您可能还记得,上面列出了PDO的优点时,我们提到有一种方法可以使PDO将当前行存储在您先前定义的类中。 您可能还看到了上面解释的PDO::FETCH_CLASS常量。 现在,让我们使用它从数据库中检索数据到User类的实例中。 这是我们的User类:

class User
{

    protected $id;
    protected $name;

    public function getId()
    {
        return $this->id;
    }

    public function setId($id)
    {
        $this->id = $id;
    }

    public function getName()
    {
        return $this->name;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

}

Now, we can make the same query again, this time using our User class, which is, in these cases, also known as Model, Entity, or a plain old PHP object (taken from Plain Old Java Object in the world of Java).

现在,我们可以使用User类再次进行相同的查询,在这种情况下,该类也称为ModelEntity或普通的旧PHP对象(取自Java领域的Plain Old Java Object )。 。

$statement = $connection->query('SELECT * FROM users');

while($row = $statement->fetch(PDO::FETCH_CLASS, 'User')) {
    echo $row->getId() . ' ' . $row->getName();
}

准备好的语句和绑定参数 (Prepared Statements and Binding Parameters)

To understand parameter binding and its benefits, we must first look more deeply into how PDO works. When we called $statement->query() above, PDO internally prepared a statement, and executed it, returning the resulting statement to us.

要了解参数绑定及其好处,我们必须首先更深入地研究PDO的工作方式。 当我们在上面调用$statement->query()PDO内部准备了一条语句,并执行了该语句,并将结果语句返回给我们。

When you call $connection->prepare(), you are creating a prepared statement. Prepared statements are a feature of some database management systems that allow them to receive a query like a template, compile it, and execute it when they receive the value of placeholders – think of them as rendering your Blade or Twig templates.

调用$connection->prepare() ,您正在创建一个准备好的语句 。 准备好的语句是某些数据库管理系统的功能,使它们可以接收查询(如模板),对其进行编译并在收到占位符的值时执行该查询–将其视为呈现BladeTwig模板。

When you later on call $statement->execute(), you are passing in the values for those placeholders, and telling the database management system to actually run the query. It’s like calling the render() function of your templating engine.

稍后当您调用$statement->execute() ,您正在传递这些占位符的值,并告诉数据库管理系统实际运行查询。 就像调用模板引擎的render()函数一样。

To see this in action, let’s create a query that returns the specified id from the database:

为了了解这一点,让我们创建一个查询,该查询从数据库中返回指定的id

$statement = $connection->prepare('Select * From users Where id = :id');

The above PHP code sends the statement, including the :id placeholder, to the database management system. The database management system parses and compiles that query, and based on your configuration, may even cache it for a performance boost in the future. Now, you can pass in the parameter to your database engine and tell it to execute your query:

上面PHP代码将包含:id占位符的语句发送到数据库管理系统。 数据库管理系统会解析并编译该查询,并且根据您的配置,甚至可以将其缓存以提高性能。 现在,您可以将参数传递给数据库引擎,并告诉它执行查询:

$id = 5;
$statement->execute([
    ':id' => $id
]);

Then, you can fetch the result from the statement:

然后,您可以从语句中获取结果:

$results = $statement->fetchAll(PDO::FETCH_OBJ);

参数绑定的好处 (The Benefits of Parameter Binding)

Now that you are more familiar with how prepared statements work, you can probably guess at their benefits.

现在,您更加了解准备好的语句的工作方式,您可能会猜出它们的好处。

PDO has taken the task of escaping and quoting the input values you receive from the user out of your hands. For example, now you don’t have to write code like this:

PDO承担了转义和引用从用户那里收到的输入值的任务。 例如,现在您不必编写如下代码:

$results = mysql_query(sprintf("SELECT * FROM users WHERE name='%s'", 
        mysql_real_escape_string($name)
    )
) or die(mysql_error());

Instead, you can say:

相反,您可以说:

$statement = $connection->prepare('Select * FROM users WHERE name = :name');
$results = $connection->execute([
    ':name' => $name
]);

If that isn’t short enough for you, you can even make it shorter, by providing parameters that are not named – meaning that they are just numbered placeholders, rather than acting like named variables:

如果那还不够短,您甚至可以通过提供未named参数来缩短它的长度,这意味着它们只是带编号的占位符,而不是像命名变量一样起作用:

$statement = $connection->prepare('SELECT * FROM users WHERE name = ?');
$results = $connection->execute([$name]);

Likewise, having a prepared statement means that you get a performance boost when running a query multiple times. Let’s say that we want to retrieve a list of five random people from our users table:

同样,具有准备好的语句意味着多次运行查询时,性能会得到提高。 假设我们要从users表中检索五个随机人员的列表:

$numberOfUsers = $connection->query('SELECT COUNT(*) FROM users')->fetchColumn();
$users = [];
$statement = $connection->prepare('SELECT * FROM users WHERE id = ? LIMIT 1');

for ($i = 1; $i <= 5; $i++) {
    $id = rand(1, $numberOfUsers);
    $users[] = $statement->execute([$id])->fetch(PDO::FETCH_OBJ);
}

When we first call the prepare function, we tell our DBMS to parse, compile and cache our query. Later on in our for loop, we only send it the values for the placeholder – nothing more. This allows the query to run and return quicker, effectively decreasing the time our application would need in order to retrieve the results from the database.

首次调用prepare函数时,我们告诉DBMS解析,编译和缓存查询。 稍后在for循环中,我们仅将占位符的值发送给它-仅此而已。 这使查询可以更快地运行和返回,从而有效减少了我们的应用程序从数据库检索结果所需的时间。

You also might have noticed that I have used a new function in the piece of code above: fetchColumn. As you can probably guess, it returns the value of one column only, and is good for getting scalar values from your query result, such as count, sum, min, max, and other functions which return only one column as their result.

您可能还已经注意到,我在上面的代码段中使用了一个新函数: fetchColumn 。 您可能会猜到,它仅返回一列的值,并且非常适合从查询结果中获取标量值,例如countsumminmax和其他仅返回一列作为结果的函数。

将值绑定到IN子句 (Binding Values to an IN Clause)

Something that has a lot of people stumped when they first start to learn about PDO is the IN clause. For example, imagine that we allow the user to enter a comma-separated list of names that we store in $names. So far, our code is:

IN子句是很多人在刚开始了解PDO时遇到的困扰。 例如,假设我们允许用户输入以逗号分隔的名称列表,这些列表存储在$names 。 到目前为止,我们的代码是:

$names = explode(',', $names);

What most people do at this point is the following:

此时大多数人的操作如下:

$statement = $connection->prepare('SELECT * FROM users WHERE name IN (:names)');
$statement->execute([':names' => $names]);

This doesn’t work – you can only pass in a scalar value (like integer, string, and so on) to prepared statements! The way to do this is – you guessed it – to construct the string yourself.

这行不通–您只能将标量值(如整数,字符串等)传递给准备好的语句! 您猜到了,这样做的方法是自己构造字符串。

$names = explode(',', $names);
$placeholder = implode(',', array_fill(0, count($names), '?'));

$statement = $connection->prepare("SELECT * FROM users WHERE name IN ($placeholder)");
$statement->execute([$names]);

Despite its scary appearance, line 2 is simply creating an array of question marks that has as many elements as our names array. It then concatenates the elements inside that array and places a , between them – effectively creating something like ?,?,?,?. Since our names array is also an array, passing it to execute() works as expected – the first element is bound to the first question mark, the second is bound to the second question mark, and so on.

尽管看起来很恐怖,但第2行只是创建了一个问号数组,其中的元素与我们的names数组一样多。 然后,它串联该数组中的元素,并在它们之间放置一个,从而有效地创建诸如?,?,?,? 。 由于我们的names数组也是一个数组,因此将其传递给execute()正常工作-第一个元素绑定到第一个问号,第二个元素绑定到第二个问号,依此类推。

绑定参数时提供数据类型 (Providing Datatypes When Binding Parameters)

The techniques we showed above for binding values to parameters are good when you are just starting out to learn PDO, but it’s always better to specify the type of every parameter you bind. Why?

当您刚开始学习PDO ,上面显示的将值绑定到参数的技术很好,但是指定绑定的每个参数的类型总是更好。 为什么?

  • Readability: for someone reading your code, it’s easy to see what type a variable must be in order to be bound to a parameter

    可读性:对于阅读您的代码的人来说,很容易看到要绑定到参数的变量必须是什么类型
  • Maintainability: knowing that the first placeholder in your query must be an integer allows you to catch any errors that slip out. For example, if someone passes a variable containing test to your function which will then use that value to search for a particular id as an integer, having a datatype allows you to quickly find the error.

    可维护性:知道查询中的第一个占位符必须是整数,可以捕获任何遗漏的错误。 例如,如果有人将包含test的变量传递给函数,然后该函数将使用该值以整数形式搜索特定的id,那么使用数据类型可以让您快速找到错误。

  • Speed: when you specify the datatype of the variable, you are telling your database management system that there’s no need to cast the variable and that you’re providing it the correct type. In this way, you don’t have the (small) overhead that comes with casting between datatypes.

    速度:当您指定变量的数据类型时,您是在告诉数据库管理系统,无需强制转换变量,而您正在为其提供正确的类型。 这样,您就没有在数据类型之间进行转换所带来的(较小)开销。

To specify the type of each variable, I personally recommend the bindValue function. Let’s alter our code above to specify the type of our placeholder:

要指定每个变量的类型,我个人建议使用bindValue函数。 让我们更改上面的代码以指定占位符的类型:

$numberOfUsers = $connection->query('SELECT COUNT(*) FROM users')->fetchColumn();
$users = [];
$statement = $connection->prepare('SELECT * FROM users WHERE id = ? LIMIT 1');

for ($i = 1; $i <= 5; $i++) {
    $id = rand(1, $numberOfUsers);
    $statement->bindValue(1, $id, PDO::PARAM_INT);
    $statement->execute();
    $users[] = $statement->fetch(PDO::FETCH_OBJ);
}

As you can see, the only thing that has changed is our call to execute(): instead of passing in the values straight to it, we have bound it first, and have specified that its type is an integer.

如您所见,唯一改变的是我们对execute()调用:我们没有绑定直接的值,而是先绑定了它,并指定其类型为整数。

Note: You have probably noticed that we have specified the first parameter to bindValue() as 1. If we were using a named parameter (recommended), we would pass in the name of our parameter (e.g. :id). However, in the case of using the ? as a placeholder, the first argument to bindValue() is a number specifying which question mark you are referring to. Be careful – this is a 1-indexed position, meaning that it starts from 1, not 0!

注意 :您可能已经注意到,我们已将bindValue()的第一个参数指定为1 。 如果我们使用命名参数(推荐),我们将传入参数名称(例如:id )。 但是,在使用?的情况下 作为占位符, bindValue()的第一个参数是一个数字,用于指定您要引用的问号。 注意–这是一个1索引的位置,这意味着它从1开始,而不是0

结论 (Conclusion)

As PHP improves, so do programmers that use it. PDO is the next generation of extensions that allows you to write better code. It’s agile, fast, easy to read, and a delight to work with, so why not implement it in your own project?

随着PHP的改进,使用它的程序员也随之改进。 PDO是允许您编写更好代码的下一代扩展。 它敏捷,快速,易于阅读,并且易于使用,为什么不在自己的项目中实现它呢?

Have you implemented PDO into your existing project? What were the problems you faced? Are you glad you migrated over? What features do you miss? Let us know in the comments below!

您是否在现有项目中实施了PDO? 您遇到了什么问题? 高兴您迁移过来了吗? 您想念什么功能? 在下面的评论中让我们知道!

翻译自: https://www.sitepoint.com/re-introducing-pdo-the-right-way-to-access-databases-in-php/

php pdo数据库

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值