Este mini tutorial puede ser usado como referencia para  cualquier lenguaje de programación,  tratare de explicar el código para que pueda ser pasado a otros lenguajes como ASP o JSP.

Muchas veces se nos presenta  este caso, tenemos un formulario cuyas variables son enviadas al servidor por POST, luego se ejecuta alguna función para su proceso ya sea  enviar un email, escribir en un archivo o modificar  las tablas de una base de datos, aquí se presenta un problema,  el usuario puede  recargar la pagina ya sea con F5 o con la opción recargar enviando erróneamente el formulario por segunda vez, para evitar esto la respuesta al submit  puede ser puesta en una nueva pagina, pero en mi caso necesitaba trabajar sobre el mismo php.

Encontre una clase que soluciona este problema la cual verifica si un formulario es enviado mas de una vez.

Creamos una clase postClass.php

  1. <?php
  2. class Post_Block {
  3. function startPost() {
  4. echo “<input type=’hidden’ name=’postID’ “;
  5. echo “value=’”.md5(uniqid(rand(), true)).“‘>”;
  6. }
  7. function postBlock($postID) {
  8. if(isset($_SESSION['postID'])) {
  9. if ($postID == $_SESSION['postID']) {
  10. return false;
  11. } else {
  12. $_SESSION['postID'] = $postID;
  13. return true;
  14. }
  15. } else {
  16. $_SESSION['postID'] = $postID;
  17. return true;
  18. }
  19. }
  20. ;}
  21. ?>
La primera función startPost() escribe en nuestro formulario un campo oculto con un valor aleatorio.
La segunda función postBlock() verifica la existencia de ese valor, ya por ahi pueden  imaginar como es el proceso.
Como usar la clase?
En el php donde tienen el formulario así tiene que estar el codigo.
  1. <?php
  2. require(“postClass.php”);
  3. $thisPost = new Post_Block;
  4. ?>
  5. <form name=“foo” action=“action.php” method=“post”>
  6. <input type=“text” name=“generica” size=“25″>
  7. <?php $thisPost->startPost(); ?>
  8. </form>
Y  en la pagina de respuesta
  1. <?php
  2. require(“postClass.php”);
  3. $thisPost = new Post_Block;
  4. if ($thisPost->postBlock($_POST['postID'])) {
  5. // No existe doble post
  6. // Procesamos la información
  7. } else {
  8. // Doble post, no procesamos el form.
  9. echo “Oops!! Doble Post!”;
  10. }
  11. ?>
OTRA FORMA DE USO
En mi caso no la pagina de respuesta es la misma del formulario, asi que utilice de otra manera la clase, es mas, no creo la clase simplemente evito usar la primera función y en mi formulario escribo:
  1. <?php
  2. ?>
  3. <form name=“foo” method=“post”>
  4. <input type=“text” name=“generica” size=“25″>
  5. <input type=’hidden’ name=’postID’ value=<?php echo “‘”.md5(uniqid(rand(), true)).”‘” ?> >
  6. </form>
y en el codigo que procesa los datos dentro del php agrego
  1. if (postBlock($_POST['postID'])) {
  2. // No existe doble post
  3. // Procesamos la información
  4. } else {
  5. // Doble post, no procesamos el form.
  6. echo “Oops!! Doble Post!”;
  7. }
  1. function postBlock($postID) {
  2. if(isset($_SESSION['postID'])) {
  3. if ($postID == $_SESSION['postID']) {
  4. return false;
  5. } else {
  6. $_SESSION['postID'] = $postID;
  7. return true;
  8. }
  9. } else {
  10. $_SESSION['postID'] = $postID;
  11. return true;
  12. }
  13. }
como puede ver elimino  this->  porque ya no uso la clase.
Pero qu’e  hace la función postBlock??
Primero pregunta por una variable sesión postID, si no existe  toma la variable oculta del formulario y la guarda en la sesión con ese nombre, retorna true, quiere decir que es la primera vez que se envía el formulario.
Si ya existe esa variable en la session,  pregunta si es igual a la que se esta reenviando del formulario, si es asi retorna falso que equivale a un reenvio.