Site icon RibosoMatic

Envio de formulario PHP vs PHP + JavaScript (fetch async/await)

Detallaremos el proceso de envió de datos y datos incluyendo un archivo de un formulario HTML de distintas formas: usando solo PHP, usando PHP y JavaScript (con jQuery), y finalmente PHP y Vanilla JavaScript + Async/Await, sin ninguna librería.

Dirigido a quienes tienes conocimiento HTML, PHP y JavaScript, bajo-medio.

Indice:

Dejo link en mi repositorio: https://github.com/RibosoMaticCode/submitformphp

La estructura de nuestro directorio es la siguiente para darnos una idea:

Enviar datos de formulario con PHP

Lo primero que hay que hacer en el lado del front-end es implementar un formulario básico, para efectos prácticos con las siguientes características:

<form action="procesar_datos.php" method="POST">
    <label>Nombres</label>
    <input type="text" name="nombres" class="form-control">
    <label>Mensaje</label>
    <textarea name="mensaje" class="form-control"></textarea>
    <br >
    <button type="submit" class="btn btn-primary">Enviar</button>
</form>

Vamos ahora a nuestro back-end, el archivo procesar_datos.php, y veremos un script simple para mostrar los datos capturados.

Nota: Este archivo usaremos para los distintos tipo de envíos más adelante.

<?php
if( $_POST ){
    foreach ($_POST as $key => $value) {
        echo $key.': <br />'.$value.'<br />';
    }
}

La variable $_POST, es un array que contiene todos los datos del formulario, en este caso tanto nombres como mensaje. Lo primero que hacemos es verificar si esta definido, y luego mediante la instrucción foreach, recorremos los elementos de este array.

Si ejecutamos el formulario, el resultados que obtenemos es el siguiente:

Resultado

Como vemos se ha impreso tanto el nombre del control (entradas de texto) HTML y su valor.

Hasta aquí espero se haya entendido ¿no es complicado verdad? Pero es importante entender esto si queremos ahora algo avanzando como adjuntar un archivo a nuestro formulario y enviarlo. Veamos.

Enviar datos de formulario y archivo con PHP

Muy bien, volvemos al front-end y usando el mismo formulario arriba descrito, vamos hacer algunas modificaciones:

El formulario completo debería quedar así:

<form action="procesar_datos_archivo.php" method="POST" enctype="multipart/form-data">
    <label>Nombres</label>
    <input type="text" name="nombres" class="form-control">
    <label>Mensaje</label>
    <textarea name="mensaje" class="form-control"></textarea>
    <label>Archivo a subir</label>
    <input type="file" name="archivo">
    <br >
    <button type="submit" class="btn btn-primary">Enviar</button>
</form>

En la parte del back-end, en el archivo procesar_datos_archivo.php tendrá el siguiente código:

<?php
// Si esta definido el archivo
if(isset($_FILES['archivo']['name'])){
    if(move_uploaded_file($_FILES['archivo']['tmp_name'], 'upload/'.$_FILES['archivo']['name'] )){
        echo 'Archivo subido <br />';
    }
}

if( $_POST ){
    foreach ($_POST as $key => $value) {
        echo $key.': <br />'.$value.'<br />';
    }
}

Explicando: Para ver el valor del archivo no usamos la variable $_POST, sino $_FILES y lo primero que hacemos es verificar si esta definida, si es así continuamos con la carga del archivo a nuestro servidor usando la función:

move_uploaded_files(archivo_a_subir, ubicacion_destino);

Si devuelve verdadero, ósea que subió correctamente, entonces mostramos el mensaje Archivo subido.

Ahora probemos nuestro código, el resultado es el siguiente:

Resultado

Revisando mi directorio upload donde irán los archivos subido veo lo siguiente:

En ambos casos anteriores luego de pulsar el botón Enviar, nos muestra el resultado en otra pantalla, es decir pasa a otra página. Pero si queremos evitar eso hay que usar Ajax para enviar y recuperar datos sin necesidad de pasar a otra página. Y eso se hace con JavaScript. Primero lo veremos con la librería jQuery y luego sin esta.

Enviar datos de formulario con PHP y JavaScript (jQuery)

Para hacer uso de jQuery tenemos que añadir la referencia a nuestra pagina html. Googlemos para buscarlo y colocamos la url de su cdn antes de la etiqueta </body>. Igual te la dejo aqui:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

Ahora volvamos al formulario inicial y hagamos nuevamente algunas modificaciones:

<form id="form_jquery" action="">
    <label>Nombres</label>
    <input type="text" name="nombres" class="form-control">
    <label>Mensaje</label>
    <textarea name="mensaje" class="form-control"></textarea>
    <br >
    <button type="submit" class="btn btn-primary">Enviar</button>
</form>

Ahora vamos crear un archivo JavaScript: script_jquery.js y también lo referenciamos antes de la etiqueta </body>. El archivo contendrá lo siguiente (allí incluyo la explicación de este archivo):

$(document).ready(function() {

    /* Aqui especificamos el id del formulario
    establecemos el evento submit
    */
    $( "#form_jquery" ).on( "submit", function( event ) {
        event.preventDefault(); // Esto es para prevenir que cargue la pagina siguiente

        /* Hacemos la llamada AJAX
        Espeficamos el archivo que captura los datos enviados
        El metodo a usar es POST
        .serialize() es para capturar todos los valores a enviar
        de este formulario
        en success, definimos una funcion que muestra una alerta con la
        respuesta del servidor
        */
        $.ajax({
            url: "procesar_datos.php",
            type: 'post',
            data: $( this ).serialize(), 
            success: function(response){
                alert( response );
            }
        });
    });
});

