Considere un archivo CSV como este
item1,"description 1"
item2,"description 2"
item3,"description 3
description 3 continues on new line"
item4,"description 4"
que debe analizarse así
item1,"description 1"
item2,"description 2"
item3,"description 3 description 3 continues on new line"
item4,"description 4"
¿Hay alguna forma de analizar este CSV en PHP que tiene valores de varias líneas?
Aquí hay algunos ejemplos prácticos de cómo hacerlo. Estoy usando fgetcsv:
CSV en variable de cadena $CsvString:
$fp = tmpfile();
fwrite($fp, $CsvString);
rewind($fp); //rewind to process CSV
while (($row = fgetcsv($fp, 0)) !== FALSE) {
print_r($row);
}
CSV en el archivo:
if (($handle = fopen("test.csv", "r")) !== FALSE) {
while (($row = fgetcsv($handle, 0, ",")) !== FALSE) {
print_r($row);
}
fclose($handle);
}
-
Excelente respuesta Tengo CSV cargados por el usuario con \r finales de línea (no tengo idea de por qué), y tuve que reemplazarlos antes de analizar CSV. Dado que str_getcsv no maneja varias líneas, y algunas filas tienen líneas nuevas, esto (aunque es un poco complicado, poner cosas en un archivo temporal solo para que PHP lo analice) funciona.
– csga5000
30 mayo 2015 a las 21:30
fgetcsv
debería ser capaz de analizar correctamente esto.
De todos modos, no recomendaría hacer esto a mano, hay muchos errores de este tipo al analizar CSV.
-
El problema es que estaba usando fgets leer la línea del archivo y luego str_getcsv para analizar la cadena en lugar de usar solo fgetcsv. Funcionaba bien con columnas de una sola línea pero no con columnas de varias líneas. Incluso PHP.net difícil dice que fgetcsv “Obtiene la línea del archivo” parece que la “línea” aquí no es una línea real en un archivo de texto sin formato, sino toda la fila real con todos los datos de varias líneas.
– Ergec
19 de enero de 2011 a las 12:50
-
Me encontré con el mismo problema hoy e hice un poco pruebaque prueba su afirmación sobre líneas refiriéndose a csv-filas y no real líneas de archivo.
– Raúl
25 de marzo de 2013 a las 12:22
-
esperaba usar
str_getcsv
ya que no tiene que cargar todo el archivo en la memoria, solo la fila que está en rojo.fgetcsv
funciona con campos CSV de varias líneas, perostr_getcsv
aparentemente no lo hace.– Erfán
19 de diciembre de 2018 a las 3:33
-
@Erfan
fgetcsv
¡También solo lee una línea a la vez desde un identificador de archivo abierto…!?– deceze
♦19 de diciembre de 2018 a las 6:26
oriadam
Basado en la respuesta de StanleyD, pero usando un bloque de memoria temporal (en lugar de escribir en el disco) para un mejor rendimiento:
$fp = fopen('php://temp','r+');
fwrite($fp, $CsvString);
rewind($fp); //rewind to process CSV
while (($row = fgetcsv($fp, 0)) !== FALSE) {
print_r($row);
}
Aquí hay una solución rápida y fácil usando la función PHP str_getcsv()
Aquí hay un ejemplo:
function parse_csv( $filename_or_text, $delimiter=",", $enclosure=""", $linebreak="\n" )
{
$return = array();
if(false !== ($csv = (filter_var($filename_or_text, FILTER_VALIDATE_URL) ? file_get_contents($filename_or_text) : $filename_or_text)))
{
$csv = trim($csv);
$csv = mb_convert_encoding($csv, 'UTF-16LE');
foreach(str_getcsv($csv, $linebreak, $enclosure) as $row){
$col = str_getcsv($row, $delimiter, $enclosure);
$col = array_map('trim', $col);
$return[] = $col;
}
}
else
{
throw new \Exception('Can not open the file.');
$return = false;
}
return $return;
}
Imagine una situación en la que necesita una función que funcione tanto con URL como con texto delimitado por comas. Esta es exactamente la función que funciona así. Simplemente inserte una URL CSV o texto separado por comas y funcionará muy bien.
@goreSplatter, o simplemente use uno existente.
– Bart Kiers
19 de enero de 2011 a las 8:18
@Bart Lo siento, omití la otra solución obvia.
– Linus Klein
19 de enero de 2011 a las 8:21
posible duplicado del archivo parse csv php
– fuera
26 de diciembre de 2011 a las 7:36