在 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 写入不带附件的文件的主要内容,如果未能解决你的问题,请参考以下文章
在 PySpark 中将数据帧写入 CSV 后重命名文件 [重复]
尝试在Python中将集合的结果写入csv文件,但只打印一行
如何通过在 Python 中将两个列表合并为一个,使用 CSV 模块或 Pandas 写入 csv 或 Excel 文件?