Chose Language:
Author: Admin/Publisher | checked

PHP fgetcsv

Hoy veremos la función fgetcsv de PHP, como podemos ver en la página de PHP esta función hace lo siguiente: Obtiene una línea de un puntero a un fichero y la analiza en busca de campos CSV

Esta definición es un tanto engañosa, por ello fui a la versión en inglés:

Gets line from file pointer and parse for CSV fields

php.net -fgetcsv

Un pointer no es lo mismo que un file pointer aunque estan relacionados, en el siguiente link podrá leer sobre exactamente lo que es un file pointer https://docs.microsoft.com/en-us/windows/win32/fileio/file-pointers.

Vamos a poner esto más en blanco y la definición nos quedaría:

Obtiene una línea de un file pointer y la analiza en busca de campos CSV

Description
fgetcsv(
    resource $stream,
    ?int $length = null,
    string $separator = ",",
    string $enclosure = "\"",
    string $escape = "\\"
): array|false
Sintaxis
fgetcsv($stream,$length,$separator,$enclosure,$escape)

Valores de la función

Parametros

$stream – es un stream de datos obtenido después de usar fopen u otra función para abrir un archivo (popen(),fsockopen()) en realidad sería el puntero al archivo que se ha abierto.

ejemplo: $stream = fopen("mycsv.csv", "r"))

$length – la longitud máxima que se espera de la línea obtenida del csv, esta línea serian las filas en una plantilla de Excel u otro programa similar. Este valor es opcional a partir de PHP 8.0, en caso de no especificar tomará el máximo valor posible.

$separator -(opcional) indica el delimitador , en este caso , es el delimitador por defecto, ya que los csv utilizan la , para separar los distintos valores.

$enclosure -(opcional) en este caso " es el valor de enclosure, este es el valor con el que está cercado el campo

$escape -(opcional) define el carácter de escape, en este caso es \ , si $escape es igual a "" deshabilita esta propiedad.

[info]Para entender mejor estos valores veremos como sería un archivo con formato .csv antes de pasar a los ejemplos[/info]

Valores de retorno

Retornará un array indexado en caso de éxito y false si no se ha podido obtener la línea que sigue.

Que es un CSV

Generalmente, se utilizan programas como Excel y otros similares para realizar distintos cálculos, funciones o incluso organizar información. Esta clase de programas nos permiten guardar como archivos csv.

Las siglas csv significan valores separados por coma y literalmente es lo que hacen por ejemplo si tenemos la siguiente tabla de excel:

productopreciostock
percha5020
almohada20012
colcha5112
pantuflas150231
toalla belagio55031
acolchado linea blanca330020
vela diseño20822

Cuando guardemos el archivo como csv pasará a estar de esta manera

archivo.csv
producto,precio,stock
percha,50,20
almohada,200,12
cocha,511,2
pantuflas,150,231
toalla belagio,550,31
acolchado línea blanca,3300,20
vela diseño,208,22

Ejemplo de uso de PHP fgetcsv

Empecemos viendo el ejemplo más simple que podemos con esta función e iremos viendo como todo tiene sentido.

Obteniendo la primera linea
<?php
if (($gestor = fopen("cvs.csv", "r")) !== FALSE) {
	if (($datos = fgetcsv($gestor, 1000, ",")) !== FALSE)
		var_dump($datos);
}
?>
array(5) { [0]=> string(0) "" [1]=> string(0) "" [2]=> string(0) "" [3]=> string(0) "" [4]=> string(0) "" } 

Ok que ha pasado aquí, ¿no estoy obteniendo datos? L o que ha pasado en este ejemplo es que nuestra tabla no empieza en la columna 0 – fila 0 y por ende está obteniendo los valores sin nada de la fila 0.

Cuando convertí mi archivo de Excel a CSV este paso las filas sin nada como ,,, y también las columnas ,,

Ahora veamos el ejemplo de tabla que vimos en Que es un CSV, pero esta vez empezando desde columna 0 y fila 0

