Desde el punto de vista de BBDD, la tabla la tienes mal definida, porque si es una tabla que relaciona Usuarios con Tarjeta, la PK debería ser (usuario_id, tarjeta_id), es decir, la PK de cada una de las dos tablas es en la tabla relacional la PK de la tabla (PK compuesta).
Sólo con eso la información
jamás se duplicaría.
Yo asumo que en lugar de hacer la pK que corresponde le has puesto un ID propio, y no has declarado al menos como UNIQUE un índice sobre los otros dos campos, cosa de proteger la consistencia de datos.
A nivel PHP, me gustaría confirmar si lo que supones que contienen las variables es lo que realmente tienen. En especial porque las estás tratando como cadenas de texto (las pones entre apóstrofos), y por ende si estuviesen vacías, jamás sería detectado un error.
Algo como:
Código PHP:
//Si viene del paso 3 a seleccionar otras tarjetas ejecuta esto
if (isset($_POST['tarjetas'])){
//trae los chekbox y escribe en la tabla.
$tarjetasSeleccionadas=$_POST['tarjetas'];
if (count($tarjetasSeleccionadas) > 0)
{
$i=0;
while($i < count($tarjetasSeleccionadas))
{
$userid = $_SESSION["usuario_id"];
$tarjeta = $tarjetasSeleccionadas[$i];
echo $userid;
echo $tarjeta;
// Verificar si la combinación ya existe.
$validar = 'SELECT COUNT(*) total FROM tarjetas_usuarios WHERE usuario_id = "'.$userid.'" AND tarjetas_usuario_id = "'.$tarjeta.'"';
$resultvalidar = mysql_query($validar) or die(mysql_error());
// Si devuelve
$row = mysql_fetch_array($resultvalidar);
if($row['total'] == 0)
{
$qryinsert = "INSERT INTO tarjetas_usuarios (usuario_id, tarjetas_usuario_id) values ('".$userid."', ".$tarjeta.")";
$result = mysql_query($qryinsert) or die (mysql_error());
if($result) $i++;
}
}
}
}