72

I want to upload a csv file with php. After the file is uploaded, I want to display the data of the CSV file. I would like an example how to accomplish this task.

6
  • 9
    Handling file uploads in the PHP manual Commented Apr 8, 2011 at 10:02
  • 6
    fgetcsv() in the PHP manual Commented Apr 8, 2011 at 10:02
  • 3
    You didn't find any tutorial that explains uploading files with PHP? I bet there are some... Commented Apr 8, 2011 at 10:03
  • 1
    i am confused to choose a plugin,Suggest me a best plugin to upload files in php. Commented Apr 8, 2011 at 10:18
  • 1
    Dup of parse csv file php, Quick php file upload guide Commented Dec 26, 2011 at 7:37

9 Answers 9

172

This can be done in a much simpler manner now.

$tmpName = $_FILES['csv']['tmp_name'];
$csvAsArray = array_map('str_getcsv', file($tmpName));

This will return you a parsed array of your CSV data. Then you can just loop through it using a foreach statement.

Sign up to request clarification or add additional context in comments.

5 Comments

In addition of this brilliant solution, using explode(<delimiter>, $csv) you can separate each field and have an array of fields inside each element of the CSV array.
$csvAsArray = array_map('str_getcsv', file($_FILES['csv']['tmp_name'])); Incase you needed it any simpler.
While this seems to be quick and easy, it is not a complete or secure solution. It should at least involve move_uploaded_file() to ensure that the file was actually uploaded via $_POST; and secondly there is no check to see if this is a CSV file. Try uploading some graphics instead and look what's inside $csvAsArray ... !
very brilliant answer.
I have an issue. If I opened using the usual fopen, my text is like this ["19","This is a \nlonger\nscrolling name","NULL"]. If I used the method above it became ["19","This is a \n"],["longer"],["scrolling name\"","NULL"]. Anyone else had similar issue?
75

untested but should give you the idea. the view:

<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="csv" value="" />
<input type="submit" name="submit" value="Save" /></form>

upload.php controller:


$csv = array();

// check there are no errors
if($_FILES['csv']['error'] == 0){
    $name = $_FILES['csv']['name'];
    $ext = strtolower(end(explode('.', $_FILES['csv']['name'])));
    $type = $_FILES['csv']['type'];
    $tmpName = $_FILES['csv']['tmp_name'];

    // check the file is a csv
    if($ext === 'csv'){
        if(($handle = fopen($tmpName, 'r')) !== FALSE) {
            // necessary if a large csv file
            set_time_limit(0);

            $row = 0;

            while(($data = fgetcsv($handle, 1000, ',')) !== FALSE) {
                // number of fields in the csv
                $col_count = count($data);

                // get the values from the csv
                $csv[$row]['col1'] = $data[0];
                $csv[$row]['col2'] = $data[1];

                // inc the row
                $row++;
            }
            fclose($handle);
        }
    }
}

5 Comments

Quick question the file will be removed after the parse right? its just temp stored under the temp folder am i correct?
A good solution, but not sure why you are only grabbing the first two columns of each row? Also, $csv[$row]['row1'] = $data[0]; is misleading, it should be $csv[$row]['column1'] = $data[0];. In any case, a better solution is just to use $csv[$row]=$data and make a multi-dimensional array with the whole file.
it's better to check MIME instead of file extension.
Thanks for this solution. I edited $num to $col_count and the row1, row2 indexes to col1, col2 since that's what they are and it was the only confusing part. Instead of disabling execution time, what I usually do is set_time_limit(60) inside the while loop so it stays reset as long as we're reading the rows and then starts to count down again after that's done. That way if there is some other issue after exiting the loop then it will time out like it's supposed to and we don't have to worry about how long the file will be.
@Bruce To my understanding, it may be removed or overwritten by future saves, but this would be a by-product of those interactions. As such, dont count on it to be stored permanently deleted or saved unless you explicitly declare it so.
52

Although you could easily find a tutorial how to handle file uploads with php, and there are functions (manual) to handle CSVs, I will post some code because just a few days ago I worked on a project, including a bit of code you could use...

HTML:

