php - tiempo - insertar datos en tablas relacionadas mysql java
Detener la inserciĆ³n de datos en una base de datos dos veces (16)
¡Puedes usar un token para evitar que la página se procese de nuevo! Tal procedimiento se utiliza en muchos marcos web!
El patrón que debes usar es el "Patrón del token del sincronizador". Si tiene una aplicación orientada al servicio, puede guardar su estado en la Base de datos.
Los datos se pueden enviar a través de JavaScript o por un campo de formulario oculto.
¡También deberías echar un vistazo a las bibliotecas con ayuda inmediata para cosas como esta! ¡Grails es tal!
Consulte: http://www.grails.org/1.1-Beta3+Release+Notes ...
<g:form useToken="true">
...
withForm {
// good request
}.invalidToken {
// bad request
}
..
Soy bastante nuevo en PHP, me preguntaba qué métodos / prevenciones utilizan otros programadores para evitar que los datos se ingresen dos veces en una base de datos MySQL cuando un usuario actualiza en la misma página como formulario. Obviamente sucede y necesito una buena manera de detener esto.
Gracias ben
Además de las buenas sugerencias ya mencionadas acerca de alejar al usuario de la página de publicación, por lo que el botón de actualización y retroceso son inofensivos, otra capa para mejorar su almacenamiento de datos es usar los UUID como claves en su tabla y dejar que sus aplicaciones los generen.
Estos también se conocen como GUID en el mundo de Microsoft y en PHP puede generar uno a través de uniqid () en PHP. Este es un valor hexadecimal de 32 caracteres que debe almacenar en un formato de columna hexadecimal / binario, pero si la tabla no va a ser muy utilizada, entonces CHAR (32) funcionará.
Genere este ID cuando muestre su formulario como una entrada oculta, y asegúrese de marcar la columna de la base de datos como la clave principal. Ahora, si el usuario logra regresar a una página de publicación, INSERT fallará porque no puede tener claves duplicadas.
Una ventaja adicional a esto es que si genera el UUID en el código, luego, después de realizar una inserción, nunca necesitará utilizar consultas inútiles para recuperar la clave que se generó porque ya lo sabrá. Este es un buen beneficio cuando necesita INSERTAR elementos secundarios en otras tablas.
La buena programación se basa en la superposición de su trabajo, no en confiar en una cosa para trabajar. A pesar de lo común que es que los programadores confíen en los ID incrementales, son una de las formas más perezosas de construir una tabla.
Agregue un campo oculto con una cadena aleatoria (producida por md5(uniqid())
por ejemplo), md5(uniqid())
un campo en la base de datos para esa cadena y hágalo ÚNICO.
Bueno, en primer lugar, para minimizar, debe hacerlo de modo que tengan que hacer una publicación de formulario para insertar los datos. De esa manera, al menos obtendrán ese pequeño diálogo de confirmación preguntando si realmente quieren volver a enviarlo.
Para ser más complicado que eso, puede poner una clave de uso oculta en cada formulario, y una vez que se haya enviado el formulario con esa clave, se mostrará un error cuando intenten enviar un formulario con la misma clave. Para crear esta clave, es probable que desee utilizar algo como un GUID.
Debe pasar una variable uniqid a su html dentro del método showAddProductForm () y el mismo uniqid en su ejemplo de $ _SESSION:
public function showAddProductForm()
{
$uniId = uniqid();
$_SESSION[''token''][$uniId] = ''1'';
$fields[''token''] = ''token[''.$uniId.'']'';
$this->fileName = ''product.add.form.php'';
$this->template($fields);
die();
}
Luego, debe colocar una entrada oculta en el código HTML dentro de su formulario con el valor del uniqid que se ha pasado al HTML desde el método showAddProductForm.
<input type="hidden" name="<?=$list[''token'']?>" value="1">
Inmediatamente después del evento de envío, lo analizará al comienzo del método addProduct (). Si el token existe en la $ _SESSION y tiene un valor igual dentro de esa matriz, entonces este es el nuevo requisito. Redirigirlo a la página adecuada, desarmar el token y continuar insertando. De lo contrario, es desde la página de recarga o desde una solicitud repetitiva, redirigirlo a la página addProdeuct
public function addProducts($fields)
{
$token_list = array_keys($fields[''token'']);
$token = $token_list[''0''];
if (isset($_SESSION[''token''][$token]) and $_SESSION[''token''][$token] == ''1'') {
unset($_SESSION[''token''][$token]);
} else {
$this->addAnnounceForm($fields, '''');
}
}
Tal vez te preguntes por qué una matriz de fichas por qué no una sola variable. Debido a que en el Panel de administración, los usuarios abren varias pestañas y las insertan en varias pestañas, por lo que este algoritmo fallará si usan varias pestañas.
Un agradecimiento especial a quienes descifran este método malekloo
Es posible que desee revisar el patrón POST / Redirect / GET que implementan la mayoría de las aplicaciones web modernas, consulte http://en.wikipedia.org/wiki/Post/Redirect/Get
Estaría de acuerdo con Ilya allí y agregaría que debería usar algún javascript del cliente para deshabilitar el botón "enviar" una vez que se haya hecho clic o presentar un diálogo modal (css puede ayudarlo aquí) para evitar múltiples clics en el botón enviar.
Por último, si no desea que los datos estén dos veces en su base de datos, también revise los datos en su base de datos antes de intentar insertarlos. Si permite registros duplicados pero no desea inserciones de repetición rápidas de una sola fuente, usaría un sello de fecha / hora y campos de dirección IP para permitir un "bloqueo" basado en tiempo en mi código de envío, es decir, si el La IP es la misma y la última vez que se envió fue hace menos de 5 minutos, entonces no inserte el nuevo registro.
Espero que te dé algunas ideas.
Intente incluir algo en sus formularios para evitar la presentación doble, preferiblemente al mismo tiempo que protege contra la falsificación de solicitudes entre sitios. Recomiendo usar lo que yo llamo una formkey , que es un campo de un solo uso que identifica de manera única el envío de un formulario, vinculándolo a un usuario individual en una dirección individual. El concepto también tiene otros nombres, pero la breve nota que he enlazado lo explica bastante bien.
La mejor manera de evitar la inserción de registros duplicados en la actualización de la página es, luego de insertar los registros en la base de datos al hacer clic en el botón, simplemente agregue esta línea:
Response.Write("<script>location.href=''yourpage.aspx''</script>");
La respuesta de Ilya es correcta, solo quería agregar un poco más de lo que cabría en un comentario:
Si la reenvío es peligrosa (volver atrás y volver a enviar, volver a cargar la página de resultados [si no ha seguido los consejos de Ilya], etc.) uso un "nonce" para asegurarme de que el formulario solo se pueda enviar una vez.
En la página del formulario:
<?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 la página de procesamiento:
<?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
Una vez que el formulario se ha enviado una vez, no se puede volver a enviar, a menos que el usuario lo llene intencionalmente por segunda vez.
Mis dos centavos:
- Redirigir al usuario a la misma página después de enviar los datos y verificar
if(isset($_POST[''submit''])
Otra información útil para casos similares:
Dale un vistazo a LOCK TABLES en MySQL
Desactivar botones a través de JavaScript después del primer clic
Para indicar lo obvio (aún no lo he visto aquí ...): nunca use GET para publicar datos, siempre use POST, de esa manera el usuario al menos recibe una advertencia si intenta actualizar / volver a publicar la página (Al menos en Firefox, pero supongo que también en otros navegadores).
Por cierto, si no puede permitirse tener los mismos datos dos veces, también debe considerar una solución MySQL con una clave única (puede ser una combinación de campos) y:
INSERT INTO ... ON DUPLICATE KEY UPDATE ...
Por lo general confío en la restricción del índice ÚNICO de sql. http://dev.mysql.com/doc/refman/5.0/en/constraint-primary-key.html
Procese el formulario, luego redirija a la página de resultados. Recargar solo vuelve a mostrar la página de resultados.
Yo llamo a esto una regla de oro de la programación web:
Nunca responda con un cuerpo a una solicitud POST. Siempre haga el trabajo y luego responda con un encabezado de Ubicación: para redirigir a la página actualizada de modo que el navegador lo solicite con GET.
De esta manera, refrescarte no te hará ningún daño.
También, con respecto a una discusión aquí en comentarios. Para evitar la doble publicación, por ejemplo, haga doble clic en el botón Enviar, almacene un md5 () de su formulario en un archivo de texto y compare el md5 del nuevo formulario con el almacenado. Si son iguales, tienes una doble entrada.
POE (Post Once Exactly) es un patrón HTTP destinado a advertir al cliente que bloquee envíos dobles utilizando un encabezado propietario ...
GET /posts/new HTTP/1.1
POE: 1
...
... pero todavía está en la especificación.
http://www.mnot.net/drafts/draft-nottingham-http-poe-00.txt
Creo que lo anterior es una buena solución. Aunque el almacenamiento del nonce como una variable de sesión discreta introducirá algunos errores si el cliente está intentando realizar publicaciones simultáneas desde varias pestañas. Quizás mejor que ...
$_SESSION[''nonces''][] = $nonce;
... y ...
if (in_array($_POST[''nonce''], $_SESSION[''nonces''])) {
... para permitir múltiples nonces (nonci? noncei?).