我真的应该使用 PDO 和准备好的语句吗?

发布于 2024-08-17 18:23:05 字数 149 浏览 2 评论 0原文

无论到目前为止我读了多少关于 PDO 和准备好的语句,我仍然感到有些困惑。所以我知道它们更“安全”,但这真的那么重要吗?我的意思是我可以使用基本 mysql 和 mysql_real_escape_string() 和 htmlspecialchars() 获得相同的最终结果,对吧?

PDO and prepared statements are still kind of confusing to me, no matter how much I read about them so far. So I know they are more "secure" but is it really that important? I mean I can get the same end result using basic mysql with mysql_real_escape_string() and htmlspecialchars() right?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

负佳期 2024-08-24 18:23:05

可以,但 PDO 和准备好的语句绝对是最安全的。您可以手动完成并使用 mysql_real_escape_string() 函数吗?当然。事实上,您的输出可能看起来相同。但最终,PDO 所需的代码将比手动完成的代码短得多。

此外,如果您不使用准备好的语句,则会面临人为错误的风险:比如您忘记转义值或清理输入。与所有其他代码混合在一起,没有正确清理的一行可能会在以后成为一场噩梦。

希望这有帮助!

You could, but PDO and prepared statements are the absolute safest. Could you do it by hand and use the mysql_real_escape_string() function? Sure. In fact, your output might look identical. But in the end, the code that PDO would require would be a hell of a lot shorter than the code if you had done it manually.

Also, if you aren't using prepared statements, you run the risk of human error: say you forget to escape a value or sanitize an input. Mixed in with all of your other code, the one line that isn't properly sanitizing could crop up to be a nightmare down the road.

Hope this helps!

快乐很简单 2024-08-24 18:23:05

我真的很喜欢 PDO 界面。一旦你习惯了它,它比 mysql_* 函数风格干净得多。我也花了一段时间才弄清楚,但这是值得的。

我发现令人困惑的部分是记住哪些方法属于 PDO DB 连接对象本身,哪些是语句对象的一部分。

通过某些操作,您还可以通过重复准备好的语句来获得性能优势。例如,如果您在循环中执行大量插入,则可以准备语句,然后每次插入之前在循环中绑定新数据。

安全性也好得多,因为您依赖于经过良好测试的库来转义每次插入时的数据。这就像密码学——既然如此重要,为什么要自己做呢?没有理由给自己犯错的机会(即意外地错过转义插入查询中的内容)。

我向 PDO 推荐 本指南,来自编写此关于Mysql的优秀巨著

我喜欢使用位置参数风格,然后你只需创建一个数据数组并将其传入。我的查询看起来像

$pdo_db=pdo_connect('cow_db');
$sql='select this,that,count(those) as snout from lovely_table where name=? and horses=?';
$data=array($username,$horse_count);

$query_stmt=$pdo_db->prepare($sql);
$result_handle=$query_stmt->execute($data);

//then I have a function to load data from the result handle
$info=load_array($result_handle);

你可以使这样的函数与标准 php mysql 接口一起使用,但为什么不直接使用 PDO 呢?

I really like the PDO interface. Once you get used to it, it's a lot cleaner than the mysql_* function style. It took me a while to figure it out, too, but it's worth it.

The part that I found confusing was remembering what methods belong to the PDO DB connection object itself, and which are part of the statement objects.

With certain actions, you'll get a performance benefit from repeating prepared statements, too. For instance, if you're doing a bunch of inserts in a loop, you can prepare the statement, and then bind new data in the loop each time before inserting.

The security is much better too, in that you are relying on a well tested library to escape your data on each insert. It's like cryptography - why do it yourself, when it's something this important? There's no reason to give yourself a chance to get it wrong (i.e., accidentally miss escaping something inserted into a query).

I recommend this guide to PDO, from the author who wrote this excellent giant book on Mysql.

I like to use the positional parameter style, and then you just make an array of the data and pass it in. My queries look like

$pdo_db=pdo_connect('cow_db');
$sql='select this,that,count(those) as snout from lovely_table where name=? and horses=?';
$data=array($username,$horse_count);

$query_stmt=$pdo_db->prepare($sql);
$result_handle=$query_stmt->execute($data);

//then I have a function to load data from the result handle
$info=load_array($result_handle);

You could make functions like this to work with the standard php mysql interface, but why not just use PDO?

傲娇萝莉攻 2024-08-24 18:23:05

我同意其他人的观点,他们认为使用准备好的查询通常比使用转义函数更好。它更容易正确使用,并且参数值不会引入 SQL 注入问题,因为该值与 SQL 查询分开发送到 RDBMS 服务器。

