24 votos

Detener inserción de datos en una base de datos dos veces

Soy bastante nuevo en PHP, me preguntaba ¿qué métodos/prevenciones otros programadores utilizan dejar datos que entró dos veces en una base de datos MySQL cuando un usuario actualiza en la misma página como una forma? Obviouly que pasa y necesito una buena manera de detener esto.

Gracias, Ben

39voto

Ilya Birman Puntos 2996

Yo llamo a esto la regla de oro de la programación web:

Nunca responder con un cuerpo para una POSTERIOR solicitud. Siempre hacen el trabajo, y luego responder con una Ubicación: cabecera para redirigir a la página actualizada de forma que el navegador solicita con GET.

De esta manera, refrescante no va a hacer ningún daño.

También, con respecto a un debate aquí en los comentarios. Para proteger de la doble contabilización de, digamos, accidental hacer doble clic en el botón de Enviar, almacenar un md5() del formulario en un archivo de texto, y comparar la nueva forma del md5 para el almacenado. Si son iguales, usted va a tener un doble post.

7voto

chaos Puntos 69029

La forma de proceso, y luego redirigir a la página de resultados. Volver a cargar entonces solamente vuelve a aparecer la página de resultados.

5voto

James Socol Puntos 1394

Ilya la respuesta es correcta, yo sólo quería añadir un poco más de lo que podría caber en un comentario:

Si el reenvío es peligroso es ir y presentar de nuevo, volver a cargar la página de resultados [si no has tomado Ilya del consejo], etc.) Yo uso un "nonce" para asegurarse de que el formulario sólo puede ir a través de una vez.

En el formulario de la página:

<?php
@session_start(); // make sure there is a session

// store some random string/number
$_SESSION['nonce'] = $nonce = md5('salt'.microtime());
?>
// ... snip ...
<form ... >
<input type="hidden" name="nonce" value="<?php echo $nonce; ?>" />
</form>

En el procesamiento de la página:

<?php
if (!empty($_POST)) {
@session_start();

// check the nonce
if ($_SESSION['nonce'] != $_POST['nonce']) {
    // some error condition
} else {
    // clear the session nonce
    $_SESSION['nonce'] = null;
}

// continue processing

Después de que el formulario ha sido presentado una vez, no puede presentarse de nuevo, a menos que el usuario intencionalmente la llena por segunda vez.

4voto

jeroen Puntos 47068

Indicar lo obvio (no he visto lo aquí pero...): nunca uso llegan a publicar datos, utilice siempre el POST, así el usuario por lo menos obtiene una advertencia si él o ella intenta /re-post la página (al menos en Firefox, pero supongo en otros navegadores también).

Por cierto, si no puede tener los mismos datos dos veces, debe considerar también una solución de MySQL con una clave única (puede ser una combinación de campos) y:

    INSERT INTO ... ON DUPLICATE KEY UPDATE ...

2voto

Lazarus Puntos 17526

Yo estaría de acuerdo con Ilya allí y agrega que se debe utilizar algún cliente javascript para deshabilitar el botón "enviar" una vez que se ha hecho clic o presente un cuadro de diálogo modal (css puede ayudarle aquí) para evitar que varios clics en el botón de enviar.

Por último, si usted no desea que los datos en su base de datos dos veces, a continuación, compruebe también la base de datos para los datos antes de intentar insertar. Si usted permite que los registros duplicados, pero no quiero repetición rápida, inserciones de una sola fuente, a continuación, que haría uso de una marca de fecha/hora y los campos de la dirección IP para permitir la base del tiempo 'lockout' en mi presentación de código, es decir, si la IP es la misma y el último tiempo de envío fue hace menos de 5 minutos, a continuación, no insertar el nuevo registro.

Esperamos que te da algunas ideas.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X