<table width="600">
<form action="<?php echo $_SERVER["PHP_SELF"]; ?>" method="post" enctype="multipart/form-data">

<tr>
<td width="20%">Select file</td>
<td width="80%"><input type="file" name="file" id="file" /></td>
</tr>

<tr>
<td>Submit</td>
<td><input type="submit" name="submit" /></td>
</tr>

</form>
</table>

PHP:

if ( isset($_POST["submit"]) ) {

   if ( isset($_FILES["file"])) {

            //if there was an error uploading the file
        if ($_FILES["file"]["error"] > 0) {
            echo "Return Code: " . $_FILES["file"]["error"] . "<br />";

        }
        else {
                 //Print file details
             echo "Upload: " . $_FILES["file"]["name"] . "<br />";
             echo "Type: " . $_FILES["file"]["type"] . "<br />";
             echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
             echo "Temp file: " . $_FILES["file"]["tmp_name"] . "<br />";

                 //if file already exists
             if (file_exists("upload/" . $_FILES["file"]["name"])) {
            echo $_FILES["file"]["name"] . " already exists. ";
             }
             else {
                    //Store file in directory "upload" with the name of "uploaded_file.txt"
            $storagename = "uploaded_file.txt";
            move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . $storagename);
            echo "Stored in: " . "upload/" . $_FILES["file"]["name"] . "<br />";
            }
        }
     } else {
             echo "No file selected <br />";
     }
}

I know there must be an easier way to do this, but I read the CSV file and store the single cells of every record in an two dimensional array.

if ( isset($storagename) && $file = fopen( "upload/" . $storagename , r ) ) {

    echo "File opened.<br />";

    $firstline = fgets ($file, 4096 );
        //Gets the number of fields, in CSV-files the names of the fields are mostly given in the first line
    $num = strlen($firstline) - strlen(str_replace(";", "", $firstline));

        //save the different fields of the firstline in an array called fields
    $fields = array();
    $fields = explode( ";", $firstline, ($num+1) );

    $line = array();
    $i = 0;

        //CSV: one line is one record and the cells/fields are seperated by ";"
        //so $dsatz is an two dimensional array saving the records like this: $dsatz[number of record][number of cell]
    while ( $line[$i] = fgets ($file, 4096) ) {

        $dsatz[$i] = array();
        $dsatz[$i] = explode( ";", $line[$i], ($num+1) );

        $i++;
    }

        echo "<table>";
        echo "<tr>";
    for ( $k = 0; $k != ($num+1); $k++ ) {
        echo "<td>" . $fields[$k] . "</td>";
    }
        echo "</tr>";

    foreach ($dsatz as $key => $number) {
                //new table row for every record
        echo "<tr>";
        foreach ($number as $k => $content) {
                        //new table cell for every field of the record
            echo "<td>" . $content . "</td>";
        }
    }

    echo "</table>";
}

So I hope this will help, it is just a small snippet of code and I have not tested it, because I used it slightly different. The comments should explain everything.

7 Comments

what if some one wanted to save the $content obtained from the inner foreach loop in the text-fields? I am trying to do this here : stackoverflow.com/questions/14536221/…
The answer below using fgetcsv looks better because it should handle escaped characters correctly.
Yes, I see, fgetcsv may be a better choice.
Why you are uploading the File, Can we read the File With out save at Server .?
@Mrworldwide PHP is a server-side program, thus you must either upload the file or use AJAX JS to send the data back to the server. You could read without saving in JS (in which case look at Papa Parse), but this Q and is explicitly for a PHP solution: "...after I uploaded the file...".
|
4

I have created below snippet with the help of @Thomas Clowes answer

$tmpName = $_FILES['csv']['tmp_name'];

$csv_data = array_map('str_getcsv', file($tmpName));

array_walk($csv_data , function(&$x) use ($csv_data) {
  $x = array_combine($csv_data[0], $x);
});

/** 
*
* array_shift = remove first value of array 
* in csv file header was the first value
* 
*/
array_shift($csv_data);

// Print Result Data
echo '<pre/>';
print_r($csv_data);    

It will get result like below

 Array
