在 PHP 中将 CSV 写入不带附件的文件

Posted

技术标签:

【中文标题】在 PHP 中将 CSV 写入不带附件的文件【英文标题】:Write CSV To File Without Enclosures In PHP 【发布时间】:2010-12-20 12:24:10 【问题描述】:

是否有本机函数或实体类/库用于将数组写为 CSV 文件中的一行而不带附件?如果没有为附件参数传递任何内容,fputcsv 将默认为 "。 Google 让我失望了(返回一大堆关于 fputcsv 的页面的结果),而 PEAR 的库或多或少与 fputcsv 做同样的事情。

fputcsv 完全一样的东西,但允许字段不被引用。

目前:"field 1","field 2",field3hasNoSpaces

所需:field 1,field 2,field3hasNoSpaces

【问题讨论】:

我认为您需要引号.. 如果那里有换行符或逗号并且它们没有引号分隔怎么办? 报价是为了您的利益。使用它们是一个好习惯;这就是为什么它们是默认的。 我不同意;如果您可以控制输入数据,则可能希望省略附件,特别是如果您可能将所有数字/过滤字符串数据导出到古老的阅读器。另一件事是制表符分隔的文件:不需要附件。 如果您生成的 CSV 用于将数据上传到构建不佳的应用程序,则引号可能会干扰 sql.. 就像我的情况一样 fputcsv 似乎有一个导致此类事情的错误:3StartssWithNum,"StartsWithAlpha", "notherStartsWAlpha" 等。附件字符不是问题。不一致的是。 [php 5.6 版] 【参考方案1】:

关于上述附件的警告是有效的,但您已经说过它们不适用于您的用例。

我想知道为什么你不能只使用这样的东西?

<?php
$fields = array(
    "field 1","field 2","field3hasNoSpaces"
);
fputs(STDOUT, implode(',', $fields)."\n");

【讨论】:

不知道为什么我没有先去这个。谢谢! 因为 CSV 库可以处理您的简单内爆解决方案无法处理的情况,例如转义分隔符(在您的情况下为 ,)。 这是替换不带附件的 fputcsv 的最佳方法。我会提出一个小建议来改进这个答案 - 使用记录在案的参数顺序 implode : implode(string $glue, array $pieces) 以避免与 PHP 新手和不知道反向参数的这个 PHP“功能”的人混淆。 fputs(...) 是别名函数,请考虑改用fwrite(...)【参考方案2】:

使用 chr() 函数:

fputcsv($f,$array,',',chr(0));

【讨论】:

chr(0) 创建以 utf8 显示的空字符,如 ^@ 我怀疑这是个好主意。你实际上是在写"\0"。在它回来咬你之前几乎是看不见的。 Windows 上的记事本会打开一个包含“\0”字符且编码错误的文件,导致屏幕上显示乱码。 你删除这个已经存在 9 年的非常错误的答案怎么样?【参考方案3】:

fputcsv($file, $data, ';', chr(127));

【讨论】:

那是我要找的那个。谢谢m8! 是的,这是正确的答案。工作完美。谢谢 实际上,chr(127) 在文件中仍然显示为一个字符,因此并不理想。该死的【参考方案4】:

car(0) 没有成功,因为 NULL 值很可能会阻塞大多数 csv 解析器。

我最终使用fputcsv() 构建初始文件,然后检查并删除了所有引号。优雅的?也许不是,但它完成了工作:)。

【讨论】:

【参考方案5】:

这不行吗?

fputcsv($fp, split(',', $line),',',' ');

【讨论】:

Split 将是一个弃用的功能,这不一定能解决我的附件问题。不幸的是,至少就此功能而言,空格不被视为合法字符。不过谢谢! 假设额外的空间不是问题,看来他正在寻找 no 外壳;但是,尝试使用空格似乎是合乎逻辑的事情。【参考方案6】:

我使用棘手的方法来删除双引号,但仅限于 Linux

....
fputcsv($fp, $product_data,"\t");
....
shell_exec('sed -i \'s/"//g\' /path/to/your-file.txt ');

【讨论】:

【参考方案7】:
<?php       
    
$filename = "sample.csv";
$handle = fopen($filename, 'w+');
fputcsv($handle, ['column 1','column 2']);
$data = ['sample','data'];

fputs($handle, implode(',', $data)."\n");

// or

fwrite($handle, implode(',', $data)."\n");

fclose($handle);
$headers = array(
    'Content-Type' => 'text/csv',
);

【讨论】:

【参考方案8】:

