从mysql_query切换到PDO的问题

时间:2011-04-22 07:57:46

标签: php mysql pdo magic-quotes

我从传统的mysql_query()参数化查询切换到PDO,以利用它的安全优势,我有几个问题。首先,就magic_quotes而言,还有什么需要做的吗?这个网络应用程序将安装在不同配置的系统上,有些人(不幸的是)将它们打开,而其他人将关闭。以前我正在向addslashes()发送完整的if语句,当它输入数据时......需要对这些PDO查询做些什么:

$dbh = new PDO("mysql:host=$db_server;dbname=$db_database", $db_username, $db_password);
$sth = $dbh->prepare("SELECT * FROM `users` WHERE `username` = :username ");
$sth->bindParam(':username', $_POST['username']);
$sth->execute();
if($row = $sth->fetch()){
    // Yup
}
$dbh = null;

另外,最后关闭数据库处理程序有多大必要?不这样做有什么不利?对于将安装在许多不同服务器设置上的CMS,PDO是否是一个很好的选择? PDO是否普遍适用于大多数服务器上的启用?

提前致谢!

2 个答案:

答案 0 :(得分:4)

  

这个网络应用程序将安装在不同配置的系统上,有些人(不幸的是)会有[魔术引号],而其他人则会关闭。

正如我在另一个答案的评论中所指出的那样,PHP手册有an entire section处理恐怖魔法引用。您通常可以在.htaccess中本地禁用它。或者在数据进入时更正数据。我个人不会与默认启用它的托管服务提供商做生意。

  

以前,当我关闭输入数据时,我正在对addslashes()执行整个if语句

糟糕! addslashes 是足够的保护。使用旧的MySQL扩展时,需要在设置字符集后使用mysql_real_escape_string Failing to do this can leave you open to a huge vulnerability

  

......需要对这些PDO查询做些什么:

除了设置连接字符集外,什么都没有! PDO将尽可能使用真实的准备语句。这意味着它将首先将带有占位符的查询发送到服务器,以便它可以处理它,然后它将分别发送参数。这使查询免受SQL注入。

(有些数据库不支持使用PDO准备好的语句。对于这些,PDO将处理查询,用带引号的转义值替换占位符。结果是相同的 - 免于SQL注入。)

  

另外,最后关闭数据库处理程序有多大必要?不这样做有什么不利?

就像其他PHP数据库处理程序一样,不需要关闭连接 - 当脚本结束时,连接将关闭。 (Don't even think about persistent connections。)

  

对于将安装在许多不同服务器设置上的CMS,PDO是否是一个不错的选择? PDO是否普遍适用于大多数服务器上的启用?

PDO在PHP 5.1中成为标准,但这并不意味着它始终可用。大多数Linux发行版都拆分了所有的PHP数据库访问选项,以便安装它们也会安装必需的库。有时,无能或缺乏经验的托管服务提供商不会安装PDO软件包以配合其他数据库访问选项,而不会意识到他们正在做什么。这通常只需要求他们启用PDO,并在他们不愿意或无法使用时切换到其他主机来纠正。

许多现代框架更喜欢在PDO之上构建,但提供其他选项。例如,Zend Framework's Zend_Db具有适用于PDO,mysqli和其他一些适配器的适配器。如果您担心PDO并不总是可用,那么使用适配器层可能对您有用。 (与大多数ZF组件一样,Zend_Db不会严重依赖其他ZF组件,这意味着您可以轻松地将其与代码捆绑在一起。)

答案 1 :(得分:3)

我不会过分担心magic_quotes。 PDO是在PHP 5.1中引入的,默认情况下magic_quotes默认关闭一段时间。应该有非常非常少的主机支持PDO但启用了magic_quotes。

如果您仍想处理这么小的百分比,我建议您只需要使用$ _GET,$ _POST和$ _COOKIE全局变量,并删除magic_quotes添加的斜杠。或者,如果您不想直接更改它们,请将它们包装在某些类型的Request对象中。