PDO类的通用插入方法

时间:2013-07-17 08:28:36

标签: php mysql oop pdo prepared-statement

这是我在PDO中的插入方法,它正在100%工作。这个'insert'方法接受表,列和值,但我想让它变得多才多艺。 (我想插入带或不带列名的值)

public function insert($table, $pair = array()){
    try{
        $Sql = "INSERT INTO $table ( ";
        $Sql .= implode(", ", array_keys($pair));
        $Sql .= " )";
        $Sql .= " VALUES (";
        $Sql .= implode(", ", array_fill("0", count($pair), " ?"));
        $Sql .= " )";
        $array = array_combine(array_keys(array_fill("1", count($pair), ":")), $pair);
        $ready = $this->conn->prepare($Sql);
        foreach($array as $key => $value)
        {
            $ready->bindValue($key, $value, PDO::PARAM_STR);
        }
        $ready->execute();
    }
    catch(Exception $e){
        $this->trace .= " • ". $e->getMessage();  
    }
}


$new = new community();
echo $new->insert("table", array("Col1" => "value1", "col1" => "value1"));

1 个答案:

答案 0 :(得分:1)

您的功能有两个问题。

  1. 易受SQL注入攻击。
  2. 不灵活。按照这种模式,你将拥有这样的一千种功能,这将使你的代码陷入混乱。然而,对于真正的SQL,它总是有限的子集。
  3. 您真正需要的是一个可以从数组中创建SET语句的函数和一个允许字段列表。
    作为进一步的改进,您可以为此语句设计自定义占位符

    有了这两件事,您可以设计一个单个通用函数来运行所有DML查询,如下所示:

    $db->query("INSERT INTO t SET %u", array("Col1" => "value1", "col1" => "value1"));
    

    它将花费你额外的3个单词(插入,插入和设置),但它将是

    • 可读。每个人都可以理解SQL。在阅读您的功能时需要一份文档
    • 柔性的。它可以支持任何查询和修饰符,而不仅仅是一个单一形式的插入。

    您希望使用此单一功能运行的每个查询:

    $data = array("Col1" => "value1", "col1" => "value1");
    $db->query("INSERT IGNORE INTO t SET %u", $data);
    $db->query("REPLACE INTO t SET %u", $data);
    $db->query("DELETE FROM t WHERE id = ?", $id);
    // and so on
    

    实际上不需要专用功能。

    此外,您必须始终针对硬编码的白名单验证一组字段,以允许用户仅插入允许的字段。不要让用户改变权限,消息计数等等。

    但即使没有自定义占位符,它也不需要一组SQL映射函数,只需要创建SET和通用查询执行函数的函数:

    $allowed = array("name","surname","email"); // allowed fields
    $sql = "INSERT INTO users SET ".pdoSet($fields,$values);
    $stm = $dbh->query($sql ,$values);