(
   [0] => Array
    (
        
        [make] => Audi
        [model] => S4
        [grade] => 
        [chassis] => WAUZZZ8K9DA076529
        [year] => 2012
        [kms] => 127000
        [color] => White
        [doors] => 4
        [cc] => 3000
        [engineno] => 
        [trans] => FAT
        [fueltype] => P
        [condition] => 4            
        [price] => 15753
        
    )

)

Comments

1

You want the handling file uploads section of the PHP manual, and you would also do well to look at fgetcsv() and explode().

1 Comment

Watch out for commas, quotes and linebreaks inside string values, you should use a state machine to split CSV, not explode.
1

I feel str_getcsv — Parse a CSV string into an array is the best option for you.

  1. You need to upload the file to the server.

  2. Parse the file using str_getcsv.

  3. Run through the array and align as per u need on your website.

3 Comments

Thanks for the reply.and i have another question for you that which is the best plugin to upload file so that it avoids size of code and has good user interface,please suggest me a plugin
@vinay - i prefer my own upload script to be written. what do u mean by upload plugin ??? you can write one on your own write... its max 10 lines of code
@vinay - if u really wanna have a plugin to do (php +js) check out tinyurl.com/44nv6yt
0
function doParseCSVFile($filesArray)
    {
        if ((file_exists($filesArray['frmUpload']['name'])) && (is_readable($filesArray['frmUpload']['name']))) { 

            $strFilePath = $filesArray['frmUpload']['tmp_name']; 

            $strFileHandle = fopen($strFilePath,"r");
            $line_of_text = fgetcsv($strFileHandle,1024,",","'"); 
            $line_of_text = fgetcsv($strFileHandle,1024,",","'"); 

            do { 
                if ($line_of_text[0]) { 
                    $strInsertSql = "INSERT INTO tbl_employee(employee_name, employee_code, employee_email, employee_designation, employee_number)VALUES('".addslashes($line_of_text[0])."', '".$line_of_text[1]."', '".addslashes($line_of_text[2])."', '".$line_of_text[3]."', '".$line_of_text[4]."')";
                    ExecuteQry($strInsertSql);
                }               
            } while (($line_of_text = fgetcsv($strFileHandle,1024,",","'"))!== FALSE);

        } else {
            return FALSE;
        }
    }

Comments

0
public function uploadCsvFile(){
   try{ 
    if($_SERVER['REQUEST_METHOD'] === 'POST'){
        $request = $this->post();
        $fileName = $request->file;
        $file = fopen($fileName, "r"); //open the file
        // $fileName = $_FILES["file"]["tmp_name"];
        while(($column = fgetcsv($file)) !== FALSE){
            $num = count($column);
            $this->dbw->query("insert into csv_upload(first_name,last_name,email,phone,address,pin) values('".$column[0]."','".$column[1]."','".$column[2]."','".$column[3]."','".$column[4]."','".$column[5]."')");
        }

        fclose($file);
    }
    }catch (Exception $e) {
        $this->responseErr($e->getMessage(), 500);
    }
}

1 Comment

Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes.
-2

You can try with this:

function doParseCSVFile($filesArray)
{
    if ((file_exists($filesArray['frmUpload']['name'])) && (is_readable($filesArray['frmUpload']['name']))) { 

        $strFilePath = $filesArray['frmUpload']['tmp_name']; 

        $strFileHandle = fopen($strFilePath,"r");
        $line_of_text = fgetcsv($strFileHandle,1024,",","'"); 
        $line_of_text = fgetcsv($strFileHandle,1024,",","'"); 

        do { 
            if ($line_of_text[0]) { 
                $strInsertSql = "INSERT INTO tbl_employee(employee_name, employee_code, employee_email, employee_designation, employee_number)VALUES('".addslashes($line_of_text[0])."', '".$line_of_text[1]."', '".addslashes($line_of_text[2])."', '".$line_of_text[3]."', '".$line_of_text[4]."')";
                ExecuteQry($strInsertSql);
            }               
        } while (($line_of_text = fgetcsv($strFileHandle,1024,",","'"))!== FALSE);

    } else {
        return FALSE;
    }
}

1 Comment

The answer isn't relevant completely and copy/paste type thing. he uses database and stuff here.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.