1

I have a form that has a checkbox list generated dynamically: name="cursoID[]" Each value correspond to cursoID ($curso['cursoID']), which is a value taken from a mySQL SELECT query that shows me a list of items IDs.

The user may select N number of items, and I need to take each one of those (ie. $cursoID = $_POST['cursoID'];) in order to save them into an INSERT query.

In the form, I generate each item with a while loop:

<?php 
$conectar = mysqli_connect(HOST, USER, PASS, DATABASE);
$query = "  SELECT cursoID, nombreCurso, cursoFechaInicio, modalidadCurso, estadoCurso
FROM cursos 
WHERE estadoCurso='abierto'";

$buscarCurso = mysqli_query($conectar,$query);

echo '<div class="checkbox">';
while ($curso=mysqli_fetch_assoc($buscarCurso)) {
echo '<input type="checkbox" name="cursoID[]" value="'.$curso['cursoID'].'">'.$curso['nombreCurso'];
}
echo '</div>'; 

?>

My database consultation in order to insert that field is a simple select:

INSERT INTO cursosUsuarios 
                (userID, cursoID) 
              VALUES 
                ('$userID', '$cursoID')

I have no issues with $userID, as is a single value.

How may I use $cursoID = $_POST['cursoID'] to add it to the database? I've been reading some other questions (like this one, or this other one), but couldn't manage to apply it to my case, as I don't know how would I insert it into the database.

Community
  • 1
  • 1
Rosamunda
  • 14,620
  • 10
  • 40
  • 70

2 Answers2

2

I dk how to use mysqli_* so i'll write in PDO. If i could understand correctly this's what u need.

ps: Security ignored.

$cursors = $_POST['cursorID'];
$user = $_POST['user'];

foreach ($cursors as $cursor) {

        $query = $DB->prepare('INSERT INTO table (user, cursor) VALUES (:user, :cursor)');

        $query->bindValue(':user', $user, PDO::PARAM_INT);
        $query->bindValue(':cursor', $cursor, PDO::PARAM_INT);

        $query->execute();
}
  • `mysqli` is very similar, so it's worth adapting this. The `bind_params` call is different. – tadman Jul 25 '16 at 20:19
1

There's two main ways you can insert a variable amount of data into your database:

  • Build your query dynamically (if you have many columns, and you don't know how many you'll update)

Like so:

$fields = array();
$values = array();

$fields[] = 'field1';
$fields[] = 'field2';
...

$values[] = 1;
$values[] = 2;
...

$query = 'INSERT INTO table (' . implode(', ', $fields) . ') VALUES (' . implode(',', $values) . ')';

// Execute $query

or:

  • Add the individual items in separate queries, that you repeat over and over (if you need to fill a variable amount of rows).

Like so (if your checkboxes are named "cursoID[]", the corresponding POST variable will be an array, and you can use anything that'll work with arrays):

$userID_int = (int)$userID;
foreach ($_POST['cursoID'] as $singleID) {
    $singleID_int = (int)$singleID;
    // Execute: INSERT INTO cursosUsuarios (userID, cursoID) VALUES ('$userID_int', '$singleID_int')
}

However, be very careful - at the moment, your code is vulnerable to SQL injections (for example, if $_POST['cursoID'] is set to something like

'; DROP DATABASE X

you might - depending on your configuration - allow someone to do a lot of nasty stuff, ranging from bypassing your logins to removing your database. As such, I would recommend taking a step back and looking into how you can parameterize your queries, so you don't have to worry about a hostile visitor injecting data in your SQL query. See, for example, this answer.

Community
  • 1
  • 1
Aaa
  • 614
  • 5
  • 14
  • Your code is vulnerable too, you went and made another SQL injection bug. Why? You know casting as `int` is ridiculous. You can do better than this. – tadman Jul 25 '16 at 20:20
  • By casting to int the code is no longer susceptible to SQL injection. Prove me wrong: none of my code that accepts user input is vulnerable. My answer links to the proper way of doing it, namely prepared statements. That's what I use, however I'm not reinventing the wheel: I told them their code is vulnerable, answered their question with code that is not vulnerable, and linked them to a fleshed out answer about how to actually secure their code. When it comes to your comment, however, I'm casting pearls before swine I guess, because despite all this you get mad enough to downvote. Good job. – Aaa Jul 26 '16 at 21:16
  • Casting to int is a highly special case "fix" for a serious problem. Can you cast to string or date for other situations? No. I know you link to the solution, but if you can't be bothered to include it in your answer how can you expect the person asking the question to bother trying? It's literally two lines of code that you should be able to do in your sleep if you use `mysqli` on a regular basis. Parameterizing queries takes less than a minute, if that. It should be second nature. I'm sorry I down-voted your half-baked `(int)` solution, but that gives people a dangerous false confidence. – tadman Jul 27 '16 at 03:58
  • I'm sorry to be so critical here but it's very important that people are shown the correct way of doing things, the cost of a simple, innocent mistake can be catastrophic to both your career and your company. `mysqli` has native support for placeholder values and using them is imperative, not optional. – tadman Jul 27 '16 at 04:10
  • Yes, it's true that I cannot be bothered to repeat a perfectly fleshed out answer in my post, and just link to it on StackOverflow. You're trying to force your opinion on how I should be doing things on me. I post "I'm showing you how you do it in your code, so you understand it, but your code has issues, here's a link on SO how you should be doing it." You try to force me "You are gonna copy the answer from that link into your answer, right now, or else I downvote". A tug-of-war, to see if you have that power over me. It doesn't work. All you accomplish is scaring people away from SO. :) – Aaa Jun 24 '17 at 19:40
  • This isn't against you personally. This is to address a general pattern where people slap together a quick and dirty answer which someone else, not knowing better, uses in their application. Then later on [bad things happen](http://codecurmudgeon.com/wp/sql-injection-hall-of-shame/). I'm sorry you're upset, but code like this destroys careers when it gets exploited. There's a certain responsibility for programmers, like doctors, electricians, engineers and pilots have, to adhere to certain *minimum* safety standards. Fixing this code isn't hard. – tadman Jun 24 '17 at 19:46