Forcing fputcsv to Use Enclosure For *all* Fields

后端 未结 5 1915
星月不相逢
星月不相逢 2020-11-29 11:44

When I use fputcsv to write out a line to an open file handle, PHP will add an enclosing character to any column that it believes needs it, but will leave other columns with

相关标签:
5条回答
  • 2020-11-29 12:21

    A "quick and dirty" solution is to add ' ' at the end of all of your fields, if it's acceptable for you:

    function addspace($v) {
      return $v.' ';
    }
    fputcsv($handle, array_map('addspace', $fields));
    

    PS: why it's working? see Volkerk answer ;)

    0 讨论(0)
  • 2020-11-29 12:26

    Not happy with this solution but it is what I did and worked. The idea is to set an empty char as enclosure character on fputcsv and add some quotes on every element of your array.

    function encodeFunc($value) {
        return "\"$value\"";
    }
    
    fputcsv($handler, array_map(encodeFunc, $array), ',', chr(0));
    
    0 讨论(0)
  • 2020-11-29 12:30

    Building on Martin's answer, if you want to avoid inserting any characters that don't stem from the source array (Chr(127), Chr(0), etc), you can replace the fputcsv() line with the following instead:

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

    Granted, fputs() is slower than fputcsv(), but it's a cleaner output. The complete code is thus:

    /***
     * @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 讨论(0)
  • 2020-11-29 12:42

    After a lot of scrafffing around and some somewhat tedious character checking, I have a version of the above referenced codes by Diego and Mahn that will correctly strip out encasings and replace with double quotes on all fields in fputcsv. and then output the file to the browser to download.

    I also had a secondary issue of not being able to be sure that double quotes were always / never escaped.

    Specifically for when outputting directly to browser using the php://input stream as referenced by Diego. Chr(127) is a space character so the CSV file has a few more spaces than otherwise but I believe this sidesteps the issue of chr(0) NULL characters 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;
    }
    

    I hope this is useful for some one.

    0 讨论(0)
  • 2020-11-29 12:43

    No, fputcsv() only encloses the field under the following conditions

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

    There is no "always enclose" option.

    0 讨论(0)
提交回复
热议问题