5

I appreciate there are already a lot of questions around this subject. But, as I'm not a PHP developer, I'm struggling to get anything to work for my specific object structure. I have a pretty flat JSON structure that is being read into PHP just fine. All I need to do is go through the array of objects, create the CSV headings from the keys in the first object (they are all the same), and then write each line of the CSV using all the object properties. Here's a look at my PHP data:

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
        )

So, you can see it should be pretty straightforward. The keys would be the CSV cell headings and then a row for each record.

I hope someone can help me. I don't know PHP at all.

UPDATE: Here's my latest PHP file. This works. I had to cast the Object to an Array to get the Keys:

<?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);
?>

Thank you everyone for the help. Amazing community!

4 Answers 4

10

For writing a PHP array to a CSV file you should use the built in PHP function 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);

Edit:

More specific example based on your data input:

<?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);

Edit 2:

Based on new information (you have a JSON string to start with), I'm added this example as a better way to write the data to a CSV file:

<?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);
Sign up to request clarification or add additional context in comments.

6 Comments

This is more like it! I'm nearly there. Am just struggling to get that initial array of the object keys.
I update my last example with a fully dynamic way to also store your headers in the CSV. If you're gonna change the properties of your objects, the CSV is gonna follow with the right headers. Please note that it only takes properties from the first object in the array to build the CSV headers from.
Thanks dude. This was the help I needed. I had to tweak it a bit and am updating my question with the final PHP that works.
Great! Glad to be of help.
Just a note: if you start with a JSON string and you want an array, just use json_decode($string, TRUE). It will give you an array.
|
1

Try below solution header of csv will be (item, cost, approved by) - replace $data with your array variable:

$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);

for more detail have alook at : PHP: fputcsv - Manual

8 Comments

I think my problem is that I have an array of Objects. I think I will need to flatten it out before it gets to the PHP so I can use this script.
in foreach loop add one more new line: $fields = (array) $fields
@ChetanAmeta I think it's worth noting that using this solution, the order of the values does matter. If you end up with writing a value in a different order then the previous one, even though you used the same key, it will still come under the wrong header in the CSV. Just wanted to highlight this. You could even be writing a completely different key for each fields row. Which makes it completely useless in my opinion. Why not just add the headers first then?
@Rein yes that can be done but according to question he want to use keys as header, also assuming that keys in his array is same
|
1

I've created a function for that before. Bare in mind the code bellow does not assume there is any csv headers.

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"));

If this is not what you're asking for let me know, I'll edit the answer.

6 Comments

My problem is that I have an array of Objects. So, I would need to unwrap them into an Array for this to work. I think.
@LeeProbert can you at least provide the source where the data comes from?
The data structure is decoded from json. I've updated with my PHP.
@LeeProbert if you shared the json data, you would have had a solution by now
I we had known you had a JSON string to begin with, we wouldn't transform the array of objects to an array. We would just have told you to set the second argument of json_decode to TRUE which returns an array.
|
0

You can try below code to write data to 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);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.