skip to Main Content

I have a large (size ~ 12k) 2D array of data like below and I want to insert these data into a csv file.

$data = array
(
    'a' => array
    (
        0 => 111,
        1 => 222,
        2 => 333,
        3 => 444,
    ),
    'b' => array
    (
        0 => 555,
        1 => 666,
        2 => 777,
        3 => 888,
    ),
    'c' => array
    (
        0 => 999,
        1 => 000,
        2 => 111,
        3 => 222,
    ),
);

Here ‘a’, ‘b’, and ‘c’ would be the CSV header row, and corresponding array values should be inserted like below:-

a b c
111 555 999
222 666 000
333 777 111
444 888 222

I know fputcsv can be used to insert the data but it insert the array values as a row in the csv but in my case I want to insert the array values to a csv column.

Is there any simpler way to insert all the array values to the csv columns like above table?

3

Answers


  1. Assuming that each sub-array contains the same count of values, you can achieve your goal with just a few lines of code:

    • use array_keys to get all the column names from your array
    • iterate each sub-array to compose the single row, assuming that each value of that row is in the same array index position
    $data = array
    (
        'a' => array
        (
            0 => 111,
            1 => 222,
            2 => 333,
            3 => 444,
        ),
        'b' => array
        (
            0 => 555,
            1 => 666,
            2 => 777,
            3 => 888,
        ),
        'c' => array
        (
            0 => 999,
            1 => 000,
            2 => 111,
            3 => 222,
        ),
    );
        
    $fp = fopen('file.csv', 'w');
    
    // headers
    fputcsv($fp, array_keys($data));
    
    // rows contents
    for($i = 0; $i<count(current($data)); $i++) {
        $row = [];
        foreach($data as $k => $v) {
            $row[] = $v[$i];
        }
        fputcsv($fp, $row);
    }
        
    fclose($fp);
    

    Try it online on https://onlinephp.io/c/735bc, with this results:

    a,b,c
    111,555,999
    222,666,0
    333,777,111
    444,888,222
    

    In the official documentation you can find many other useful array functions.

    Login or Signup to reply.
  2. Since CSV files are fundamentally written row by row, you’ll need to:

    • Determine how many rows you want to generate
    • Loop that many times, picking one item for each column

    Assuming all your sub-arrays have the same number of keys, you could set up this way:

    $lastRowNumber = array_key_last($data['a']);
    $columns = array_keys($data);
    

    And then your loop would look like this:

    for ( $rowNumber = 0; $rowNumber <= $lastRowNumber; $rowNumber++ ) {
        $csvRow = [];
        foreach ( $columns as $columnKey ) {
            $csvRow[] = $data[$columnKey][$rowNumber];
        }
        fputcsv($outputFileHandle, $csvRow);
    }
    

    Demo echoing the data rather than writing with fputcsv: https://3v4l.org/P5rtU

    Alternatively, you could loop using a list of row keys, rather than assuming they’re sequentially numbered. For instance, taking the keys from the first sub-array:

    $columnKeys = array_keys($data);
    $rowKeys = array_keys($data[$columnKeys[0]]);
    

    Then use foreach instead of for:

    foreach ( $rowKeys as $rowKey ) {
        $csvRow = [];
        foreach ( $columnKeys as $columnKey ) {
            $csvRow[] = $data[$columnKey][$rowKey];
        }
        echo implode(',', $csvRow), PHP_EOL;
    }
    
    Login or Signup to reply.
  3. There exists an array_column function that might be of help:

    $out = fopen('php://stdout', 'w');
    
    # output the CSV header
    fputcsv($out, array_keys($data));
    
    # output the CSV records
    foreach ( array_keys( $data[ array_key_first($data) ] ) as $column_key) {
         fputcsv($out, array_column($data, $column_key));
    }
    

    output:

    a,b,c
    111,555,999
    222,666,0
    333,777,111
    444,888,222
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search