但是,仅当 SQL 查询的动态部分是代替表达式中的文字值的参数时,使用参数才有用。您不能使用查询参数来代替表名、列名、SQL 表达式或值列表(例如 IN( ) 谓词的参数)。

准备好的查询还比非准备的查询具有更好的性能(至少在 MySQL 中)。大多数人的说法相反,但备受推崇的 mysqlperformanceblog.com 进行了测试:

http://www.mysqlperformanceblog.com/2006/08/02/mysql-prepared-statements/

I agree with others who say using prepared queries is generally better than using escaping functions. It's easier to use correctly, and there's no way that parameter values can introduce SQL injection problems, since the value are sent to the RDBMS server separately from the SQL query.

However, using parameters is useful only when the dynamic parts of your SQL query is a parameter in lieu of a literal value in an expression. You can't use a query parameter in place of a table name, column name, an SQL expression, or a list of values (e.g. arguments of an IN( ) predicate).

Prepared queries also have better performance than non-prepared queries (at least in MySQL). Most people say the opposite, but the well-respected mysqlperformanceblog.com did the testing:

http://www.mysqlperformanceblog.com/2006/08/02/mysql-prepared-statements/

雪化雨蝶 2024-08-24 18:23:05

只要您为查询适当地清理数据,就不必使用 PDO/准备好的语句。 不过,我个人建议使用 PDO/prepared 语句,因为它们确实使开发/调试变得更容易,并且准备好的语句甚至可以防止不正确的数据类型进入查询。

如果您想了解有关如何创建简单的准备好的语句的更多信息,请查看函数 sprintf。您只需用类型说明符替换任何变量字符串、整数等(在本例中分别为 %s%d)。

例如,在下面的查询中,我知道 id 将是一个整数(它将是数字),而 name 将是一个字符串(字母数字)。

$username = 'Simon';
$id       = 3;
$query    = "SELECT FROM `users` WHERE `id` = {$id} AND `name` = '{$username}'";

如果我从不受信任的来源(例如 POST/GET)获取这些变量中的任何一个,那么我可以通过用 替换最后一行($query 集)来确保它们是正确的数据类型sprintf 调用如下:

$username = 'Simon';
$id       = 3;
$query    = sprintf( "SELECT FROM `users` WHERE `id` = %d AND `name` = '%s'", $id, $username );

sprintf 不会让我在调用时使用字符串作为 $id 或使用整数作为 $name,以确保给出正确的数据类型(这给了我一点额外的安全感)。如果给出了不正确的数据类型,那么我相信它将把变量转换为请求的类型。

要了解有关 sprintf 的更多信息,请访问此处:http://php.net/sprintf

我希望这足以解释(这是我的第一个答案):)。

As long as you sanitize data appropriately for your queries then you don't have to use PDO/prepared statements. Though, I would personally recommend using PDO/prepared statements simply because they do both make development/debugging easier and prepared statements prevent incorrect data types from even getting in to a query.

If you want to learn more about how to create a simple prepared statement look in to the function sprintf. You simply replace any variable strings, integers, etc with a type specifier (in this case %s and %d respectively).

So for example in the following query, I know that id is going to be an integer (it will be numerical) and name will be a string (alphanumeric).

$username = 'Simon';
$id       = 3;
$query    = "SELECT FROM `users` WHERE `id` = {$id} AND `name` = '{$username}'";

If I'm getting either of this variables from an un-trusted source (such as a POST/GET) then I can make sure they are the correct data types by replacing the final line (the $query set) with a sprintf call like this:

$username = 'Simon';
$id       = 3;
$query    = sprintf( "SELECT FROM `users` WHERE `id` = %d AND `name` = '%s'", $id, $username );

sprintf will simply not let me use a string for the $id or an integer for the $name when it is called which ensures the correct types of data are given (this gives me that little extra bit of security). IF incorrect data types ARE given then I believe it'll cast the variables to the requested type.

To read more about sprintf visit here: http://php.net/sprintf

I hope this explains enough (it's my first answer) :).

夜夜流光相皎洁 2024-08-24 18:23:05

你可以尝试 zend_db 它在底层使用 pdo 。 (mdb2 是您可以使用的另一个选项。)

you could try zend_db which uses pdo under the hood. (mdb2 is another option you can use.)

岁月蹉跎了容颜 2024-08-24 18:23:05

PHP 可以让您做任何您想做的事情,而 PDO 恰好可以用更少的代码做“您想做的”事情。 :)

PHP lets you do anything you want, and it just so happens PDO does what "you want" with a lot less code. :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文