1

Here is my code:

$post_id = 10;
$tags_id = [23, 55, 155, 15];

$stmt = $dbh_conn->prepare("INSERT INTO post_tags  (post_id, tag_id) VALUES (?, ?)");
$stmt->execute([$post_id, $tags_id[0]]);
if ( !$stmt->rowCount() ){
    throwErrorMessage("Something went wrong while inserting tags");
}

As you can see, my code only inserts one row. I can count the number of count($tags_id) and copy-paste the whole code according to that number. But that approach doesn't seem good to me. Any idea what's the best approach to use an loop on that?

3 Answers 3

4

Prepare once and insert in a loop:

$stmt = $dbh_conn->prepare("INSERT INTO post_tags  (post_id, tag_id) VALUES (?, ?)");
foreach ($tags_id as $tag) {
    $stmt->execute([$post_id, $tag]);
    if ( !$stmt->rowCount() ){
        throwErrorMessage("Something went wrong while inserting tag " . $tag);
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

And they are wrong. Prepared statements can be prepared once and used many times, that is the profit.
@MartinAJ yes, that should be the way to go
2

You can either…

A) use a single statement and produce the VALUES (…) part in side a loop.

$values = [];
foreach ($tags_id as $tag) {
    $values[] = sprintf( '(%d, %s)', (int)$post_id, $dbh_conn->quote($tag) );
}

$stmt = $dbh_conn->prepare(
    sprintf(
        'INSERT INTO post_tags  (post_id, tag_id) VALUES %s;',
        implode(',', $values)
    ));

if(!$stmt->execute()) {
    // something went wrong
}

or

B) re-use the statement for one row per INSERT and call the execute inside a loop. (as suggested in the other answers)

2 Comments

Thank you, how can I generate values() part dynamically?
@MartinAJ added quick example
0

Prepare the insert query and execute once. Try below code, it might be help

$post_id = 10;
$tags_id = [23, 55, 155, 15];
$lastElement = end($tags_id);
$insert = "INSERT INTO post_tags  (post_id, tag_id) VALUES";
foreach ($tags_id as $key => $value) 
{
    if ($value == $lastElement) {
        $insert .= "(".$post_id.", ".$value.")";
    } else {
        $insert .= "(".$post_id.", ".$value."),";
    }        
}
$stmt = $dbh_conn->prepare($insert);
$stmt->execute();
if ( !$stmt->rowCount() ){
    throwErrorMessage("Something went wrong while inserting tags");
}

2 Comments

Such a mess of prepared statements and direct concatenation, please don't do that.
Seems complex, but the logic is fine, thank you, upvote

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.