1

I am trying to create multiple csv from a given source (i.e array).

It works with sample data but it does not work with the actual data.

here is the code :-

<?php

$keycompare = array('98','83');
    $arraysource =
    array (
      0 => 
      array (
        0 => 
        array (
          1 => 'Coogee Tri Club Performance Cycle Jersey Women',
          2 => 'WCJ011DC-15924v',
          3 => '2',
          4 => 'Coogee Triathlon Club - Rd 2,Womens size chart',
          5 => '98',
        ),
        1 => 
        array (
          1 => 'Coogee Tri Club Cycle Bib and Brace Men',
          2 => 'MCB009DC-15925v',
          3 => '6',
          4 => 'Coogee Triathlon Club - Rd 2,Mens size chart',
          5 => '98',
        ),
        2 => 
        array (
          1 => 'Coogee Tri Club Performance Cycle Jersey Men',
          2 => 'MCJ007DC-15924v',
          3 => '12',
          4 => 'Coogee Triathlon Club - Rd 2,Mens size chart',
          5 => '98',
        ),
        3 => 
        array (
          1 => 'Coogee Tri Club Performance Triathlon Suit Men/Unisex',
          2 => 'MTU018DC-14792v',
          3 => '5',
          4 => 'Coogee Triathlon Club - Rd 2,Mens size chart',
          5 => '98',
        ),
        4 => 
        array (
          1 => 'Coogee Tri Club Triathlon Shorts Men',
          2 => 'UTK006DC-14790v',
          3 => '1',
          4 => 'Coogee Triathlon Club - Rd 2,Mens size chart',
          5 => '98',
        ),
        5 => 
        array (
          1 => 'Coogee Tri Club Run Singlet Men',
          2 => 'MRS004DC-17445v',
          3 => '12',
          4 => 'Coogee Triathlon Club - Rd 2,Mens size chart',
          5 => '98',
        ),
        6 => 
        array (
          1 => 'Coogee Tri Club Run Singlet Women',
          2 => 'WRT004DC-17445v',
          3 => '5',
          4 => 'Coogee Triathlon Club - Rd 2,Womens size chart',
          5 => '98',
        ),
        7 => 
        array (
          1 => 'Cogee Tri Club Visor',
          2 => 'BHATDC-17444v',
          3 => '12',
          4 => 'Coogee Triathlon Club - Rd 2',
          5 => '98',
        ),
        8 => 
        array (
          1 => 'Coogee Tri Club Chrlorine Resistant Two Piece Swim Suit Women',
          2 => 'WSU007DC-13856v',
          3 => '3',
          4 => 'Coogee Triathlon Club - Rd 2,Womens size chart',
          5 => '98',
        ),
        9 => 
        array (
          1 => 'Coogee Tri Club Swim Suit Women',
          2 => 'WSU009DC-13851v',
          3 => '1',
          4 => 'Coogee Triathlon Club - Rd 2,Womens size chart',
          5 => '98',
        ),
        10 => 
        array (
          1 => 'Coogee Tri Club Elite Triathlon Suit Hydrophobic Women',
          2 => 'WTU022DC-14029v',
          3 => '2',
          4 => 'Coogee Triathlon Club - Rd 2,Womens size chart',
          5 => '98',
        ),
        11 => 
        array (
          1 => 'Coogee Tri Club Performance Sleeved Triathlon Suit Women',
          2 => 'WTU032DC-14789v',
          3 => '3',
          4 => 'Coogee Triathlon Club - Rd 2,Womens size chart',
          5 => '98',
        ),
        12 => 
        array (
          1 => 'Coogee Tri Club Performance Sleeved Triathlon Suit Men',
          2 => 'MTU021DC-14789v',
          3 => '3',
          4 => 'Coogee Triathlon Club - Rd 2,Mens size chart',
          5 => '98',
        ),
        13 => 
        array (
          1 => 'Coogee Tri Club Cycle Bib and Brace Women',
          2 => 'WCB010DC-15925v',
          3 => '3',
          4 => 'Coogee Triathlon Club - Rd 2,Womens size chart',
          5 => '98',
        ),
        14 => 
        array (
          1 => 'Coogee Tri Club Swim Briefs Men',
          2 => 'MSU001DC-14557v',
          3 => '4',
          4 => 'Coogee Triathlon Club - Rd 2,Mens size chart',
          5 => '98',
        ),
      ),
      1 => 
      array (
        15 => 
        array (
          1 => 'Redcliffe Triathlon Club Triathlon Jersey Womens',
          2 => 'WTJ002DC-16580v',
          3 => '4',
          4 => 'Private Shops,Redcliffe Triathlon Club,Womens size chart',
          5 => '83',
        ),
        16 => 
        array (
          1 => 'Redcliffe Triathlon Club Triathlon Knicks Mens',
          2 => 'UTK006DC-14316v',
          3 => '3',
          4 => 'Private Shops,Redcliffe Triathlon Club,Mens size chart',
          5 => '83',
        ),
        17 => 
        array (
          1 => 'Redcliffe Triathlon Club Triathlon Shorts Women',
          2 => 'WTK005DC-14316v',
          3 => '2',
          4 => 'Private Shops,Redcliffe Triathlon Club,Womens size chart',
          5 => '83',
        ),
      ),
    );
    
    // some data to be used in the csv files
    $headers = array('id', 'name', 'age', 'species');
    $records = array(
        array('1', 'gise', '4', 'cat'),
        array('2', 'hek2mgl', '36', 'human')
    );
    
    // create your zip file
    $zipname = 'file.zip';
    $zip = new ZipArchive;
    $zip->open($zipname, ZipArchive::CREATE);
    
    // loop to create 3 csv files
    for ($i = 0; $i < 3; $i++) {
    
        // create a temporary file
        $fd = fopen('php://temp/maxmemory:1048576', 'w');
        if (false === $fd) {
            die('Failed to create temporary file');
        }
        
        // write the data to csv
        fputcsv($fd, $headers);
        foreach($arraysource as $record) {
            fputcsv($fd, $record);
        }
    
        // return to the start of the stream
        rewind($fd);
         
        // add the in-memory file to the archive, giving a name
        $zip->addFromString('file-'.$i.'.csv', stream_get_contents($fd) );
        //close the file
        fclose($fd);
    }
    // close the archive
    $zip->close();

