Subir archivos CSV a MySql con PHP

Esta entrada la destinaré a una de las utilidades más usadas a la hora de importar datos. Es muy probable que los clientes nos den ficheros con los datos que deben subirse, procesarse e insertarse en una base de datos mediante MySQL. Por eso, el objetivo aquí es aprender a subir archivos CSV a MySQL con PHP.

1.- Conexión:

// conexión
$mysqli = @new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);

2.- Conocer el archivo / extensión:

Debemos conocer el nombre del archivo y la extensión del mismo. El archivo se recoge mediante un formulario por su input de ficheros.

Existe una clase en PHP que nos da información de los archivos que subimos, la clase SplFileInfo tiene un método llamado pathinfo al que le podemos pasar el atribujo PATHINFO_EXTENSION.

$filename=$_FILES["file"]["name"];
$info = new SplFileInfo($filename);
$extension = pathinfo($info->getFilename(), PATHINFO_EXTENSION);

3.- Leer y guardar los datos:

El ejemplo escogido será la importación de usuarios con sus correos electrónicos. Debemos suponer que tenemos preparada una tabla en nuestra base de datos que reciba tal información porque la vamos a procesar mediante consultas SQL.

Pero antes de nada debemos recorrer el archivo. Normalmente los ficheros CSV separan los datos con «,». Por lo tanto nuestro manejador irá saltando de dato en dato cada vez que encuentre una coma.

$filename = $_FILES['file']['tmp_name'];
$handle = fopen($filename, "r");

while( ($data = fgetcsv($handle, 1000, ";") ) !== FALSE )
{
  $q = "INSERT INTO importacion (nombre, apellido, correo) VALUES (
	'$data[0]', 
	'$data[1]',
	'$data[2]'
)";

//....

Conforme vamos recorriendo el fichero generamos una consulta con INSERT para que se vayan rellenando las filas al lanzar la consulta.

Si todo ha ido bien y hemos terminado de recorrerlo (cambiar la longitud del manejador dependiendo del tamaño que tenga), cerramos el archivo que hemos leído con el método fclose($handle).

4.- Formulario de recogida:

Este apartado es sencillo, tan solo generamos nuestro formulario con el detalle siempre de que vamos a subir ficheros, lo que quiere decir que vamos a necesitar el atributo enctype

<form enctype="multipart/form-data" method="post" action="">
    CSV File:<input type="file" name="file" id="file">
    <input type="submit" value="Enviar" name="enviar">
</form>

El resultado final del fichero funcional sería este…

<?php 

// conexión
$mysqli = @new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);

if (isset($_POST['enviar']))
{
	
  $filename=$_FILES["file"]["name"];
  $info = new SplFileInfo($filename);
  $extension = pathinfo($info->getFilename(), PATHINFO_EXTENSION);

   if($extension == 'csv')
   {
	$filename = $_FILES['file']['tmp_name'];
	$handle = fopen($filename, "r");

	while( ($data = fgetcsv($handle, 1000, ";") ) !== FALSE )
	{
	   $q = "INSERT INTO importacion (nombre, apellido, correo) VALUES (
		'$data[0]', 
		'$data[1]',
		'$data[2]'
	)";

	$mysqli->query($q);
   }

      fclose($handle);
   }
}

?>

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Importación</title>
</head>
<body>
	
<form enctype="multipart/form-data" method="post" action="">
   CSV File:<input type="file" name="file" id="file">
   <input type="submit" value="Enviar" name="enviar">
</form>

</body>
</html>

Hasta aquí el tutorial de cómo subir archivos CSV a MySQL con ayuda de PHP, un script mejorado del artículo de Miguel Ángel en su web.

10 comentarios en «Subir archivos CSV a MySql con PHP»

    • los archivos csv manejan diferentes tipos de separadores, entre esos esta la coma que es la más común, pero también se hace uso del punto y coma «;»o del doble punto «:», estos se usan dependiendo de la necesidad o de como este ajustada la base de daros para importar o exportar.

      Responder
  1. Hola! He copiado el script tal como esta, y no me carga los datos en la BD. Uso php7 con maria db…
    Tampoco me tira errores en el log del apache ni en la página web…
    ¿Alguna idea del por qué podría ser?

    Responder
  2. Que tal, me da estos errores.

    Notice: Undefined offset: 1 in C:\xampp\htdocs\sistema1\vistas\exportacion.php on line 21

    Notice: Undefined variable: mysqli in C:\xampp\htdocs\sistema1\vistas\exportacion.php on line 25

    Fatal error: Uncaught Error: Call to a member function query() on null in C:\xampp\htdocs\sistema1\vistas\exportacion.php:25 Stack trace: #0 {main} thrown in C:\xampp\htdocs\sistema1\vistas\exportacion.php on line 25

    Responder
  3. Hola! sabes por que recibo estos warnings?
    Notice: Undefined offset: 1 in C:\xampp\htdocs\tr\up.php on line 22

    Notice: Undefined offset: 2 in C:\xampp\htdocs\tr\up.php on line 23

    Notice: Undefined offset: 3 in C:\xampp\htdocs\tr\up.php on line 24

    Warning: mysqli::query(): Couldn’t fetch mysqli in C:\xampp\htdocs\tr\up.php on line 27

    Responder
  4. Hola,

    Primero que todo gracias por el código, me funcionó para cargar un archivo csv, sin embargo, lo que necesito es subir un csv desde un link, es decir que no hago uso del formulario ya que va a ser un proceso automático ¿Podría orientarme en ese caso?

    Mil gracias

    Responder
  5. Hola

    Y si es archivo de texto y el archivo no tiene separadores? Cómo debo escribir que sea por posiciones de carácteres?

    Ejemplo de datos:

    1000 Grupo $1000 -$100 $900

    Alguna idea??

    Responder

Deja un comentario