:::: MENU ::::

Evitar doble POST en PHP

En la mayor parte de desarrollos de aplicaciones hechas en web, nos encontramos con el problema de que el usuarios puede enviar dos veces la información, estos por ejemplo hay un formulario de registro el usuario ingresa sus datos y completa el registro, pero si el usuarios actualiza la página el browser preguntará si desea enviar la información nuevamente con lo cual nos arriesgamos a que el usuario se registre dos veces.

post.gif

Entre las muchas lecturas que tengo me encontré con una solución en Big Trapezze la cual comparto con ustedes. Se trata de una clase que verificará que no se envíen dos veces los datos del formulario. Para ello debes crear un archivo llamado postClass.php.

<?php
class Post_Block {
    function startPost() {
        echo "<input type='hidden' name='postID' ";
        echo "value='".md5(uniqid(rand(), true))."'>";
    }

    function postBlock($postID) {
        session_start();
        if(isset($_SESSION['postID'])) {
            if ($postID == $_SESSION['postID']) {
                return false;
            } else {
                $_SESSION['postID'] = $postID;
                return true;
            }
        } else {
            $_SESSION['postID'] = $postID;
            return true;
        }
    }
;}
?>

Esta clase tiene dos funciones la primera startPost creara un campo oculto en el formulario con un número identificador único que servirá para verificar si se envió el formulario. La segunda función llamada postBlock verifica que el identificador no exista y si no detiene la ejecución del script.

Uso de la Clase

Primero debemos insertar el código de verificación en nuestro formulario y esto lo hacemos con la función startPost.

<?php
require("postClass.php");
$thisPost = new Post_Block;
?>
<form name="foo" action="action.php" method="post">
    <input type="text" name="generica" size="25">
    <?php $thisPost->startPost(); ?>
</form>

El siguiente paso es verificar el número identificador en nuestra pagina que procesa el formulario, en nuestro ejemplo action.php.

<?php
require("postClass.php");
$thisPost = new Post_Block; 
if ($thisPost->postBlock($_POST['postID'])) {
    // No existe doble post
    // Procesamos la información
} else {
    // Doble post, no procesamos el form.
    echo "Oops!! Doble Post!";
}
?>

Como verá con una sentencia if podemos verificar que no se esten enviando dos veces el formulario. Como comentario adicional debo decirles que hay otra forma de evitar este problema y es que luego de procesar los datos redireccionemos a otra página de confirmación de procesamiento de datos, con esto se evita que se envíen los datos, el único problema es que tenemos que crear un tercera página solo para confirmación de resultados.


17 Comentarios

  • HERNAN CONTRERAS |

    Excelente aporte, a mí me pasaba que un formulario se estaba enviando dos veces, pero era por un error de hacer submit en el javascript. Pero gracias a esta clase encontré que el formulario se enviaba dos veces. Saludos.

  • Leonardo |

    SOS UN MAESTRO!!!

    Muchisimas gracias!! Me solucionaste un problema muy grande.

    Ahora tengo que hacerlo en todos los forms. ¿Alguna ayudita para buscarlos? jeje

    Saludos

  • Juanma |

    Buenísimo, muchas gracias, realmente el único método que me solucionó el problema del doble post.

    Gracias!

  • Carlos |

    Gracias! Funciona perfectamente y es muy útil. No solo evita el doble post, sino el triple-post, cuadruple-post… y aquellos emails repetidos enviados tantas veces como veces clicado el F5!!

  • Pedro Urday |

    Esa manera esta muy bien. Tambien se puede evitar que aparesca ese cartel. Se trata simplemente de usar redireccion absoluta con php. Tu codigo se puede convinar de alguna manera con este:

    //archivo 'formulario.php'
    '', 'campo2' => '', 'campo3' => '');
    }
    ?>

    Campo 1:
    <input type="text" name="campo1" value="">

    Campo 2:
    <input type="text" name="campo2" value="">

    Campo 3:
    <input type="text" name="campo3" value="">

    Con esto el browser no volvera a preguntar si desea enviar la información nuevamente. Que les parece? A mi me funciona. Diganme si les funciona.

  • Pedro Urday |

    Perdon. El codigo se me chispoteo. Es este:


    //archivo 'formulario.php'
    <?php
    if (isset($_POST)){
    //recibo los campos del formulario
    $msg_error = ''; //mensaje de validacion erronea
    //valido los campos del formulario
    $id; //id del resultado del post
    if ($msg_error == '') {
    require_once 'include/conectar.php'; //archivo de coneccion
    $sql = "INSERT INTO blablabla"//el 'blablabla' no va, lo remplazan
    if (mysql_query($sql)){
    header("HTTP/1.1 301 Moved Permanently");
    header("Location: resultados.php?id=$id");
    exit();
    }else
    $msg_error .= 'Error en el servidor: no se pudo enviar.';
    }
    $campo = $_POST;
    }else{
    //Les seteo algunos valores por defecto a los campos del formulario
    $campo = array('campo1' => '', 'campo2' => '', 'campo3' => '');
    }
    ?>

    <!-- Envio las variables al mismo formulario por el metodo post-->
    <form class="mi-formulario" action="formulario.php" method="post">

    <label>Campo 1:<br>
    <input type="text" name="campo1" value="<?=$campo['campo1']?>"><br></label>

    <label>Campo 2:<br>
    <input type="text" name="campo2" value="<?=$campo['campo2']?>"><br></label>

    <label>Campo 3:<br>
    <input type="text" name="campo3" value="<?=$campo['campo3']?>"><br></label>

    </form>

    Con esto el browser no volvera a preguntar si desea enviar la información nuevamente. Que les parece? A mi me funciona. Diganme si les funciona.

  • chuchhin |

    Muy buenas entradas, me han ayudado mucho con mi trabajo de tesis.
    Ojalá sigas escribiendo información que nos ayuda a todos.
    Un sauldo y gracias.

  • Fernando |

    Me fue de utilidad.Muy claro y bien explicado.Pude arreglar el tema que los reenvios que durante mucho tiempo lo venia portergando.Gracias

  • Francisco |

    Funciona bien con el retroceder del navegador, no puede enviar dos veces el formulario. Pero no funciona con que el idiota de mi cliente presione dos veces el boton submit, lo bloqueare con javascript a ver si no me sigue jodiendo

  • Marlon Guadalupe |

    Esta clase tiene un error grabe.
    Al presionar F5 todo conforme evita el doble post,
    pero si en lugar de refrescar la pagina lo que se hace es ingresar directamente a la pagona que procesa el formulario este sera enviado y lo peor si se hace f5 ahi no bloquea el doble envio.

    Tratare de revisar la clase y publicar la correcion

Publica tu comentario

En este blog los comentarios están moderados, serán mostrados cuando el administrador los apruebe. Por favor, evita comentarios ofensivos u obscenos por que no serán aprobados.
Si deseas publicar código fuente debes hacerlo entre las etiquedas <code> y </code>, además debes reemplazar los carácteres < por &lt; y > por &gt;.