i am not sure where is the issue if its between array format or something.

Basically the expected output is 2 csv

csv one will have data from array having key value as 5 => '98'

csv two will have data from array having key value as 5 => '83'

Can you please give me some hint on this ?

Thankyou

  • Any hint would be appreciated. Thanks –  Dec 02 '20 at 08:46
  • this looks very similar to [https://stackoverflow.com/questions/65086389/seperate-array-data-and-generate-csv-php](https://stackoverflow.com/questions/65086389/seperate-array-data-and-generate-csv-php) – berend Dec 02 '20 at 08:56
  • @berend, it does(and I voted to close that question), but at least this also shows a lot more of an attempt to solve the problem. – Nigel Ren Dec 02 '20 at 09:00

1 Answers1

0

There are a few problems with the script, I've changed the way it loops over the data and now it loops over the $arraysource using a foreach loop. Then for each loop it outputs that set of data to the CSV file. I've also changed the file name to include the corresponding value from $keycompare so the file name is more relevant. You can change the values in $headers to be the actual names of the fields, these are just to show how to do it...

// Change this next line to be the column headings
$headers = array('Description', 'Code', 'Size', 'Something Else', 'value');
// create your zip file
$zipname = 'file.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);

// Loop over the data to output
foreach ( $arraysource as $index => $csvData )  {
    
    // create a temporary file
    $fd = fopen('php://temp/maxmemory:1048576', 'w');
    if (false === $fd) {
        die('Failed to create temporary file');
    }
    
    // write the data to csv
    fputcsv($fd, $headers);
    // Output the data for the current file
    foreach($csvData as $record) {
        fputcsv($fd, $record);
    }
    
    // return to the start of the stream
    rewind($fd);
    
    // add the in-memory file to the archive, giving a name (including the ID)
    $zip->addFromString('file-'.$keycompare[$index].'.csv', stream_get_contents($fd) );
    //close the file
    fclose($fd);
}
// close the archive
$zip->close();

this gives a zip file with two files, file-98.csv and file-83.csv.

Nigel Ren
  • 56,122
  • 11
  • 43
  • 55
  • Thankyou very much for the answer & the explanation. I have a question, i am going to fetch the csv & send it as attachment in email. I am thinking as per my understanding the code for email send would be in loop after "fputcsv($fd, $record)" this right ? –  Dec 02 '20 at 10:10
  • @newphpdev, depends on what you are sending. If you send the CSV file or the zip file. The zip file won't be completely created until after the `$zip->close()`. – Nigel Ren Dec 02 '20 at 10:48
  • Ohps, then i am not much sure how to fetch the file from zip & send it along with this loop. Any thoughts ? –  Dec 02 '20 at 11:01
  • At the end of the loop, there should be a file called `file.zip`, you should then be able to attach this (using something like https://stackoverflow.com/questions/12301358/send-attachments-with-php-mail to help.( – Nigel Ren Dec 02 '20 at 11:04
  • I've thought i would just make a function for send mail & pass it into this loop (i.e foreach ( $arraysource as $index => $csvData ) { ) & make it work. –  Dec 02 '20 at 11:06
  • That's sounds great, though i need to attach each csv as seperately. –  Dec 02 '20 at 11:07
  • For exg - if there are $keycompare = array(1,2.3) then 3 csv will be created, i need to send these 3 csv seperately in email. 1 email & 1 csv at a time. That's the thing. What do you say ? –  Dec 02 '20 at 11:08
  • OK, in that case, you can pass them after the `fclose($fd);`, just attach the file (https://stackoverflow.com/a/26616360/1213708 shows how to attach a string to an e-mail) with `stream_get_contents($fd)` as the file contents. – Nigel Ren Dec 02 '20 at 11:11
  • Thanks :) Yes i called mail function under fclose like fclose($fd); sendreport($open_shop_cat_name[$index].' '.'('.$open_shop_today_date.')', $open_shop_cat_name[$index].' '.$open_shop_cat_start_date[$index].' '.'to'.' '.$yesterday); But I am not sure how would i extract the zip file in server then find in it with the file name & attach it to email. Can you please share your thoughts on this ? updated code with mail function - https://3v4l.org/6DqCa –  Dec 02 '20 at 11:21
  • Do you mean like this answer - https://stackoverflow.com/questions/30510941/create-csv-in-memory-email-and-remove-from-memory ? –  Dec 02 '20 at 11:31
  • Thankyou for the answer, i've able to work it out :) I appreciate it –  Dec 03 '20 at 04:50
  • Hello @nigel , can you i want to remove the "shop" column from the csv, can you please help me identify which is the protential code that you've used to sepearte the data as per "keycompare" ASAP ? –  Dec 03 '20 at 12:18
  • Depending on what the `shop` column is, then just before `fputcsv($fd, $record);` you can use something like `unset($record[5]);` to remove the last value in each record. – Nigel Ren Dec 03 '20 at 12:32
  • That would not remove the functionality of seperate csv wise ? –  Dec 03 '20 at 12:47
  • I am very thankful for your quick response. –  Dec 03 '20 at 12:47