Importar a base de datos desde archivo CSV con PHP

Para poder importar información con PHP es muy muy sencillo, realmente ya tiene todo directamente, vamos a utilizar la función fgetcsv que básicamente lo que hace es leer nuestro archivo y su información fila por fila y después podemos hacer lo que queramos con dicha información.

Recuerden que en este tutorial estamos utilizando nuestro framework Bee framework en su versión 1.1.4, es gratis y pueden descargarlo directamente en nuestro Github.

Simplemente necesitaremos un archivo para nuestro front end donde estará el formulario con un campo de tipo file, y un atributo accept para definir que tipo de archivos aceptará el input, ojo, es importante saber que aunque nosotros definamos o filtremos con ese atributo, uno fácilmente puede quitarle el atributo en el inspector del sitio, así que también debería existir una validación en el backend de la extensión y tipo de archivo.

Recuerda que debes agregar el atributo enctype con valor multipart/form-data en el formulario, de lo contrario nunca recibirás los archivos en el back end.

Este es nuestro formulario a grandes rasgos:

<div class="col-12">
    <div class="card">
      <div class="card-header">Completa el formulario</div>
      <div class="card-body">
        <form action="home/post_importar_csv" method="POST" enctype="multipart/form-data">
          <?php echo insert_inputs(); ?>
          
          <div class="mb-3">
            <label for="archivo">Selecciona un archivo <code>.csv</code></label>
            <input type="file" class="form-control" name="archivo" id="archivo" accept=".csv, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, application/vnd.ms-excel" required>
          </div>
          <button class="btn btn-success" type="submit">Importar</button>
        </form>
      </div>
    </div>
  </div>

Y mostraría algo así:

Una vez que seleccionemos nuestro archivo csv y le demos importar vamos a mandar la información ya sea a una ruta especial o a un archivo, en nuestro caso, mandaremos el POST a la ruta “home/importar_csv” donde se recibirá y tendremos la siguiente función que hará todo el trabajo:

<?php // Recibe la información del formulario

function post_importar_csv()
  {
    try {
      if (!check_posted_data(['csrf'], $_POST) || !Csrf::validate($_POST["csrf"])) {
        throw new Exception("Acceso no autoritzado.");
      }

      $rows     = [];
      $total    = 0;
      $inserted = 0;
      $errors   = 0;

      if (!isset($_FILES["archivo"])) {
        throw new Exception("Selecciona un archivo CSV válido.");
      }

      $file     = $_FILES["archivo"];
      $tmp      = $file["tmp_name"];
      $filename = $file["name"];
      $size     = $file["size"];

      if ($size < 0) {
        throw new Exception("Selecciona un archivo válido por favor.");
      }

      $handle = fopen($tmp, "r");

      while (($data = fgetcsv($handle)) !== false) {
        $rows[] = $data;
      }

      unset($rows[0]); // se eliminan las cabeceras
      $total = count($rows);
      
      if ($total <= 0) {
        throw new Exception("El archivo proporcionado está vacio.");
      }

      // Insertando información
      foreach ($rows as $r) {
        $data =
        [
          'titulo'      => $r[0],
          'contenido'   => $r[1],
          'creado'      => now(),
          'actualizado' => now()
        ];

        if (Model::add('posts', $data) === false) {
          $errors++;
          continue;
        }

        $inserted++;
      }

      Flasher::new(sprintf('Se han insertado <b>%s</b> de <b>%s</b> registros con éxito.', $inserted, $total), 'success');

      if ($errors > 0) {
        Flasher::new(sprintf('Tuvimos problemas al importar <b>%s</b> registros.', $errors), 'danger');
      }

      Redirect::back();

    } catch (Exception $e) {
      Flasher::new($e->getMessage(), 'danger');
      Redirect::back();
    }
  }

Las líneas que hacen la lectura de nuestro contenido en el archivo csv son las que aparecen abajo, simplemente utilizamos fopen y fgetcsv en combinación para leer la información, la asignamos en una variable y después vamos a iterar sobre esa variable para ir agregando los registros a la base de datos.

  $handle = fopen($tmp, "r");
  while (($data = fgetcsv($handle)) !== false) {
    $rows[] = $data;
  }

Para guardar en la base de datos iteramos sobre $rows y usamos nuestro modelo para generar el nuevo registro.

// Insertando información
foreach ($rows as $r) {
  $data =
  [
    'titulo'      => $r[0],
    'contenido'   => $r[1],
    'creado'      => now(),
    'actualizado' => now()
  ];

  if (Model::add('posts', $data) === false) {
    $errors++;
    continue;
  }

  $inserted++;
}

Lo último solo es mostrar notificaciones al usuario y regresarlo a la ruta inicial del formulario, si se insertan 60 registros, se lo mencionaremos, o si hay errores, también.

Flasher::new(sprintf('Se han insertado <b>%s</b> de <b>%s</b> registros con éxito.', $inserted, $total), 'success');

if ($errors > 0) {
 Flasher::new(sprintf('Tuvimos problemas al importar <b>%s</b> registros.', $errors), 'danger');
}

Redirect::back();

Y listo, con eso podemos importar los registros necesarios y guardarlos en la base de datos.

Importación concluida
Base de datos con nuevos registros importados

Si te gustó o te fue de ayuda este tutorial, no olvides seguirnos en nuestra redes sociales aquí abajito o compartir, te lo agradeceremos mucho.

Deja que llegue a más gente

Share on facebook
Facebook
Share on twitter
Twitter
Share on pinterest
Pinterest
Share on linkedin
LinkedIn

Considera suscribirte para más

Flecha apuntando

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

¿Ya nos sigues?

Más Populares

Recibe Todo en Tu Inbox

Suscríbete a nuestro boletín

Sin spam, solo notificaciones de nuevos cursos y contenido de la Academia.

Destacados para ti

Relacionados

Como hacer un Mock Up en Photoshop

En esta entrada te enseñaremos como hacer un mock up sencillo y profesional con Photoshop, antes de continuar te invitamos a suscribirte a nuestro canal

Selecciona tu moneda
MXN
USD