2017-06-26 13 views
-2

私はtextarea要素を追加したり削除したりすることができる動的なフォームを持っています。私はこれらの要素をforループでMySQLデータベースに挿入しようとしています。

<?php 

//if upload button is pressed 
if (isset($_POST['upload'])) { 

    //connect to the database 
    $db = mysqli_connect('', '', '', ''); 

    $sql = "INSERT INTO table (paragraph) VALUES ('$paragraph')"; 

    $i = 0; 
    foreach ($_POST as $value){ 
     $paragraph = $_POST['paragraph'][$i]; 
     mysqli_query($db, $sql); 
     $i++; 
    } 

    header("location: form.php"); 
    exit; 

} 

?> 

<html> 
<body> 

    <form method="post" action="form.php"> 

     <input type="submit" name="upload" value="Upload" id="upload"> 

    </form> 

    <button onclick="addParagraph()">Add Paragraph</button> 



</body> 
</html> 

<script> 

//add paragraph div 
function addParagraph() { 
    $("form").append('<div><textarea name="paragraph[]"></textarea><button class="remove">Remove</button></div>'); 
} 

//remove paragraph div 
$(document).on('click', ".remove", function(e) { 
    $(this).parent().remove(); 
}); 



</script> 

残念ながら、これは空のフィールドをデータベースに入力するようです。私は問題がPHPコード内のループforeachで発生すると考えています。

+1

SQLインジェクションを防ぐために準備されたステートメントについて学ぶ – Jens

答えて

3

元のSQL並べ替えを防ぐために準備された文について学ぶ

:私は私のコメントで示唆したように

foreach ($_POST['paragraph'] as $value){ 
     $paragraph = value[$i]; 
     $sql = "INSERT INTO table (paragraph) VALUES ('$paragraph')"; 
     mysqli_query($db, $sql); 
     $i++; 
    } 

はあなたのループ内でステートメントを配置する必要がありますprepared statementsを使用しようとしましたが、SQLインジェクションに脆弱でした。このようなことができるはずです:

if (isset($_POST['upload'])) { 

    //connect to the database 
    $db = mysqli_connect('', '', '', ''); 

    $sql = "INSERT INTO table (paragraph) VALUES (?)"; 
    $stmt=$db->prepare($sql); 

    if($stmt){ 

     $stmt->bind_param('s',$paragraph); 

     foreach ($_POST['paragraph'] as $paragraph){ 
      $stmt->execute(); 
     } 
     $stmt->close(); 
    } 
    exit(header("location: form.php")); 
} 
+0

これに戻って、これはSQLステートメントの '?'の意味ですか?それはプレースホルダですか? – rpivovar

+1

はい - 変数は(mysqliで) 'bind_param'を使っているプレースホルダやPDOで' bindParam'を使っているプレースホルダに束縛されています。これは値の解釈がdb自身によって行われることを意味します。プリペアドステートメントのもう一つの大きなメリットは、たとえばループに値を挿入するときです。ステートメントはループの外側で一度準備され、バインディングはループの外側で実行されますが、ループ内で変数に新しい値を割り当ててから – RamRaider

+0

を実行します。ありがとうございます。 – rpivovar

1

あなたはこのラインでSQLステートメントに$paragarphの値を割り当てる:

$sql = "INSERT INTO table (paragraph) VALUES ('$paragraph')"; 

をここで値が空である、それはあなたのデータベース内に空である理由です。 SQLインジェクションにルックスの

+1

'$ _POST'ではなく' $ _POST ['paragraph'] 'をループする –

+0

mysqli_real_escape_stringを先に使ってみると、私が提供していなかったエラーが出ていた2つの変数。私はさらにこれを見なければならないでしょう。それはSQLインジェクションを防ぐでしょうか? – rpivovar

+1

@coffeebot:いいえmysqli_real_escape_stringはSQLインジェクションに対して保存されていません – Jens

関連する問題