Search code examples
phpcsvfputcsv

How to add double quotes in each field and print new row on next line - PHP CSV


I have a file data whom I creating CSV file manually.

Then I parse that file and picked necessary data and create new CSV file from it.

Till that step things are good and working but the problem is when I open that new file in text file, it misses double quotes around each fields and there is no new line at the ending of each row.

Here is the data of CSV file:

TransactionNumber   CustomerName    ReferenceNumber PurchaseOrderNumber ShipCarrier ShipService ShipBilling ShipAccount EarliestShipDate    CancelDate  Notes   ShipToName  ShipToCompany   ShipToAddress1  ShipToAddress2  ShipToCity  ShipToState ShipToZip   ShipToCountry   ShipToPhone ShipToFax   ShipToEmail ShipToCustomerName  ShipToDeptNumber    ShipToVendorID  TotalCartons    TotalPallets    TotalWeight TotalVolume BOLNum  TrackingNum TrailerNum  SealNum ShipDate    ItemNumber  ItemQuantityOrdered ItemQuantityShipped ItemLength  ItemWidth   ItemHeight  ItemWeight  FreightPP   WarehouseID LotNumber   SerialNumber    ExpirationDate  Supplier    Cost    FulfillInvShippingAndHandling   FulfillInvTax   FulfillInvDiscountCode  FulfillInvDiscountAmount    FulfillInvGiftMessage   SoldToName  SoldToCompany   SoldToAddress1  SoldToAddress2  SoldToCity  SoldToState SoldToZip   SoldToCountry   SoldToPhone SoldToFax   SoldToEmail SoldToCustomerID    SoldToDeptNumber    FulfillInvSalePrice FulfillInvDiscountPct   FulfillInvDiscountAmt
242328  PARADIGM TRENDS 123810  40-402849   CUSTOMER PICK UP    LTL FreightCollect                  HG BUYING- JEFFERSON DC 884 HG BUYING- JEFFERSON DC 884 125 LOGISTICS CENTER PKWY       JEFFERSON   AL  30549   US                          30  0   30  0.0174      22              DOV3S   64  64  4   1   1   4   22  1                       0   0       0                                                           0   0   0
222223      123812  40-402850                                                                                       12      3                           DOV3M   64  64  4   1   1   4   442                                                                                                 0   0   0
242423      1238120 40-402851                                                                                       33      67          3               BY3S    176 176 11  1   1   11  2                                                                                                   0   0   0
7868        1233810 40-402852                                                                                       44      55          33              BY3M    176 176 11  1   1   11  45                                                                                                  0   0   0
989879      1234810 40-402853                                                                                       53      442         7                                           6                                                                                                           
        1253810 40-402854                                                                                       66                  88                                                                                                                                                      
898     1263810 40-402855                                                                                       88      66                                                      6                                                                                                           
888     1273810 40-402856                                                                                       32      88                                                      33                                                                                                          
333     1235810 40-402857                                                                                       8       8           9                                           5                                                                                                           
55      1233810 40-402858                                                                                       8       33                                                      7                                                                                                           
99      3332223 40-402859                                                                                       8       7           96                                          5                                                                                                           
996     356666  40-402860                                                                                       8       65          44                                                                                                                                                      

Here the output of new file in text file:

123810,30,"CUSTOMER PICK UP",22,22,30123812,12,,,442,31238120,33,,3,2,67 1233810,44,,33,45,551234810,53,,7,6,4421263810,88,,,6,661273810,32,,,33,88
1235810,8,,9,5,81233810,8,,,7,333332223,8,,96,5,7356666,8,,44,,65

The desired output is:

"123810","30","CUSTOMER PICK UP","22","22","30"
"123812","12","","","442","3"
...

PHP Code

<?php
set_time_limit(0);
ini_set("memory_limit", -1);

$realPath = realpath( dirname(__FILE__) );
$path     = glob($realPath.'/3pltracking/*.csv');
$UpdPath  = $realPath . '/3pltracking/';
$files    = scandir($UpdPath);
$date     = date('m-d-Y_his');
$result   = array();
$csvData  = array();



if (file_exists($path[0])) 
{
    if (($handle = fopen($path[0], "r")) !== FALSE) 
        {
            $i=0;
            while (($data = fgetcsv($handle, 10000, ",")) !== FALSE) 
            {
                $i++;
                if($i==1) continue;
                if($data[2] != ""){
                        $csvData[] = $data[2].','.$data[25].','.$data[4].','.$data[30].','.$data[41].','.$data[27];
                    }
            }

        fclose($handle);
        $fp      = fopen($realPath.'/3pltracking/TrackingFiles/Tracking_File_'.$date.'.csv', 'w');
        foreach ($csvData as $line) {
            fputcsv($fp, explode(",", $line));
        }
        fclose($fp);
        echo "Your CSV File Has Been Created In Folder Name => 'TrackingFiles' On Your FTP";
        }
    } else {
        echo "Please Upload Your CSV File First";
        }

        copy($UpdPath.$files[2], $realPath.'/3pltracking/UsedFiles/'.date('Y-m-d').'_'.rand(111, 999).'-'.$files[2]);
        //unlink($path[0]);
?>

Solution

  • It is better when you build your csvData array to build a matrix and then you do not need to bother with the explode.

    while (($data = fgetcsv($handle, 10000, ",")) !== FALSE) {
        $i++;
        if($i==1) continue;
        if($data[2] != "") {
            $csvData[] = [$data[2], $data[25], $data[4], $data[30], $data[41], $data[27]];
        }
    }
    
    fclose($handle);
    $fp = fopen($realPath.'/3pltracking/TrackingFiles/Tracking_File_'.$date.'.csv', 'w');
    foreach ($csvData as $row) {
        fputcsv($fp, $row);
    }
    

    Then as @SergeyEremin mentioned, when you use fputcsv only fields that need to be enclosed will be, ie. fields with spaces or special chars etc.

    If you absolutely need every field to be enclosed with quotes then you should probably not use fputcsv but rather build the line exactly how you want it and just use fputs.

    while (($data = fgetcsv($handle, 10000, ",")) !== FALSE) {
        $i++;
        if($i==1) continue;
        if($data[2] != "") {
            $csvData[] = '"' . $data[2] . '","' . $data[25] . '","' . $data[4] . '","' . $data[30] . '","' .  $data[41] . '","' . $data[27] . '"' . "\r\n";
        }
    }
    
    fclose($handle);
    $fp = fopen($realPath.'/3pltracking/TrackingFiles/Tracking_File_'.$date.'.csv', 'w');
    foreach ($csvData as $row) {
        fputs($fp, $row);
    }