fputcsv and newline codes

前端 未结 8 2224
别那么骄傲
别那么骄傲 2020-11-28 10:12

I\'m using fputcsv in PHP to output a comma-delimited file of a database query. When opening the file in gedit in Ubuntu, it looks correct - each record has a line break (no

相关标签:
8条回答
  • 2020-11-28 10:51

    Using the php function fputcsv writes only \n and cannot be customized. This makes the function worthless for microsoft environment although some packages will detect the linux newline also.

    Still the benefits of fputcsv kept me digging into a solution to replace the newline character just before sending to the file. This can be done by streaming the fputcsv to the build in php temp stream first. Then adapt the newline character(s) to whatever you want and then save to file. Like this:

    function getcsvline($list,  $seperator, $enclosure, $newline = "" ){
        $fp = fopen('php://temp', 'r+'); 
    
        fputcsv($fp, $list, $seperator, $enclosure );
        rewind($fp);
    
        $line = fgets($fp);
        if( $newline and $newline != "\n" ) {
          if( $line[strlen($line)-2] != "\r" and $line[strlen($line)-1] == "\n") {
            $line = substr_replace($line,"",-1) . $newline;
          } else {
            // return the line as is (literal string)
            //die( 'original csv line is already \r\n style' );
          }
        }
    
            return $line;
    }
    
    /* to call the function with the array $row and save to file with filehandle $fp */
    $line = getcsvline( $row, ",", "\"", "\r\n" );
    fwrite( $fp, $line);
    
    0 讨论(0)
  • 2020-11-28 10:52

    alternatively, you can output in native unix format (\n only) then run unix2dos on the resulting file to convert to \r\n in the appropriate places. Just be careful that your data contains no \n's . Also, I see you are using a default separator of ~ . try a default separator of \t .

    0 讨论(0)
  • 2020-11-28 10:56
    // Writes an array to an open CSV file with a custom end of line.
    //
    // $fp: a seekable file pointer. Most file pointers are seekable, 
    //   but some are not. example: fopen('php://output', 'w') is not seekable.
    // $eol: probably one of "\r\n", "\n", or for super old macs: "\r"
    function fputcsv_eol($fp, $array, $eol) {
      fputcsv($fp, $array);
      if("\n" != $eol && 0 === fseek($fp, -1, SEEK_CUR)) {
        fwrite($fp, $eol);
      }
    }
    
    0 讨论(0)
  • 2020-11-28 11:11

    I've been dealing with a similiar situation. Here's a solution I've found that outputs CSV files with windows friendly line-endings.

    http://www.php.net/manual/en/function.fputcsv.php#90883

    I wasn't able to use the since I'm trying to stream a file to the client and can't use the fseeks.

    0 讨论(0)
  • 2020-11-28 11:12

    As webbiedave pointed out (thx!) probably the cleanest way is to use a stream filter.

    It is a bit more complex than other solutions, but even works on streams that are not editable after writing to them (like a download using $handle = fopen('php://output', 'w'); )

    Here is my approach:

    class StreamFilterNewlines extends php_user_filter {
        function filter($in, $out, &$consumed, $closing) {
    
            while ( $bucket = stream_bucket_make_writeable($in) ) {
                $bucket->data = preg_replace('/([^\r])\n/', "$1\r\n", $bucket->data);
                $consumed += $bucket->datalen;
                stream_bucket_append($out, $bucket);
            }
            return PSFS_PASS_ON;
        }
    }
    
    stream_filter_register("newlines", "StreamFilterNewlines");
    stream_filter_append($handle, "newlines");
    
    fputcsv($handle, $list, $seperator, $enclosure);
    ...
    
    0 讨论(0)
  • 2020-11-28 11:13

    windows needs \r\n as the linebreak/carriage return combo in order to show separate lines.

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