Domanda

Quando uso fputcsv per scrivere una riga nell'handle di un file aperto, PHP aggiungerà un carattere di chiusura a qualsiasi colonna che ritiene ne abbia bisogno, ma lascerà le altre colonne senza gli allegati.

Ad esempio, potresti ritrovarti con una riga come questa

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

A parte aggiungere uno spazio fasullo alla fine di ogni campo, esiste un modo per forzare fputcsv a racchiudere sempre le colonne con il carattere recinto (per impostazione predefinita è ")?

È stato utile?

Soluzione

No, fputcsv() racchiude il campo solo nelle seguenti condizioni

/* 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(' ')
)

Non esiste l'opzione "allega sempre".

Altri suggerimenti

Non sono soddisfatto di questa soluzione, ma è quello che ho fatto e ho lavorato.L'idea è di impostare un carattere vuoto come carattere di recinzione su fputcsv e aggiungere alcune virgolette su ogni elemento dell'array.

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

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

Basandosi su Martino, se vuoi evitare di inserire caratteri che non derivano dall'array di origine (Chr(127), Chr(0), ecc.), puoi invece sostituire la riga fputcsv() con la seguente:

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

Certo, fputs() è più lento di fputcsv(), ma è un output più pulito.Il codice completo è quindi:

/***
 * @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);

Dopo un sacco di tentativi e qualche noioso controllo dei caratteri, ho una versione dei codici sopra citati di Diego E Mah che rimuoverà correttamente gli involucri e li sostituirà con virgolette doppie su tutti i campi in fputcsv.e quindi inviare il file al browser per scaricarlo.

Ho anche avuto un problema secondario di non essere in grado di essere sicuro che le virgolette doppie fossero sempre/mai sfuggite.

Specificamente per quando si invia direttamente al browser utilizzando il flusso php://input come indicato da Diego. Chr(127) è un carattere di spazio, quindi il file CSV ha alcuni spazi in più rispetto al resto, ma credo che questo elimini il problema di chr(0) Caratteri NULL in 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;
}

Spero che questo sia utile per qualcuno.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top