【发布时间】:2015-12-08 06:41:01
【问题描述】:
我正在用 PHP 构建一个自定义 CMS,并且我想从一个数组生成 MySQL。我猜这不是最安全的做法,因为我会将变量直接放入准备好的语句中。我希望更有经验的人可以看看我到目前为止所做的事情,并让我了解如何使这更安全。
这是我存储所有数据操作方法的类
abstract class MySQLData extends MySQLDataHelper {
// connection to database
abstract public function getConn();
// table name from concrete class
abstract public function getTable();
public function insert( $args ) {
try {
$stmt = $this->getConn()->prepare( $this->generateInsertSQL( $args ) );
foreach ($args as $arg => &$value) {
$stmt->bindParam(":{$arg}", $value);
}
$stmt->execute();
} catch (PDOException $e) {
echo "Insert error: " . $e->getMessage();
}
}
//............................................
// More methods below, including delete, select and update, but lets focus on 'insert' only to keep things simple.
}
Helper方法类,包括插入SQL生成器
abstract class MySQLDataHelper {
public function generateInsertSQL( $args ) {
$columns = array_keys( $args );
$placeholders = implode(', :', $columns);
$columns = implode(', ', $columns);
return "INSERT INTO `{$this->getTable()}` ({$columns}) VALUES (:{$placeholders})";
}
}
示例用例
require_once 'core/Pages.php';
$pages = new Pages( $db->conn() ); // Pages extends MySQLData
$args = array(
'name' => 'New page',
'content' => 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Quisquam, laboriosam!',
'enabled' => true);
$pages->insert( $args );
请注意,在这种情况下 generateInsertSQL 的输出将是:
INSERT INTO `pages` (name, content, enabled) VALUES (:name, :content, :enabled)
提醒,这段代码运行良好,我只是想知道它是否可以变得更安全。
谢谢。如果这是一个不好的问题或在错误的地方,我很抱歉。
【问题讨论】:
-
$args会来自用户输入吗? -
“这段代码工作得很好,我想知道它是否可以变得更安全。” - 不要上网。如果适用,请考虑 XSS 注入。
-
如何更安全?除非你做一些愚蠢的事情,比如
$args['\'; drop table students; --'] = 'haha im in ur query injecting ur tablez'... -
谢谢你们。 @Rocket Hazmat,是的,这将是来自管理面板中表单的用户输入。请注意,我当然会清理该输入,所以它更像是: $args = array('name' => filterInput($_POST['name']));
-
你考虑过使用RedBean吗?我强烈推荐它。我曾经担心 SQL 注入和许多其他问题,直到我发现通过 ORM 可以更轻松地进行数据库操作,并且不太容易出现开发人员错误。