提问人:Lee Probert 提问时间:2/12/2016 最后编辑:Lee Probert 更新时间:11/10/2022 访问量:20967
从 PHP 数组编写 CSV 文件
Write a CSV file from a PHP Array
问:
我很欣赏围绕这个主题已经有很多问题。但是,由于我不是PHP开发人员,我正在努力使任何东西都适用于我的特定对象结构。我有一个非常扁平的JSON结构,可以很好地读入PHP中。我需要做的就是遍历对象数组,从第一个对象中的键创建 CSV 标题(它们都相同),然后使用所有对象属性编写 CSV 的每一行。下面是我的PHP数据:
Array
(
[0] => stdClass Object
(
[record id] => -KA9S-beTbe9LIPBm_xK
[timestamp] => Wed Feb 10 2016 10:12:20 GMT+0100
[user id] => 33037t23nxyx1x5k
[user age] => 18-24
[user gender] => M
[user q1] => Yes
[user q2] => Yes
[user q3] => more
[answer q1 value] => 1
[answer q1 confidence] => 3
[answer q1 duration] => 262412
[answer q2 value] => 1
[answer q2 confidence] => 3
[answer q2 duration] => 1959
[answer q3 value] => 0
[answer q3 confidence] => 3
[answer q3 duration] => 2939
[answer q4 value] => 1
[answer q4 confidence] => 2
[answer q4 duration] => 1868
[answer q5 value] => 1
[answer q5 confidence] => 2
[answer q5 duration] => 2196
)
所以,你可以看到它应该非常简单。键将是 CSV 单元格标题,然后是每条记录的一行。
我希望有人能帮助我。我根本不懂PHP。
更新:这是我最新的PHP文件。这行得通。我必须将对象转换为数组才能获得键:
<?php
$data = $_POST['data'];
$response = json_decode($data);
$records_arr = $response->records;
$fp = fopen('records.csv', 'w');
$i = 0;
foreach ($records_arr as $record) {
// $record is an object so create an array
$record_arr = array();
foreach ($record as $value) {
$record_arr[] = $value;
}
if($i == 0){
fputcsv($fp, array_keys((array)$record));
}
fputcsv($fp, array_values($record_arr));
$i++;
}
fclose($fp);
echo print_r($records_arr);
?>
谢谢大家的帮助。了不起的社区!
答:
1赞
Chetan Ameta
2/12/2016
#1
尝试以下 csv 的解决方案标头将是 (item, cost, approved by) - 替换为您的数组变量:$data
$data = array(
array( 'item' => 'Server', 'cost' => 10000, 'approved by' => 'Joe'),
array( 'item' => 'Mt Dew', 'cost' => 1.25, 'approved by' => 'John'),
array( 'item' => 'IntelliJ IDEA', 'cost' => 500, 'approved by' => 'James')
);
$fp = fopen('file.csv', 'w');
$i = 0;
foreach ($data as $fields) {
if($i == 0){
fputcsv($fp, array_keys($fields));
}
fputcsv($fp, array_values($fields));
$i++;
}
fclose($fp);
有关更多详细信息,请查看: PHP: fputcsv - Manual
评论
0赞
Lee Probert
2/12/2016
我认为我的问题是我有一个对象数组。我想我需要在它到达 PHP 之前将其扁平化,以便我可以使用此脚本。
0赞
Rein
2/12/2016
stackoverflow.com/questions/19495068/......
1赞
Chetan Ameta
2/12/2016
在 foreach 循环中,再添加一行新行:$fields = (array) $fields
1赞
Rein
2/12/2016
@ChetanAmeta 我认为值得注意的是,使用此解决方案,值的顺序确实很重要。如果您最终以与前一个值不同的顺序写入一个值,即使您使用了相同的键,它仍然会在 CSV 中位于错误的标头下。只是想强调这一点。您甚至可以为每个字段行编写一个完全不同的键。在我看来,这使得它完全没用。为什么不先添加标题呢?
0赞
Chetan Ameta
2/12/2016
@Rein是的,这是可以做到的,但根据问题,他想使用键作为标头,也假设他的数组中的键是相同的
10赞
Rein
2/12/2016
#2
要将PHP数组写入CSV文件,您应该使用内置的PHP函数:fputcsv
<?php
$list = array (
array('header 1', 'header 2', 'header 3', 'header 4'),
array('5656', '454545', '5455', '5454'),
array('541212', '454545', '5455', '5454'),
array('541212', '454545', '5455', '5454'),
);
$fp = fopen('file.csv', 'wb');
foreach ($list as $fields) {
fputcsv($fp, $fields);
}
fclose($fp);
编辑:
基于您的数据输入的更具体示例:
<?php
// I had to recreate your data, this is just an example
$array_of_objects = array();
for( $i = 0; $i < 5; $i++ )
{
$obj = new \stdClass();
$obj->username = "Rein";
$obj->answer = "Correct";
$obj->awesomeness = 1000;
$array_of_objects[] = $obj;
}
// Open a file to write to
$fp = fopen('file.csv', 'wb');
$i = 0;
// Loop the array of objects
foreach( $array_of_objects as $obj )
{
// Transform the current object to an array
$fields = array();
foreach ($obj as $k => $v)
{
$fields[ $k ] = $v;
}
if( $i === 0 )
{
fputcsv($fp, array_keys($fields) ); // First write the headers
}
fputcsv($fp, $fields); // Then write the fields
$i++;
}
fclose($fp);
编辑2:
根据新信息(你有一个 JSON 字符串开始),我添加了这个示例,作为将数据写入 CSV 文件的更好方法:
<?php
$data = json_decode($_POST['data'], TRUE);
$records = $data['records'];
$fp = fopen('records.csv', 'wb');
$i = 0;
foreach ($records as $record) {
if($i === 0) {
fputcsv($fp, array_keys($record));
}
fputcsv($fp, array_values($record));
$i++;
}
fclose($fp);
评论
0赞
Lee Probert
2/12/2016
这更像是它!我快到了。我只是在努力获取对象键的初始数组。
0赞
Rein
2/12/2016
我用一种完全动态的方式更新了我的最后一个示例,以将您的标头存储在 CSV 中。如果要更改对象的属性,CSV 将遵循正确的标题。请注意,它仅从数组中的第一个对象中获取属性,以便从中构建 CSV 标头。
0赞
Lee Probert
2/12/2016
谢谢伙计。这是我需要的帮助。我不得不稍微调整一下,并用最终有效的PHP更新我的问题。
0赞
Rein
2/12/2016
伟大!很高兴能帮上忙。
0赞
Rein
2/12/2016
请注意:如果您以 JSON 字符串开头并且想要一个数组,只需使用 .它会给你一个数组。json_decode($string, TRUE)
1赞
André Ferraz
2/12/2016
#3
我之前为此创建了一个函数。请记住,下面的代码不假定有任何 csv 标头。
function doCSV($file, $content = array())
{
$handle = fopen($file, "w");
foreach($content as $value) {
fputcsv($handle, array(key($content), $value));
}
fclose($handle);
}
doCSV("test.csv", array("Test 1" => "Value 1", "Test 2" => "Value 2"));
如果这不是您要求的,请告诉我,我会编辑答案。
评论
0赞
Lee Probert
2/12/2016
我的问题是我有一个对象数组。因此,我需要将它们解包到一个数组中才能正常工作。我认为。
0赞
André Ferraz
2/12/2016
@LeeProbert至少能提供数据的来源?
0赞
Lee Probert
2/12/2016
数据结构是从json解码的。我已经更新了我的 PHP。
0赞
André Ferraz
2/12/2016
@LeeProbert,如果您共享了 JSON 数据,您现在应该已经有了解决方案
0赞
Rein
2/12/2016
我早就知道你有一个JSON字符串,我们不会将对象数组转换为数组。我们只是告诉您设置第二个参数,该参数返回数组。json_decode
TRUE
0赞
rsmdh
11/9/2022
#4
您可以尝试以下代码将数据写入 csv
ob_start();
$outputCsv = fopen('export-csv.csv'', 'wb');
fputcsv($outputCsv, ['column header 1', 'column header 2', 'column header 3', 'column header 4'], ",");
$arOutput = [
['1', '2', '3', '4'],
['4', '6', '2', '0'],
['4', '6', '3', '2'],
['4', '7', '3', '3'],
['4', '3', '2', '4'],
['4', '4', '8', '1'],
]
foreach ($arOutput as $r)
{
fputcsv($outputCsv, $r, ",");
}
fclose($outputCsv);
评论