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:

Estructura de archivos envio de formularios php javascript async  await

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:

  • En action especificamos el archivo que recibirá los datos enviados desde este formulario. En este caso el archivo se llama procesar_datos.php.
  • También definido el atributo method, para definir el método como enviaremos los datos, los más usados son POST y GET.
  • Definimos dos entradas de texto (input text y textarea, con los nombres nombres y mensaje respectivamente) y es importante especificar sus nombres en el atributo name.
  • Definimos un botón de tipo submit. Por defecto al pulsar enviara toda la información de las entradas del formulario.
<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:

Envio de Formulario php javascript async await
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:

  • en el form el atributo action, cambiar por el archivo procesar_datos_archivo.php que mostrará los datos enviados y también subirá el archivo.
  • en el mismo form añadimos un atributo más: enctype con el valor multipart/form-data para especificar que incluiremos un elemento tipo file.
  • y un control más tipo file con el nombre archivo, usado para adjuntar un archivo a nuestro formulario.

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:

Envio de Formulario php javascript async await
Resultado

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

Estructura de archivos envio de formularios php javascript async  await

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:

  • Al formulario le añadir el atributo id, y le damos un identificador unico: form_jquery.
<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:

Envio de Formulario php javascript async await

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:

  • El atributo id, colocamos otro valor form_archivo_jquery.
  • Y añadimos el control input tipo file, con el nombre archivo.
<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.

Envio de Formulario php javascript async await

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.

Estructura de archivos envio de formularios php javascript async  await

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:

  • El form con atributo id, tiene el valor form_archivo_js.
  • El botón que hará el envío de los datos tiene atributo id, con el valor btnSendFile.
<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:

Envio de Formulario php javascript async await

Revisamos si se subió el archivo al directorio upload.

Estructura de archivos envio de formularios php javascript async  await

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

Leave a Reply

Your email address will not be published. Required fields are marked *