0

これは私の PDO への挿入方法です。100% 動作しています。この「挿入」メソッドは、テーブル、列、および値を受け入れますが、用途が広いようにしたいと考えています。(列名の有無にかかわらず値を挿入したい)

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"));
4

1 に答える 1

1

あなたの機能には2つの問題があります。

  1. SQL インジェクションに対して脆弱です。
  2. 柔軟ではありません。このパターンに従うと、この種の関数が 1000 もあることになり、コードがごちゃごちゃになります。それでも、実際の SQL に対して常に限定されたサブセットになります。

本当に必要なのは、配列と許可されたフィールドのリストから SET ステートメントを作成できる関数です。さらなる改善として、このステートメントのカスタムプレースホルダー
を 考案することができます。

これら 2 つのものがあれば、次のようにすべての DML クエリを実行する単一の汎用関数を作成できます。

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

追加で 3 単語 (insert、into、set) がかかりますが、

  • 読み取り可能。誰でも SQL を理解できます。関数を読むにはドキュメントが必要です
  • フレキシブル。1 つの単一形式の挿入だけでなく、任意のクエリと修飾子をサポートできます。

この単一の関数で実行できるすべてのクエリ:

$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);
于 2013-07-17T08:46:56.400 に答える