Ten en cuenta que el archivo que recibe los valores de este formulario y luego los mostrara, es procesar_datos.php, que explicamos en la parte superior. No haremos ningún cambio a este archivo. Ahora si ejecutamos este formulario veamos el resultado:

Vemos que el formulario no nos lleva a otra pagina y también vemos que la respuesta del servidor es mostrado en una ventana emergente alert, como definimos en nuestro archivo JavaScript.

Ahora siguiendo la misma lógica, pero también enviando un archivo en el formulario.

Enviar datos de formulario y archivo con PHP y JavaScript (jQuery)

Usando el mismo formulario anterior, hagamos las siguientes modificaciones:

<form id="form_archivo_jquery" action="">
    <label>Nombres</label>
    <input type="text" name="nombres" class="form-control">
    <label>Mensaje</label>
    <textarea name="mensaje" class="form-control"></textarea>
    <label>Archivo a subir</label>
    <input type="file" name="archivo">
    <br >
    <button type="submit" class="btn btn-primary">Enviar</button>
</form>

Ahora en nuestro archivo JavaScript script_jquery.js añadimos lo siguiente (alli también explico el funcionamiento de este)

$(document).ready(function() {

    /* Aqui especificamos el id del formulario
    establecemos el evento submit
    */
    $( "#form_archivo_jquery" ).on( "submit", function( event ) {
        event.preventDefault(); // Esto es para prevenir que cargue la pagina siguiente

        /* Hacemos la llamada AJAX
        Espeficamos el archivo que captura los datos enviados, este caso es procesar_datos_archivo.php
        El metodo a usar es POST
        En data usamos FormData para compilar los datos a enviar
        Hay dos claves mas: contentType y proccessData que seteamos a false
        En success, definimos una funcion que muestra una alerta con la
        respuesta del servidor
        */
        $.ajax({
            url:"procesar_datos_archivo.php",
            type: 'post',
            data: new FormData( document.getElementById('form_archivo_jquery') ), 
            contentType: false, // por defecto es application / x-www-form-urlencoded; charset = UTF-8, al poner false desactivamos esto
            processData: false, // por defecto es true, que transforma los datos enviados en una cadena de consulta, al poner false desactivamos esto
            success: function(response){
                alert( response );
            }
        });
    });

});

Muy bien ahora probemos nuestro formulario.

Vemos que el formulario no nos lleva a otra pagina y también vemos que la respuesta del servidor es mostrado en una ventana emergente alert. El archivo en el servidor no ha devuelto además el mensaje Archivo subido. Podemos verificar en nuestro directorio.

Ahora vemos una forma libre de librerías en JavaScript.

Enviar datos de formulario y archivo con PHP y JavaScript (sin librerías)

Muy bien vamos a usar el mismo formulario para escribir datos y adjuntar un archivo. Tendrá la siguiente estructura:

<form id="form_archivo_js" action="">
    <label>Nombres</label>
    <input type="text" name="nombres" class="form-control">
    <label>Mensaje</label>
    <textarea name="mensaje" class="form-control"></textarea>
    <label>Archivo a subir</label>
    <input type="file" name="archivo">
    <br >
    <button id="btnSendFile" type="submit" class="btn btn-primary">Enviar</button>
</form>

Vamos a crear otro archivo JavaScript para colocar nuestro código, lo llamaremos script_vanill.js y tendrá el siguiente código: (allí mismo comento el funcionamiento de este)

// definimos el formulario a usar formFile
const formFile = document.getElementById('form_archivo_js');

// definimos el boton a usar btnSendFile
const btnSendFile = document.getElementById("btnSendFile");

// definimos la accion clic al pulsar el boton btnSendFile
btnSendFile.addEventListener('click', function(event){

    event.preventDefault(); // anulamos que boton nos lleve a otro lado

    //usamos FormData para compilar los datos a enviar
    const formattedFormData = new FormData(formFile); 

    // llamamos a una funcion que enviara los datos,
    // como parametro pasamos los datos del formulario
    postData(formattedFormData);

});

// nuestra función personalizada que envia datos y recibe respuesta del servidor
// usamos async/await para trabajar de mejor manera la respuesta por parte del servidor

async function postData(formattedFormData){

    // en fetch especificamos el archivo en el servidor que captura los datos enviados
    const response = await fetch('procesar_datos_archivo.php',{
        // el metodo a usar
        method: 'POST',
        // los datos a ser enviados
        body: formattedFormData
    });
   
    // data contendra la respuesta del servidor
    const data = await response.text();

    // y la mostramos en un alert
    alert(data);

}

A simple vista solo usando JavaScript es más práctico y menos líneas, y lo eso!. Veamos como trabaja:

Revisamos si se subió el archivo al directorio upload.

Consideraciones finales

Esto es un ejemplo práctico de como enviar datos y archivo al servidor, pero no para producción, ya que las respuestas del servidor no tienen un formato adecuado, podemos mejorarla usando JSON por ejemplo y un mejor diseño.

Los datos antes de enviar deben ser validados y en el servidor también para evitar algún tipo de ataque.

Y si vas a permitir la subida de archivos también debe tener validaciones para el tipo de archivo a subir, donde subirlo, el tamaño, etc.

Espero les sirva el artículo y si les fue útil compártanlo, nos ayuda mucho eso 🙂

Créditos:

https://gist.github.com/jesperorb/a6c12f7d4418a167ea4b3454d4f8fb61