【发布时间】: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