PHP – 使用POST $data创建CSV文件 = curl_exec($ch);,其中只包含一个大字符串

huangapple go评论82阅读模式
英文:

PHP - create CSV file from POST $data = curl_exec($ch); that Contains only 1 big String

问题

我使用POST方法执行了$data = curl_exec($ch);。当我执行echo ''<pre>',var_dump($data),'</pre>';时,输出如下:

string(15124) ""A","B","C","D","E","F","G","H"
,"2",,"4","5",,,"8"
"ONE",,,"QW AH",,"US",,"EU""

我尝试将其拆分并转换为数组,使用$lines = str_getcsv($data, PHP_EOL);,但我只得到一个包含所有内容的数组。输出如下:

array(1) {
  [0]=>
  string(15121) ""A","B","C","D","E","F","G","H"
,"2",,"4","5",,,"8"
"ONE",,,"QW AH",,"US",,"EU""
}

我想从中创建一个CSV文件,所以我执行了以下操作:

$fp = fopen('../myfile.csv','w');
fputcsv($fp, $data);
fclose($fp);

我成功获得了文件,但在Excel中打开时,列并不正确。如何实际按行拆分它们?谢谢。

英文:

I did $data = curl_exec($ch); with POST method.
When I did echo '<pre>',var_dump($data),'</pre>';

string(15124) ""A","B","C","D","E","F","G","H"
,"2",,"4","5",,,"8"
"ONE",,,"QW AH",,"US",,"EU""

I tried to split them and make into array $lines = str_getcsv($data, PHP_EOL);
But I got only 1 array with everything in it
echo '<pre>',var_dump($lines),'</pre>';

