2010-03-22 19 views
30

Cuando uso fputcsv para escribir una línea en un descriptor de archivo abierto, PHP agregará un carácter adjunto a cualquier columna que crea que lo necesita, pero dejará otras columnas sin el recintos.Obligar a fputcsv a utilizar el gabinete para * todos * Campos

Por ejemplo, usted podría terminar con una línea como esta

11,"Bob ",Jenkins,"200 main st. USA ",etc 

corto de añadir un espacio falso al final de cada campo, ¿hay alguna manera de forzar fputcsv para encerrar siempre columnas con el recinto (por defecto a ") personaje?

+0

Sólo por curiosidad, ya que mi conjetura es que estás en cuestión era: Re a 'Magento/Varien_Io_File :: streamWriteCsv()' (que al final sólo utiliza 'fputcsv'), hizo ¿alguna vez encuentras una buena solución para esto? Posiblemente usando 'Varien_File_Csv'? – pspahn

+0

@pspahn Nunca lo hizo, (y esto fue hace más de cuatro años, pero no creo que haya sido específicamente relacionado con Magento) –

Respuesta

25

no, fputcsv() sólo encierra el campo bajo las siguientes condiciones

/* enclose a field that contains a delimiter, an enclosure character, or a newline */ 
if (FPUTCSV_FLD_CHK(delimiter) || 
    FPUTCSV_FLD_CHK(enclosure) || 
    FPUTCSV_FLD_CHK(escape_char) || 
    FPUTCSV_FLD_CHK('\n') || 
    FPUTCSV_FLD_CHK('\r') || 
    FPUTCSV_FLD_CHK('\t') || 
    FPUTCSV_FLD_CHK(' ') 
) 

no hay "siempre encierran" opción.

+2

¡triste, porque fgetcsv falla con Österreich sin comillas dobles! – nalply

+9

VolkerK es, por supuesto, bastante cierto. fputcsv no puede ayudarte con este problema (tengo el mismo problema). Permítanme ayudarlo a comenzar la próxima búsqueda que hará: [http://stackoverflow.com/questions/3933668/convert-array-into-csv](http://stackoverflow.com/questions/3933668/convert-array-into-csv) – ftrotter

14

No estoy contento con esta solución pero es lo que hice y trabajé. La idea es establecer un char vacío como carácter de recinto en fputcsv y agregar algunas comillas en cada elemento de su matriz.

function encodeFunc($value) { 
    return "\"$value\""; 
} 

fputcsv($handler, array_map(encodeFunc, $array), ',', chr(0)); 
+2

Incluir chr (0) en el archivo provoca problemas en algunos scripts de importación si el archivo es UTF-8 –

+0

el csv contiene^@ si está utilizando chr (0) – Mike

+1

Puede deshacerse de los nulos (chr (0)) en el archivo resultante filtrándolos después de que haya terminado de generar su csv: 'file_put_contents ($ file, str_replace (chr (0), '', file_get_contents ($ file))); '. Además, su 'encodeFunc' necesitará escapar de comillas dobles si sus valores las tienen. Ver mi revisión [aquí] (https://gist.github.com/anonymous/223ea7353626bc6a6a9e#file-csvenclosed-php). Aparte de eso, parece funcionar, solo ten en cuenta que es un truco. – Mahn

2

Después de una gran cantidad de scrafffing alrededor y algunas comprobaciones carácter algo tedioso, que tienen una versión de los códigos anteriormente referenciados por Diego y Mahn que se tira correctamente fundas y reemplazar con comillas dobles en todos los campos en fputcsv. y luego muestra el archivo en el navegador para descargar.

También tuve un problema secundario de no poder estar seguro de que las comillas dobles siempre/nunca se escaparon.

Específicamente para cuando la salida directamente al navegador utilizando el flujo de entrada php: // como se hace referencia por Diego. Chr(127) es un carácter de espacio, por lo que el archivo CSV tiene algunos espacios más que lo contrario, pero creo que esto evita el problema de chr(0) caracteres NULOS en UTF-8.

/*** 
* @param $value array 
* @return string array values enclosed in quotes every time. 
*/ 
function encodeFunc($value) { 
    ///remove any ESCAPED double quotes within string. 
    $value = str_replace('\\"','"',$value); 
    //then force escape these same double quotes And Any UNESCAPED Ones. 
    $value = str_replace('"','\"',$value); 
    //force wrap value in quotes and return 
    return '"'.$value.'"'; 
} 


$result = $array_Set_Of_DataBase_Results; 
$fp = fopen('php://output', 'w'); 
if ($fp && $result) { 
    header('Content-Type: text/csv'); 
    header('Content-Disposition: attachment; filename="export-'.date("d-m-Y").'.csv"'); 
    foreach($result as $row) { 
     fputcsv($fp, array_map("encodeFunc", $row), ',', chr(127)); 
    } 
    unset($result,$row); 
    die; 
} 

Espero que esto sea útil para alguien.

6

Basándose en respuesta Martin 's, si se quiere evitar la inserción de cualquier carácter que no se derivan de la matriz de origen (Chr(127), Chr(0), etc), puede reemplazar la línea fputcsv() con el siguiente cambio:

fputs($fp, implode(",", array_map("encodeFunc", $row))."\r\n"); 

Concedido, fputs() es más lento que fputcsv(), pero es una salida más limpia. El código completo es así:

/*** 
* @param $value array 
* @return string array values enclosed in quotes every time. 
*/ 
function encodeFunc($value) { 
    ///remove any ESCAPED double quotes within string. 
    $value = str_replace('\\"','"',$value); 
    //then force escape these same double quotes And Any UNESCAPED Ones. 
    $value = str_replace('"','\"',$value); 
    //force wrap value in quotes and return 
    return '"'.$value.'"'; 
} 

$fp = fopen("filename.csv", 'w'); 
foreach($table as $row){ 
    fputs($fp, implode(",", array_map("encodeFunc", $row))."\r\n"); 
} 
fclose($fp); 
+0

Encontré realmente después de publicar esta respuesta que con 'fputcsv' que la función es realmente coja y usando funciones estándar * write-to-file * ya que también se ha ordenado mi código y eludido todos los problemas con la coherencia CSV en plataformas y programas. – Martin

+0

Gracias por el buen ejemplo. Necesitaba siempre adjuntar todos los valores entre comillas. Y, necesitaba forzar los finales de línea a CR + LF en lugar de solo a LF. Este ejemplo resuelve ambos problemas. –

Cuestiones relacionadas