这是我用来将标准 CSV 放入数组的方法...

function csv_explode($delim=',', $str, $enclose='"', $preserve=false)
        $resArr = array();
        $n = 0;
        $expEncArr = explode($enclose, $str);
        foreach($expEncArr as $EncItem)
                if($n++%2)
                        array_push($resArr, array_pop($resArr) . ($preserve?$enclose:'') . $EncItem.($preserve?$enclose:''));
                else
                        $expDelArr = explode($delim, $EncItem);
                        array_push($resArr, array_pop($resArr) . array_shift($expDelArr));
                        $resArr = array_merge($resArr, $expDelArr);
                
        
        return $resArr;
 

然后您可以在 foreach 循环中输出任何您想要的内容。

【讨论】:

【参考方案9】:

没有附件的 CSV 文件的缺点是用户输入中的错误逗号会影响该行。因此,您需要在写入 CSV 行之前删除逗号。

处理 CSV 的棘手部分是解析附件,这使得 PHP 和 PEAR CSV 函数很有价值。本质上,您正在寻找一个以逗号分隔的列和以换行符分隔的行的文件。这是一个简单的起点:

<?php
$col_separator= ',';
$row_separator= "\n";

$a= array(
 array('my', 'values', 'are', 'awes,breakit,ome'),
 array('these', 'values', 'also', "rock\nAND\nROLL")
);

function encodeRow(array $a) 
 global $col_separator;
 global $row_separator;
 // Can't have the separators in the column data!
 $a2= array();
 foreach ($a as $v) 
  $a2[]= str_replace(array($col_separator, $row_separator), '', $v);
 
 return implode($col_separator, $a2);


$output= array();
foreach ($a as $row) 
 $output[]= encodeRow($row);


echo(implode($row_separator, $output));

?>

【讨论】:

【参考方案10】:

旧的 fwrite() 有什么问题?

function encloseString($field)
    return ($field) ? '"' . $field . '"' : null;


$delimiter = ';';
$data = ["data_field_1", "data_field_2", "data_field_3"];

$fp = fopen("some-file.csv", 'w');

for($i = 0;$i<100000;$i++) 
    fwrite($fp, implode($delimiter, array_map('encloseString', $data) . "\n");


fclose($fp);

(显然你需要确保 $data 中的数据首先被转义)

【讨论】:

【参考方案11】:

根据您的应用选择解决方案。在某些情况下,需要自己的 csv 代码。在案例 1(见结果 chr0)、案例 2(chr127)和案例 3(chr127)中,数据将被修改(坏事)。而是使用这样的东西,谢谢@oops:

<?php
$fields = array(
    "field 1","field 2","field3hasNoSpaces"
);
fputs(STDOUT, implode(',', $fields)."\n");


case 1. `fputcsv($f, $array, $delimiter, car(0))`
See result [chr0][1]
case 2. `fputcsv($f, $array, $delimiter, car(127))`
[chr127][2]
case 3. `fputcsv($f, $array, $delimiter, ' ')`
[onespace][3]
case 4. Own code:
[oops](https://***.com/a/1904945)
 or [Ansyori](https://***.com/a/51981613)
 or [zeros-and-ones](https://***.com/a/38778459)
produces better results.

【讨论】:

你打算chr(0)chr(197) 吗?我用第一个解决了这个问题。【参考方案12】:

chr(0) 也为我工作:

 fputcsv($fp, $aLine, $sDelimiter, chr(0));

【讨论】:

我认为它有效是因为您的编辑器没有向您显示空字符,但它仍然存在【参考方案13】:

想通了。通过将 Null 的 ascii 代码传递给 car() 函数,它似乎工作得很好。

fputcsv($f, $array, $delimiter, car(0))

谢谢大家的回答!!!

【讨论】:

嗯...你确定它不会在 csv 文件中放入一堆隐形空值吗? :s 另外,我认为是 'chr(0)' --! 为我设置 NULL。不是理想的解决方案。 car(0) 真的吗??

以上是关于在 PHP 中将 CSV 写入不带附件的文件的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中将数据写入 CSV 文件

在 PySpark 中将数据帧写入 CSV 后重命名文件 [重复]

如何在 for 循环中将结果写入多个 CSV 文件

尝试在Python中将集合的结果写入csv文件,但只打印一行

如何通过在 Python 中将两个列表合并为一个,使用 CSV 模块或 Pandas 写入 csv 或 Excel 文件?

在pyspark(2.2.0)中将CSV文件写入AWS时如何分配访问控制列表(ACL)?