2012-02-04 160 views
3

我正在使用PDO將表單值插入到帶有PDO的mysql數據庫中的PHP類方法。這個想法概述如下,但我不知道如何傳遞方法的第四個參數。有人可以解釋如何做到這一點?PHP PDO插入方法

謝謝!

<?php 
class Contact { 
    private $DbHost = DB_HOST; 
    private $DbName = DB_NAME; 
    private $DbUser = DB_USER; 
    private $DbPass = DB_PASS; 

    public function MySqlDbInsert($DbTableName, $DbColNames, $DbValues, $DbBindParams){ 
    try{ 
     $dbh = new PDO("mysql:host=$this->DbHost;dbname=$this->DbName",$this->DbUser,$this->DbPass, array(PDO::ATTR_PERSISTENT => true)); 
     $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
     $dbh->exec("SET CHARACTER SET utf8"); 

     $sth = $dbh->prepare("INSERT INTO $DbTableName($DbColNames) VALUES ($DbValues)"); 
     // i know this is all wrong ---------------- 
     foreach($DbBindParams as $paramValue){ 
      $sth->bindParam($paramValue); 
     } 
     // ---------------------------------------- 
     $sth->execute(); 
    } 
    catch(PDOException $e){ 
     $this->ResponseMessage(true, 'Database access FAILED!'); 
    } 
} 

$object = new Contact(); 
$object->MySqlDbInsert(
    'DbTableName', 
    'DbColName1, DbColName3, DbColName3', 
    ':DbColValue1, :DbColValue2, :DbColValue3', 
    // this part is all wrong ------------------- 
    array(
    ':DbColValue1', $col1, PDO::PARAM_STR, 
    ':DbColValue2', $col2, PDO::PARAM_STR, 
    ':DbColValue2', $col3, PDO::PARAM_STR 
    ) 
    // ------------------------------------------ 
); 
+1

接受的代碼很容易受到SQL注入 – 2013-02-25 13:10:53

回答

10

動態插入PDO我使用下面的函數。

使用這個傳遞數組格式的值,以功能:

<?php 
class Contact 
{ 
    private $UploadedFiles = ''; 
    private $DbHost = DB_HOST; 
    private $DbName = DB_NAME; 
    private $DbUser = DB_USER; 
    private $DbPass = DB_PASS; 
    private $table; 

    function __construct() 
    { 
     $this->table = strtolower(get_class()); 
    } 

    public function insert($values = array()) 
    { 
     $dbh = new PDO("mysql:host=$this->DbHost;dbname=$this->DbName", $this->DbUser, $this->DbPass, array(PDO::ATTR_PERSISTENT => true)); 
     $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 
     $dbh->exec("SET CHARACTER SET utf8"); 

     foreach ($values as $field => $v) 
      $ins[] = ':' . $field; 

     $ins = implode(',', $ins); 
     $fields = implode(',', array_keys($values)); 
     $sql = "INSERT INTO $this->table ($fields) VALUES ($ins)"; 

     $sth = $dbh->prepare($sql); 
     foreach ($values as $f => $v) 
     { 
      $sth->bindValue(':' . $f, $v); 
     } 
     $sth->execute(); 
     //return $this->lastId = $dbh->lastInsertId(); 
    } 

} 

並使用它:

$contact = new Contact(); 
$values = array('col1'=>'value1','col2'=>'value2'); 
$contact->insert($values); 
+4

這個代碼是容易受到SQL注入 – 2013-02-25 13:10:29

+1

@Your常識你能解釋一下這個代碼是如何脆弱,我所知道的是他已經習慣了準備,參數化的語句的字符集。 – 2013-07-15 22:16:58

+2

他不使用準備好的語句,而是使用老式的連接。 – 2013-07-16 05:16:02

4

我會使用的陣列。也許是這樣的:

public function MySqlDbInsert($DbTableName, $values = array()) 
{ 
    try{ 
     $dbh = new PDO('.....'); 

     // Specify the tables where you can insert 
     $allowedTables = array('table_1', 'table_2', 'table_3'); 

     // Specify allowed column names 
     $allowedColumns = array('age', 'city', 'address'); 

     if (!in_array($DbTableName, $allowedTables)) 
      throw new Exception('Invalid Table Given!'); 

     $columns = array_keys($values); 
     foreach ($columns as $c) 
     { 
      if (!in_array($c, $allowedColumns)) 
       throw new Exception('The column ' . $c. ' is not allowed'); 
     } 

     $sql = 'INSERT INTO ' . $DbTableName; 
     $sql .= '(' . implode(',', $columns) . ') '; 
     $sql .= 'VALUES (' . implode(',', array_fill(0, count($values), '?')) . ')'; 

     $sth = $dbh->prepare($sql); 
     $sth->execute(array_values($values)); 
    } 
    catch(PDOException $e){ 
     $this->ResponseMessage(true, 'Database access FAILED!'); 
    } 
    catch(Exception $e) { $this->ResponseMessage(true, $e->getMessage()); } 
} 

$contact->MySqlDbInsert('table_name', array('colname1' => 'value1', 'colname2' => 'value2', 'colname3' => 'value3')); 

不過,所有的值都會被轉義爲「PDO :: PARAM_STR」。

+2

這段代碼很容易被SQL注入 – 2013-02-25 13:10:10

+1

只有讓用戶指定列名或表名(如果他這樣做,而不是他缺少暱稱),它才容易受到攻擊。另一方面,我更新了代碼,照顧這個問題。 – mpratt 2013-03-04 14:35:34

+0

@mpratt Nope,正確準備的PDO語句使用$ sth-> bindParam()或bindValue()將任何參數插入到語句中,而不是在饋入prepare()的字符串中。 – dotVezz 2015-12-07 14:52:06