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.
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.
4 comentarios en “Importar a base de datos desde archivo CSV con PHP”
Muchas gracias. Me ha servido de ayuda para mi proyecto.
Saludos
Para mostrar los registros que no se subieron?
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.
Gracias INg por su dato