You need to do three things:
1) Generate the placeholders.
Knowing how many groupings of values will be inserted, generate sql with placeholders. It will generate something like:
INSERT INTO test(name, email) VALUES (:nome0, :email0),(:nome1, :Email1),(:Nome2, :Email2)
2) Make Binds with array values.
3) Run the query outside of foreach after you have done all Binds
In the end, it executes only one query with all the Insert.
<?php
/* Connect to a MySQL database using driver invocation */
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'root';
$password = '';
try
{
$conecta = new PDO($dsn, $user, $password);
} catch(PDOException $e)
{
echo 'Connection failed: ' . $e->getMessage();
}
//imaginando que se tenha uma matriz de nomes e e-mails, como é um csv
$csv_array = array(
array(
'nome' =>'Teste 1',
'email' =>'[email protected]'
),
array(
'nome' =>'Teste 2',
'email' =>'[email protected]'
),
array(
'nome' =>'Teste 3',
'email' =>'[email protected]'
)
);
// gerando os placeholders e inserindo no seu sql
$qtd = count($csv_array);
$sql= 'INSERT INTO teste(nome, email) VALUES ';
$sql_fragment = '(:nome, :email),';
for($i=0; $i<$qtd; $i++)
{
$sql_to_add = str_replace(
array(':nome',':email'),
array(":nome$i",":email$i"),
$sql_fragment
);
$sql.=$sql_to_add;
}
$sql = rtrim( $sql, ",");
//echo $sql;
//INSERT INTO teste(nome, email) VALUES (:nome0, :email0),(:nome1, :email1),(:nome2, :email2)
// fazendo os binds dos placeholders com os valores do array
try{
$query= $conecta->prepare($sql);
$i=0;
foreach ($csv_array as $linha)
{
$query->bindValue(":nome$i", $linha['nome'],PDO::PARAM_STR);
$query->bindValue(":email$i",$linha['email'],PDO::PARAM_STR);
$i++;
}
$query->execute();
}
catch(Exception $e)
{
echo $e->getMessage();
}
Since it is PDO, it is an alternative that may be valid in some contexts. If you are going to use native Binds, as mysqli does, in many situations it is more elegant and efficient to have several "execute", which transmit only the values, and in native types, greatly speeding up the process.
– Bacco