array(1) {
  [0]=>
  string(15121) ""A","B","C","D","E","F","G","H"
,"2",,"4","5",,,"8"
"ONE",,,"QW AH",,"US",,"EU""

I want to create a csv file from that. So I did

$fp = fopen('../myfile.csv','w');
    fputcsv($fp, $data);
fclose($fp);

I got the file, but when opened in excel the columns are not right.
How to actually split them row by row?
Thanks.

答案1

得分: 3

请注意,您的数据已经是一个CSV格式的。简而言之,您无需做任何操作,只需要使用file_put_contents函数将其保存到文件中。

关于您的方法:
您只获取了数组中的一个项目,因为:

  • str_getcsv函数设计用于读取CSV的一行,而不是包含多行的整个CSV字符串。
  • str_getcsv的第二个参数不是行分隔符(请查看手册),而是项目分隔符,它不是换行符。

但如果您想更改CSV的外观(分隔符、保护或转义字符、换行序列),您必须逐行读取并写入它。一个简单的方法是使用fopen()函数与data://包装器一起使用,例如,从简单的字符串获取资源。这样,您就不必手动按行拆分数据,因为fgetcsv会为您完成:

$data = '"A","B","C","D","E","F","G","H"
    ,"2",,"4","5",,,"8"
    "ONE",,,"QW AH",,"US",,"EU"';
        
$fhi = fopen('data://text/plain;base64,' . base64_encode($data), 'r');
    
if (false !== $fho = fopen('output.csv', 'w')) {
    while (false !== $row = fgetcsv($fhi)) {
        fputcsv($fho, $row, ';', '"', '\\', "\n"); // 选择参数
    }
    
    fclose($fho);
}

fclose($fhi);
英文:

Note that your data are already a csv. In short you have nothing to do except to save it to a file with file_put_contents.

About your approach:
You obtain only one item in your array because:

  • str_getcsv is designed to read only one line of csv, not a whole csv string with multiple lines.
  • the second parameter of str_getcsv is not the line separator (see the manual) but the item separator that isn't a newline.

But if you want to change how the csv looks like (the delimiter, the protection or escape character, the newline sequence), you have to read it and to write it line by line. A simple way to do that is to use fopen() with the data:// wrapper, for example, to obtain a resource from a simple string. This way you don't have to split your data by lines since fgetcsv does it for you:

$data = '"A","B","C","D","E","F","G","H"
,"2",,"4","5",,,"8"
"ONE",,,"QW AH",,"US",,"EU"';
    
$fhi = fopen('data://text/plain;base64,' . base64_encode($data), 'r');

if (false !== $fho = fopen('output.csv', 'w')) {
    while (false !== $row = fgetcsv($fhi)) {
        fputcsv($fho, $row, ';', '"', '\\', "\n"); // choose the parameters
    }
    
    close($fho);
}

close($fhi);

答案2

得分: 1

以下是翻译好的部分:

似乎某些Microsoft Excel版本倾向于使用分号 '';'' 而不是逗号 '','',如此链接所示 (https://answers.microsoft.com/en-us/msoffice/forum/all/excel-keeps-on-using-semicolon-instead-of-comma/543510d9-65a8-4a0d-8464-a08fc0ac1c4f)。这也可能取决于地区设置和用户偏好。

在这种情况下,根据用户请求可能需要将 '','' 更改为 '';''。

例如,对于以下数据...

// 获取的数据
$data = ''"A","B","C","D","E","F","G","H"
,"2",,"4","5",,,"8"
"ONE",,,"QW AH",,"US",,"EU"';

// 将其分成行
$lines = explode(PHP_EOL, $data);

// 格式化的行的容器
$csv_rows = [];

foreach ($lines as $line) {
	// 通过逗号拆分每行中的单元格,忽略值内可能的逗号
	$cells = preg_split(''/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/'', $line);

	// 使用分号连接单元格
	$csv_rows[] = implode(';'', $cells);
}

// 结果
$csv_text = implode(PHP_EOL, $csv_rows);

结果文本:

"A";"B";"C";"D";"E";"F";"G";"H"
;"2";;"4";"5";;;"8" "ONE";;;"QW
AH";;"US";;"EU"

在PHP Sandbox中测试
https://onlinephp.io/c/23cc3

欢迎提出改进意见。

英文:

It seems some Microsof Excel versions tend to use semicolon ';' instead of comma ',' as seen at (https://answers.microsoft.com/en-us/msoffice/forum/all/excel-keeps-on-using-semicolon-instead-of-comma/543510d9-65a8-4a0d-8464-a08fc0ac1c4f). It also may depend on locale and user settings.

In such case, changes from ',' to ';' may be needed according to user request.

E.g., for the data below...

// obtained data
$data = '"A","B","C","D","E","F","G","H"
,"2",,"4","5",,,"8"
"ONE",,,"QW AH",,"US",,"EU"';

// break it into lines
$lines = explode(PHP_EOL, $data);

// haven for the formatted rows
$csv_rows = [];

foreach ($lines as $line) {
	// Breaks each line into cells by the comma,
	// ignoring eventual commas inside values
	$cells = preg_split('/,(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)/', $line);

	// joins cells with semicolon
	$csv_rows[] = implode(';', $cells);
}

// result
$csv_text = implode(PHP_EOL, $csv_rows);

Result text:

"A";"B";"C";"D";"E";"F";"G";"H"
;"2";;"4";"5";;;"8" "ONE";;;"QW
AH";;"US";;"EU"

Tested within PHP Sandbox
https://onlinephp.io/c/23cc3

Improvements are welcome.

答案3

得分: -1

只是为了我的提醒或任何感兴趣的人。这是我最终获取所需文件的步骤。
删除

$fp = fopen('../myfile.csv','w');
    fputcsv($fp, $data);
fclose($fp);

并更改为 file_put_contents('../myfile.csv','w');
非常感谢大家解释给我看,甚至展示了更多额外的知识 PHP – 使用POST $data创建CSV文件 = curl_exec($ch);,其中只包含一个大字符串

英文:

Just for my own reminder or anyone interested. This is what I do to finally get the file that I wanted.
Remove

$fp = fopen('../myfile.csv','w');
    fputcsv($fp, $data);
fclose($fp);

and change to file_put_contents('../myfile.csv','w');

Thank you very much guys for explaining me that and showing even more bonus knowledge PHP – 使用POST $data创建CSV文件 = curl_exec($ch);,其中只包含一个大字符串

huangapple
  • 本文由 发表于 2023年7月13日 00:30:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/76672715.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定