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.

¿Quieres desarrollar sistemas profesionales?

Si nos sigues desde hace tiempo o eres nuevo en la Academia y quieres apoyar nuestro trabajo, te invitamos a nuestro Pack Full Stack, contiene todos nuestros cursos avanzados y premium.

¿Nos ayudas compartiendo?

Considera suscribirte para más

4 comentarios en “Importar a base de datos desde archivo CSV con PHP”

    1. Claro, sencillo, vas a hacerlo así (es una forma), crea un array afuera de tu iteración, no sé, $errores, y en tu loop cuando haya error agrega al array $errores ese registro que presentó error, y después puedes listar esos registros.

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