【问题标题】:Write a CSV file from a PHP Array从 PHP 数组写入 CSV 文件
【发布时间】:2016-02-12 14:04:12
【问题描述】:

我很感激已经有很多关于这个主题的问题。但是,由于我不是 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);
?>

感谢大家的帮助。很棒的社区!

【问题讨论】:

    标签: php csv fopen


    【解决方案1】:

    要将 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);
    

    【讨论】:

    • 这个更像!我快到了。我只是在努力获取对象键的初始数组。
    • 我用一种完全动态的方式更新了我的最后一个示例,将您的标题也存储在 CSV 中。如果您要更改对象的属性,CSV 将跟随正确的标题。请注意,它只使用数组中第一个对象的属性来构建 CSV 标头。
    • 谢谢老兄。这是我需要的帮助。我不得不稍微调整一下,并用最终的 PHP 更新我的问题。
    • 太棒了!很高兴能帮上忙。
    • 请注意:如果您以 JSON 字符串开头并且想要一个数组,请使用 json_decode($string, TRUE)。它会给你一个数组。
    【解决方案2】:

    尝试下面的 csv 解决方案标题将是(项目、成本、批准人) - 将 $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

    【讨论】:

    • 我认为我的问题是我有一个对象数组。我想我需要在它到达 PHP 之前把它弄平,这样我才能使用这个脚本。
    • 在 foreach 循环中再添加一行:$fields = (array) $fields
    • @ChetanAmeta 我认为值得注意的是,使用此解决方案时,值的顺序确实很重要。如果您最终以与前一个不同的顺序写入值,即使您使用了相同的键,它仍然会出现在 CSV 中的错误标题下。只是想强调这一点。您甚至可以为每个字段行编写一个完全不同的键。这使得它在我看来完全没用。那么为什么不先添加标题呢?
    • @Rein 是的,可以做到,但根据问题,他想使用键作为标题,还假设他的数组中的键是相同的
    【解决方案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"));
    

    如果这不是您想要的,请告诉我,我会编辑答案。

    【讨论】:

    • 我的问题是我有一个对象数组。因此,我需要将它们解包到一个数组中才能正常工作。我想。
    • @LeeProbert 你能至少提供数据的来源吗?
    • 数据结构是从json解码出来的。我已经用我的 PHP 更新了。
    • @LeeProbert 如果你分享了 json 数据,你现在应该有解决方案了
    • 我知道你有一个 JSON 字符串开头,我们不会将对象数组转换为数组。我们只会告诉你将json_decode 的第二个参数设置为TRUE,它会返回一个数组。
    猜你喜欢
    • 1970-01-01
    • 2016-01-06
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    • 1970-01-01
    • 2014-05-01
    • 2017-09-27
    • 1970-01-01
    相关资源
    最近更新 更多