ejemplo fgetcsv
<?php
if (($gestor = fopen("cvs.csv", "r")) !== FALSE) {
	while (($datos = fgetcsv($gestor, 1000, ",")) !== FALSE) {
		$numero = count($datos);
		for ($c=0; $c < $numero; $c++) {
			echo $datos[$c];
		}
		echo "<br/>";
	}
	fclose($gestor);
}
?>
productopreciostock
percha5020
almohada20012
colcha5112
pantuflas150231
toalla belagio55031
acolchado linea blanca330020
vela dise�o20822

Ejercicios:

Ejercicio 1

En los 2 ejemplos anteriores vimos que al guardar como CSV una tabla que no empieza en posición obtendremos información en blanco.

Crea una tabla en Excel en un lugar inapropiado y guarda esta en un archivo cvs.csv, al código visto en el ejemplo 2 modifícalo para que este depure la información para solo obtener los datos pertinentes.

Para poder realizar este ejercicio necesitarás un poco de investigación de tu parte.

Ejercicio 2

En el ejercicio anterior se pide que se devuelva los campos limpios sin los espacios innecesarios que nos da poner una tabla en un lugar inapropiado antes de exportarla como .csv.

Para ello debemos de tener en cuenta lo que hicimos en los 2 ejemplos anteriores.

En el ejemplo 1 vimos como obtener una fila de este .csv, mientras que en el ejemplo 2 recorrimos por completo este .csv

Como ve en el ejercicio, se pide un poco de investigación de nuestra parte: y de hecho es que necesitaremos de una función para rebobinar(rewind) a nuestro puntero a archivo.

Ejercicio 2 Resuelto

Veamos como sería nuestro ejercicio resuelto:

Nuestra parte principal[csv4.php]
<?php

$list=[];
$col=[];
if (($gestor = fopen("cvs.csv", "r")) !== FALSE) {
	//preset cols
	
	$data_analysis = fgetcsv($gestor, 1000, ",");
	$number = count($data_analysis);
	for ($n = 0 ; $n < $number; $n++) {
		$col[$n] = false;
	}
	rewind($gestor);
	
                //lines iteration
	while (($data = fgetcsv($gestor, 1000, ","))!==FALSE) {
		$not_empty = !checkRowEmptiness($number,$data);
		if($not_empty)
			$list[] = $data;
	}
	$depurated_list =[];
	foreach ($list as $element) {
		$depurated_list[] = array_slice($element,sliceposition($col));
	}
	var_dump($depurated_list);
}

Como podemos ver desde el comentario //preset cols hasta el rewind hara que $col que son las columnas que tenemos en la tabla sean false por defecto.

Luego haremos un rewind, ya que deseo empezar desde el inicio a chequear todo esto.

En el siguiente while chequearemos si las líneas están vacías o no, de esta manera eliminaremos las filas que están totalmente vacías. Este array nuevo será $list[]

Tabla ficticia
«»«»«»«»«»«»
«»«»«»«»«»«»
«»«»xxxx
«»«»xxxx
«»«»xxxx
«»«»xxxx
x representa un campo con contenido y «» uno sin contenido

Como se veria el contenido de $list[] si fuera una tabla

Tabla ficticia
«»«»xxxx
«»«»xxxx
«»«»xxxx
«»«»xxxx
x representa un campo con contenido y «» uno sin contenido

Ahora deberemos depurar nuestras filas para no tener nuestras columnas vacías para eso utilizaremos el array_slice que nos dará un nuevo array a partir del anterior, el cual lo agregaremos a nuestra lista depurada $depurated_list[]

Por otra parte, tenemos nuestras funciones:

función checkRowEmptiness [csv4.php]
/**
* Check if the row is empty, in case its empty
* @param $number
* @param $data
* 
* @return bool
*/
function checkRowEmptiness(int $number,array $data): bool{
	global $col;
	for ($i=0; $i < $number; $i++) {
		if ($data[$i]!= "" ) {
			$col[$i] = true;
			return false;
		}
	}
	return true;
}
función sliceposition [csv4.php]
/**
* Return slice position depending in column_emptiness after found first colum with data
* @param $col
* 
* @return int
*/
function sliceposition(array $col): int{
	for ($i=0; $i<count($col); $i++) {
		if ($col[$i]== true)
			return $i;
	}
}
Category: php
Something wrong? If you found an error or mistake in the content you can contact me on Twitter | @luisg2249_luis.
Last 4 post in same category