How To Read A CSV File & Write Data Into It Using PHP
Tags: webdev, tutorial, php, beginners
Published: 2023-04-10 16:26:12

I'm currently building an email software with PHP to help companies send newsletters to their contact list and I implemented a feature that would enable the software to read & write data into a contact list in CSV format.

I will start by explaining what a CSV file is, how to read data & extract data from it, then how to write data into it.

## What is a CSV File?

A CSV (Comma Separated Values) File is a text file that uses commas to separate information.

Each line of this file is a data record and this means that it can be used to present information in a table-structured format.

In the next section, I will show you how to read and extract data from a CSV file.

## Reading & Extracting Data From CSV File

I will use the inbuilt function [`file`](https://www.w3schools.com/php/func_filesystem_file.asp) to read data from the CSV file and then I will use the [`str_getcsv()`](https://www.w3schools.com/php/func_string_str_getcsv.asp) to parse the strings containing commas.

Before I explain how to use the function `str_getcsv()`, I want to show you how data from a CSV file is being outputted.

```php
<?php
    if($_FILES){
        var_dump(file($_FILES['file']['tmp_name'], FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));
    }
?>

<html>
    <body>
        <form method="post" enctype="multipart/form-data">
            <input type="file" name="file" />
            <button>upload</button>
        </form>
    </body>
</html>
```
When I upload a file using the code above, this is what the output looks like;

![csv_php_1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a01ggzkxkjdvjs3bn33i.png)

Now, If you look at the image above you will notice that each of the strings has commas within them and each comma separates one piece of information from the other.

I will go ahead and loop through this file again, but this time I will be using the [`array_map()`](https://www.w3schools.com/php/func_array_map.asp) function and then provide `str_getcsv()` as the callback that will parse each of these strings that have commas and separate them in a single array.

```php
if($_FILES){
    //loop through the csv file into an array
    $theCSV = array_map('str_getcsv', file($_FILES['file']['tmp_name'], FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));
    //dump result
    var_dump($theCSV);
}
```
This is what our array looks like now.

![csv_php_2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7fqj1vl02kinl1qbf0wn.png)

You can say that it is much better than the previous output, and we have the column headers (Full Name, Phone, Email) as the first element of this array.

Now, let us walk on this array using the [`array_walk()`](https://www.w3schools.com/php/func_array_walk.asp) function and then provide a callback function that will combine the column headers (Full Name, Phone, Email) and each of the CSV data as a new array.

```php
if($_FILES){
    //loop through the csv file into an array
    $theCSV = array_map('str_getcsv', file($_FILES['file']['tmp_name'], FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));
    /*Walk through the array and combine the headers which is the first element of our csv array with the rest of the csv data*/
    array_walk($theCSV, function(&$ary) use($theCSV) {
        $ary = array_combine($theCSV[0], $ary);
    });
    //dump result
    var_dump($theCSV);
}
?>
```

If you noticed, on the callback function above, I used the `&` operator on the `$ary` variable to pass it into the function by reference and this makes it possible for us to modify the original array. [Visit my article on LinkedIn to learn the difference between passing by reference and passing by value in PHP.](https://www.linkedin.com/pulse/passing-reference-value-php-simon-ugorji?trk=public_post)

When we run the code above, this is what our CSV array now looks like;

![csv_php_3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/52xvefu4ngsx7kibyoq1.png)

If you noticed, the first element of this new array still has the headers combined with itself because we had earlier used it to combine with every other element of the CSV array.

Now, let us remove the column headers which is the first element of this CSV array using the function [`array_shift()`](https://www.php.net/manual/en/function.array-shift.php)

```php
if($_FILES){
    //loop through the csv file into an array
    $theCSV = array_map('str_getcsv', file($_FILES['file']['tmp_name'], FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));
    /*Walk through the array and combine the headers which is the first element of our csv array with the rest of the csv data*/
    array_walk($theCSV, function(&$ary) use($theCSV) {
        $ary = array_combine($theCSV[0], $ary);
    });
    //remove column headers which is the first element
    array_shift($theCSV);
    //dump result
    var_dump($theCSV);
}
```

This is what our final CSV array looks like

![csv_php_4](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/soz7xwq4bo9s8l0sv6nk.png)

If you want to extract values from the Email columns only, you can write a loop that will go through the CSV array and then extract data from the email index.

We have made it very easy to read and extract data from a CSV file 😃

![chp_knuckle_gif](https://miro.medium.com/v2/resize:fit:640/0*CX3t-1CpUOl3S3vp.gif)

Now, before we talk about writing data to this same CSV file, I will make the code above a function so that we can return both the column headers and the CSV data as an array because we would need it in the next section 🙂

```php
function readCSV($file){
    if(empty($file) || !file_exists($file)) return;
    //store the column headers
    $headers = null;
    $theCSV = array_map('str_getcsv', file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));
    /*Walk through the array and combine the headers which is the first element of our csv array with the rest of the csv data*/
    array_walk($theCSV, function(&$ary) use($theCSV, &$headers) {
            $ary = array_combine($theCSV[0], $ary);
            //store the headers
            $headers = $theCSV[0];
    });
    //remove column headers which is the first element of our csv array
    array_shift($theCSV);
    //return data
    return array(
        "headers" => $headers,
        "data" => $theCSV
    );
}
```

## Writing Data Into A CSV File

In this section, I will show you an easy way to write data into a CSV file.

The logic is to open the CSV file in append mode with [`fopen()`](https://www.w3schools.com/php/func_filesystem_fopen.asp) and use [`fputcsv()`](https://www.w3schools.com/php/func_filesystem_fputcsv.asp) to parse the data we want to write to it in CSV format and then it will write this data to the file stream.

Now, how do we format and arrange this new data that we want to append to our CSV file?

To do that, I will loop through the column headers that are returned from the `readCSV()` function and then attach the respective values to these headers so that they are able to maintain their position when we append them to the CSV file.

```php
if($_SERVER['REQUEST_METHOD'] == "POST"){
    $file = "./my_csv_file.csv";
    //loop through the csv file into an array
    $csvData = readCSV($file);
    //create array to store the new data
    $newData = [];
    //loop through headers and then add values as a new array
    foreach($csvData['headers'] as $index => $key){
        if($key == 'Full Name'){
            $newData[$key] = $_POST['full_name'];
        }elseif($key == 'Email'){
            $newData[$key] = $_POST['email'];
        }elseif($key == 'Phone'){
            $newData[$key] = $_POST['phone'];
        }else{
            $newData[$key] = '';
        }
    }
    var_dump($newData);
}
```
So, this is what the array that will be appended to our CSV file looks like.

![csv_php_5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3el62onxaulanmbvuahf.png)

Before we append this data to the CSV file, we have to get rid of the keys and we can do that easily using [`array_values()`](https://www.w3schools.com/php/func_array_values.asp)

```php
if($_SERVER['REQUEST_METHOD'] == "POST"){
    $file = "./my_csv_file.csv";
    //loop through the csv file into an array
    $csvData = readCSV($file);
    //create array to store the new data
    $newData = [];
    //loop through headers and then add values as a new array
    foreach($csvData['headers'] as $index => $key){
        if($key == 'Full Name'){
            $newData[$key] = $_POST['full_name'];
        }elseif($key == 'Email'){
            $newData[$key] = $_POST['email'];
        }elseif($key == 'Phone'){
            $newData[$key] = $_POST['phone'];
        }else{
            $newData[$key] = '';
        }
    }
    //open the csv file as in append mode
    $fp = fopen($file, 'a+');
    //remove keys from new data
    $newData = array_values($newData);
    //append data to csv file
    fputcsv($f, $newData);
    //close the resource
    fclose($fp);
}
```

If you followed the process correctly, you should see a new row of data when you open the CSV file.

![csv_php_5](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zxk8lw25lnnjs2h74ym4.png)

## CONCLUSION

We have talked about what a CSV file is, how to read and extract data from a CSV file, and then how you can write data back into a CSV file.

I explained all the functions and procedures used in this tutorial and I added external links if you want to extend your knowledge.

![anything_else_gif](https://miro.medium.com/v2/resize:fit:640/0*5l8s_R6ZX3RD4v-K.gif)

That's it! Is there anything I'm missing? Do you have any questions for me? I will be in the comments section! 😊

## EXTRA

> I am open to web development and Technical Writing roles ✅
You will never know if I am a good fit for your company until you give me a chance.

Which validation library do you use for your PHP forms?

Have you tried [octavalidate](https://octagon-simon.github.io/projects/octavalidate/), the simplest and easiest validation library with over 4 releases that help to validate your forms using validation rules, sophisticated regular expressions, and PHP's inbuilt functions?

[Learn how you can validate your PHP forms using octavalidate](https://medium.com/nerd-for-tech/how-to-validate-your-forms-server-side-with-php-75680d04971b)

Thank you for reading!

Photo by Mika Baumeister on Unsplash