【问题标题】:PDO escaping with imploding array'sPDO 与内爆数组一起逃逸
【发布时间】:2016-12-21 03:39:59
【问题描述】:

我目前正在学习 PDO(从 MySQLi 转移),因为 MySQLi 的预处理语句是,让我们说“sucky”。但是,我以前从未在此级别上完全尝试过 PDO。我正在尝试创建一个 PDO 数据库类,其中包含多个常用函数,以根据函数的给定信息构建查询。

这是我的 delete() 函数,用于从表中删除一行:

public function delete( $table, $where = array(), $limit = '' ) {
    $holders = array();
    $params = array();
    foreach( $where as $field ) {
        $holders[] = '?';
    }

    foreach( $where as $field => $value ) {
        $value = $value;
        $clause[] = "$field = " . implode( '', array_values( $holders  ) ) . "";
        $params[] = $value;
    }

    $table = $this->prepend_table( $table );

    $sql = "DELETE FROM {$table} WHERE " . implode( 'AND ', $clause );
    if( !empty( $limit ) ) {
        $sql .= " LIMIT {$limit}";
    }

    try {
        $stmt = $this->connection->prepare( $sql );
        $stmt->execute( $params );
        return true;
    } catch( PDOException $e ) {
        die( 'Query Error: ' . $e->getMessage() );
        exit;
    }
}

如您所见,我正在从 MySQL 语句中的参数中分解数组,然后准备并执行已构建的查询。

现在,在我之前的问题中,有人提到使用 implode() 和准备语句 - 就像我上面所说的那样,非常危险,我应该对 PDO 使用“escape”。现在,我知道 MySQLi 有 real_escape_string,但我将如何处理我的删除(和其他函数)并尽可能保证它的安全。

由于我是 PDO 的新手,如果我遗漏了任何检查(或我可以做的任何其他事情以确保其安全),请告诉我 - 一旦完成,我将询问代码审查基地审查我的课程以确保它是安全的。

【问题讨论】:

  • 您需要验证$limit 是一个数值并且$table 是一个合法的表名(您的prepend_table 函数可能会这样做吗?)。但就转义而言,如果您使用查询参数,则不需要转义这些字段;这就是使用查询参数的重点。好吧,无论如何,整个观点的很大一部分。
  • 很高兴您尝试自己做某事。这让我想起了几年前我尝试这样做的时候(它确实有效,现在仍然有效,但语法很复杂;for reference pastebin)。我最终编写了一个全新的类来构建查询(类似于 Laravel 的 querybuilder 类)。我建议您查看Doctrine 或将任何其他开源 PDO 包装器作为您自己项目的参考。

标签: php arrays mysqli pdo escaping


【解决方案1】:

请注意,因为您使用的是准备好的语句,根据 PHP 文档中的引用,您不需要这样做。

如果您使用此函数构建 SQL 语句,强烈建议您使用 PDO::prepare() 来准备带有绑定参数的 SQL 语句,而不是使用 PDO::quote() 将用户输入插入到 SQL 语句中.带有绑定参数的预处理语句不仅更便携、更方便、不受 SQL 注入的影响,而且执行起来通常比插值查询快得多,因为服务器端和客户端都可以缓存查询的编译形式。

这样就可以避免整个转义过程。

但是,供您参考的是 PDO 的 quote 函数,

<?php
$conn = new PDO('sqlite:/home/lynn/music.sql3');

/* Simple string */
$string = 'Nice';

echo 'Unquoted string: ' . $string . '\n';
echo 'Quoted string: ' . $conn->quote($string) . '\n';
?>

输出

Unquoted string: Nice
Quoted string: 'Nice'

【讨论】:

  • 好的,如果我理解正确的话,我想使用 PDO 的报价,然后将它们放入一个数组中?
  • “他们”我的意思是?参数
  • 没有。再次阅读第一部分和报价!你不需要使用它。
  • 是的,我做到了。我读到的是我不需要这样做,因为我正在使用 prepare() 来保护查询。
猜你喜欢
  • 2015-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多