2016-11-28 10 views
2

これは完璧ではありませんが、MySQLIを使用してSQLテーブルにデータを挿入する関数を作成しようとしています。私は、さまざまな種類のデータを異なるデータベースに挿入する汎用関数を作成したいと考えています。私はこれまでのところ次のようなことがあります:MYSQLIで指定されていない長さの配列を挿入

/** 
* Add data to specified table. Data consist of column name as key, and value. 
* Table is a string of the table to insert into. 
* @param array $data 
* @param string $table 
* @return string 
*/ 
private function insert($data = array(), $table = null){ 

    foreach($data as $key => $value){ 

     // Create arrays of separate keys and values 
     $keys[]  = $key; 
     $values[] = $value; 

     // Get type of data 
     switch(gettype($value)){ 
      case "integer": 
       $types[] = "i"; 
       break; 
      case "string": 
       $types[] = "s"; 
       break; 
      default: 
       $types[] = "i"; 
       break; 
     }; 

     // for each variable, add a questionmark 
     $vars[]  = "?"; 

    } 

    // Create strings out of the data 
    $key = implode(",", $keys); 
    $var = implode(",", $vars); 
    $type = implode("", $types); 
    $value = '"' . implode('\", \"', $values) . '"'; 

    // prepare SQL statement 
    // var_dump($sql) = 'INSERT INTO table (var1,var2,var3) VALUES (?,?,?)' 
    $sql = "INSERT INTO " . $table . " (" . $key . ") VALUES (" . $var . ")"; 

    // Prepare SQL insert 
    // $this->conn = new mysqli($this->server, $this->user, $this->pass, $this->name); 
    if(! ($stmt = $this->conn->prepare($sql))) { 
     return "Preparing failed!: (" . $this->conn->errno . ") " . $this->conn->error; 
    } 

    // Bind parameters. THIS IS WHERE THE ISSUE IS! 
    if(! $stmt->bind_param($type, $values)) { 
     return "Binding failed! (" . $stmt->errno . ") " . $stmt->error;; 
    } 

    // Execute the statement 
    if(! $stmt->execute()){ 
     return "Executing failed! (" . $stmt->errno . ") " . $stmt->error;; 
    } 

} 

問題はパラメータをバインドすることです。値とキーを持つ複数の変数があるので、私はそれらを束縛する良い方法を見つけることができません。bind_paramにはそれぞれ新しい変数が必要です

つまり、私のSQLに不特定の長さの配列を追加する方法を探しています(安全な方法で)。

+0

参考までに、このコードはSQLインジェクションに対して脆弱です。 –

+0

ありがとう、私はまだそれを調べなければなりません。私はまだそれに多くの時間をかけていないので、それを認識しています。それはおそらく書いている間にそれを行う方が良いですが、私はまだそれに取り組んでいました。しかし頭をありがとう! –

答えて

3

、あなたは、配列を展開する...演算子を使用することができます。あなたの例では

$stmt->bind_param($type, ...$values) 

manual例#14を参照してください。

+1

うわー、もしこれがわかっていれば、これは簡単でした!これは素晴らしいものです。ありがとう。 –

+1

それは '...'遠くの鐘を鳴らして、私は覚えていない...ああ待ってちょうだい(私はこれを入力していたので、それは私に戻ってきた); PERL/CGI。私は何年も前に仕事をしていたことに対して、その正確な構文を使っていました。 PHPでこれを使うことができます。編集:それからもう一度、それは '..' * lol *だったかもしれませんが、それは十分に近いです;-) –

+0

@ Fred-ii- PERL/CGIはそれ以上ではないことを嬉しく思います。 – jeroen

1
/* Bind parameters. Types: s = string, i = integer, d = double, b = blob */ 
$a_params = array(); 

$param_type = ''; 
$n = count($a_param_type); 
for($i = 0; $i < $n; $i++) { 
    $param_type .= $a_param_type[$i]; 
} 

/* with call_user_func_array, array params must be passed by reference */ 
$a_params[] = & $param_type; 

for($i = 0; $i < $n; $i++) { 
    /* with call_user_func_array, array params must be passed by reference */ 
    $a_params[] = & $a_bind_params[$i]; 
} 

/* Prepare statement */ 
$stmt = $conn->prepare($sql); 
if($stmt === false) { 
    trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->errno . ' ' . $conn->error, E_USER_ERROR); 
} 

/* use call_user_func_array, as $stmt->bind_param('s', $param); does not accept params array */ 
call_user_func_array(array($stmt, 'bind_param'), $a_params); 

/* Execute statement */ 
$stmt->execute(); 

/* Fetch result to array */ 
$res = $stmt->get_result(); 
while($row = $res->fetch_array(MYSQLI_ASSOC)) { 
    array_push($a_data, $row); 
} 

参考:あなたは、PHP 5.6+を使用している場合http://www.pontikis.net/blog/dynamically-bind_param-array-mysqli

+0

非常に良い解決策ですが、Jeroenによって与えられたほど簡単ではありません。 –

関連する問題