How to create an array from a CSV file using PHP and the fgetcsv function

PhpArraysCsv

Php Problem Overview


Can someone kindly provide a code to create an array from a CSV file using fgetcsv?

I've used the following code to create an array from a simple CSV file, but it doesn't work right when one of my fields has multiple commas - such as addresses.

$lines =file('CSV Address.csv');

foreach($lines as $data)
{
list($name[],$address[],$status[])
= explode(',',$data);
}

*Also, str_getcsv is not supported by my hosting service.

The above code doesn't work with the following CSV file example. First column is name, second column is address, third column is marital status.

Scott L. Aranda,"123 Main Street, Bethesda, Maryland 20816",Single
Todd D. Smith,"987 Elm Street, Alexandria, Virginia 22301",Single
Edward M. Grass,"123 Main Street, Bethesda, Maryland 20816",Married
Aaron G. Frantz,"987 Elm Street, Alexandria, Virginia 22301",Married
Ryan V. Turner,"123 Main Street, Bethesda, Maryland 20816",Single

Php Solutions


Solution 1 - Php

Like you said in your title, fgetcsv is the way to go. It's pretty darn easy to use.

$file = fopen('myCSVFile.csv', 'r');
while (($line = fgetcsv($file)) !== FALSE) {
  //$line is an array of the csv elements
  print_r($line);
}
fclose($file);

You'll want to put more error checking in there in case fopen() fails, but this works to read a CSV file line by line and parse the line into an array.

Solution 2 - Php

I think the str_getcsv() syntax is much cleaner, it also doesn't require the CSV to be stored in the file system.

$csv = str_getcsv(file_get_contents('myCSVFile.csv'));

echo '<pre>';
print_r($csv);
echo '</pre>';

Or for a line by line solution:

$csv = array();
$lines = file('myCSVFile.csv', FILE_IGNORE_NEW_LINES);

foreach ($lines as $key => $value)
{
    $csv[$key] = str_getcsv($value);
}

echo '<pre>';
print_r($csv);
echo '</pre>';

Or for a line by line solution with no str_getcsv():

$csv = array();
$file = fopen('myCSVFile.csv', 'r');

while (($result = fgetcsv($file)) !== false)
{
	$csv[] = $result;
}

fclose($file);

echo '<pre>';
print_r($csv);
echo '</pre>';

Solution 3 - Php

I have created a function which will convert a csv string to an array. The function knows how to escape special characters, and it works with or without enclosure chars.

$dataArray = csvstring_to_array( file_get_contents('Address.csv'));

I tried it with your csv sample and it works as expected!

function csvstring_to_array($string, $separatorChar = ',', $enclosureChar = '"', $newlineChar = "\n") {
    // @author: Klemen Nagode
	$array = array();
	$size = strlen($string);
	$columnIndex = 0;
	$rowIndex = 0;
	$fieldValue="";
	$isEnclosured = false;
	for($i=0; $i<$size;$i++) {

		$char = $string{$i};
		$addChar = "";

		if($isEnclosured) {
			if($char==$enclosureChar) {

				if($i+1<$size && $string{$i+1}==$enclosureChar){
					// escaped char
					$addChar=$char;
					$i++; // dont check next char
				}else{
					$isEnclosured = false;
				}
			}else {
				$addChar=$char;
			}
		}else {
			if($char==$enclosureChar) {
				$isEnclosured = true;
			}else {
				
				if($char==$separatorChar) {
					
					$array[$rowIndex][$columnIndex] = $fieldValue;
					$fieldValue="";

					$columnIndex++;
				}elseif($char==$newlineChar) {
					echo $char;
					$array[$rowIndex][$columnIndex] = $fieldValue;
					$fieldValue="";
					$columnIndex=0;
					$rowIndex++;
				}else {
					$addChar=$char;
				}
			}
		}
		if($addChar!=""){
			$fieldValue.=$addChar;

		}
	}

	if($fieldValue) { // save last field
		$array[$rowIndex][$columnIndex] = $fieldValue;
	}
	return $array;
}

Solution 4 - Php

$arrayFromCSV =  array_map('str_getcsv', file('/path/to/file.csv'));

Solution 5 - Php

Old question, but still relevant for PHP 5.2 users. str_getcsv is available from PHP 5.3. I've written a small function that works with fgetcsv itself.

Below is my function from https://gist.github.com/4152628:

function parse_csv_file($csvfile) {
	$csv = Array();
	$rowcount = 0;
	if (($handle = fopen($csvfile, "r")) !== FALSE) {
		$max_line_length = defined('MAX_LINE_LENGTH') ? MAX_LINE_LENGTH : 10000;
		$header = fgetcsv($handle, $max_line_length);
		$header_colcount = count($header);
		while (($row = fgetcsv($handle, $max_line_length)) !== FALSE) {
			$row_colcount = count($row);
			if ($row_colcount == $header_colcount) {
				$entry = array_combine($header, $row);
				$csv[] = $entry;
			}
			else {
				error_log("csvreader: Invalid number of columns at line " . ($rowcount + 2) . " (row " . ($rowcount + 1) . "). Expected=$header_colcount Got=$row_colcount");
				return null;
			}
			$rowcount++;
		}
		//echo "Totally $rowcount rows found\n";
		fclose($handle);
	}
	else {
		error_log("csvreader: Could not read CSV \"$csvfile\"");
		return null;
	}
	return $csv;
}

Returns

Begin Reading CSV

Array
(
    [0] => Array
        (
            [vid] => 
            [agency] => 
            [division] => Division
            [country] => 
            [station] => Duty Station
            [unit] => Unit / Department
            [grade] => 
            [funding] => Fund Code
            [number] => Country Office Position Number
            [wnumber] => Wings Position Number
            [title] => Position Title
            [tor] => Tor Text
            [tor_file] => 
            [status] => 
            [datetime] => Entry on Wings
            [laction] => 
            [supervisor] => Supervisor Index Number
            [asupervisor] => Alternative Supervisor Index
            [author] => 
            [category] => 
            [parent] => Reporting to Which Position Number
            [vacant] => Status (Vacant / Filled)
            [index] => Index Number
        )

    [1] => Array
        (
            [vid] => 
            [agency] => WFP
            [division] => KEN Kenya, The Republic Of
            [country] => 
            [station] => Nairobi
            [unit] => Human Resources Officer P4
            [grade] => P-4
            [funding] => 5000001
            [number] => 22018154
            [wnumber] => 
            [title] => Human Resources Officer P4
            [tor] => 
            [tor_file] => 
            [status] => 
            [datetime] => 
            [laction] => 
            [supervisor] => 
            [asupervisor] => 
            [author] => 
            [category] => Professional
            [parent] => 
            [vacant] => 
            [index] => xxxxx
        )
) 

Solution 6 - Php

Try this..

function getdata($csvFile){
	$file_handle = fopen($csvFile, 'r');
	while (!feof($file_handle) ) {
		$line_of_text[] = fgetcsv($file_handle, 1024);
	}
	fclose($file_handle);
	return $line_of_text;
}


// Set path to CSV file
$csvFile = 'test.csv';

$csv = getdata($csvFile);
echo '<pre>';
print_r($csv);
echo '</pre>';

Array
(
    [0] => Array
        (
            [0] => Project
            [1] => Date
            [2] => User
            [3] => Activity
            [4] => Issue
            [5] => Comment
            [6] => Hours
        )

    [1] => Array
        (
            [0] => test
            [1] => 04/30/2015
            [2] => test
            [3] => test
            [4] => test
            [5] => 
            [6] => 6.00
        ));

Solution 7 - Php

To get an array with the right keys, you can try this:

// Open file
$file = fopen($file_path, 'r');

// Headers
$headers = fgetcsv($file);

// Rows
$data = [];
while (($row = fgetcsv($file)) !== false)
{
    $item = [];
    foreach ($row as $key => $value)
        $item[$headers[$key]] = $value ?: null;
    $data[] = $item;
}

// Close file
fclose($file);

Solution 8 - Php

This function will return array with Header values as array keys.

function csv_to_array($file_name) {
		$data =  $header = array();
		$i = 0;
		$file = fopen($file_name, 'r');
		while (($line = fgetcsv($file)) !== FALSE) {
			if( $i==0 ) {
				$header = $line;
			} else {
				$data[] = $line;		
			}
			$i++;
		}
		fclose($file);
		foreach ($data as $key => $_value) {
			$new_item = array();
			foreach ($_value as $key => $value) {
				$new_item[ $header[$key] ] =$value;
			}
			$_data[] = $new_item;
		}
		return $_data;
	}

Solution 9 - Php

If you want each line to be in an array, and each cell in the line in array:

$file = fopen('csvFile.csv', 'r');              // Open the file                     
while (($line = fgetcsv($file)) !== FALSE) {    // Read one line
    $array[] =$line;                            // Add the line in the main array
}
echo '<pre>';
print_r($array);   //print it out
echo '</pre>'; 
fclose($file);

Solution 10 - Php

 function csvToArray($path)
{
    try{
        $csv = fopen($path, 'r');
        $rows = [];
        $header = [];
        $index = 0;
        while (($line = fgetcsv($csv)) !== FALSE) {
            if ($index == 0) {
                $header = $line;
                $index = 1;
            } else {
                $row = [];
                for ($i = 0; $i < count($header); $i++) {
                    $row[$header[$i]] = $line[$i];
                }
                array_push($rows, $row);
            }
        }
        return $rows;
    }catch (Exception $exception){
        return false;
    }
}

Solution 11 - Php

Please fin below a link to the function from @knagode, enhanced with a skip rows parameter. https://gist.github.com/gabrieljenik/47fc38ae47d99868d5b3#file-csv_to_array

<?php
	/**
	 * Convert a CSV string into an array.
	 * 
	 * @param $string
	 * @param $separatorChar
	 * @param $enclosureChar
	 * @param $newlineChar
	 * @param $skip_rows
	 * @return array
	 */
	public static function csvstring_to_array($string, $skip_rows = 0, $separatorChar = ';', $enclosureChar = '"', $newlineChar = "\n") {
	    // @author: Klemen Nagode 
	    // @source: http://stackoverflow.com/questions/1269562/how-to-create-an-array-from-a-csv-file-using-php-and-the-fgetcsv-function
	    $array = array();
	    $size = strlen($string);
	    $columnIndex = 0;
	    $rowIndex = 0;
	    $fieldValue="";
	    $isEnclosured = false;
	    for($i=0; $i<$size;$i++) {
	
	        $char = $string{$i};
	        $addChar = "";
	
	        if($isEnclosured) {
	            if($char==$enclosureChar) {
	
	                if($i+1<$size && $string{$i+1}==$enclosureChar){
	                    // escaped char
	                    $addChar=$char;
	                    $i++; // dont check next char
	                }else{
	                    $isEnclosured = false;
	                }
	            }else {
	                $addChar=$char;
	            }
	        }else {
	            if($char==$enclosureChar) {
	                $isEnclosured = true;
	            }else {
	
	                if($char==$separatorChar) {
	
	                    $array[$rowIndex][$columnIndex] = $fieldValue;
	                    $fieldValue="";
	
	                    $columnIndex++;
	                }elseif($char==$newlineChar) {
	                    echo $char;
	                    $array[$rowIndex][$columnIndex] = $fieldValue;
	                    $fieldValue="";
	                    $columnIndex=0;
	                    $rowIndex++;
	                }else {
	                    $addChar=$char;
	                }
	            }
	        }
	        if($addChar!=""){
	            $fieldValue.=$addChar;
	
	        }
	    }
	
	    if($fieldValue) { // save last field
	        $array[$rowIndex][$columnIndex] = $fieldValue;
	    }
	    
	    
	    /**
	     * Skip rows. 
	     * Returning empty array if being told to skip all rows in the array.
	     */ 
	    if ($skip_rows > 0) {
	    	if (count($array) == $skip_rows)
	    		$array = array();
	    	elseif (count($array) > $skip_rows)
	    		$array = array_slice($array, $skip_rows);	    	
	    	
	    }
	    
	    return $array;
	}

Solution 12 - Php

I came up with this pretty basic code. I think it could be useful to anyone.

$link = "link to the CSV here"
$fp = fopen($link, 'r');

while(($line = fgetcsv($fp)) !== FALSE) {
    foreach($line as $key => $value) {
	    echo $key . " - " . $value . "<br>";
	}
}
  

fclose($fp);

Solution 13 - Php

convertToArray(file_get_content($filename));

function convertToArray(string $content): array
{
   $data = str_getcsv($content,"\n");
   array_walk($data, function(&$a) use ($data) {
       $a = str_getcsv($a);
   });

   return $data;
}

Solution 14 - Php

Try this code:

function readCsv($file)
{
    if (($handle = fopen($file, 'r')) !== FALSE) {
        while (($lineArray = fgetcsv($handle, 4000)) !== FALSE) {
            print_r(lineArray);
        }
        fclose($handle);
    }
}

Solution 15 - Php

I've made an utility in PHP that converts CSV data from a file or string to an array of objects, and also offers an option to group the items by an specific column, and you can also change the delimiter from comma to any character you want.

Example:

Brand, Model, Year
Volkswagen, Gol,2008
Fiat, Uno, 2007
Fiat, Palio, 2002
Fiat, Mobi, 2021
Volkswagen, Jetta, 2018
Hyunday, HB20, 2020

Returns: Array made out of CSV

Group by examples:

Grouping by the 'Brand' column

Grouping by the 'Year' column

You can find the code here: https://github.com/raphah96/PHPCSV

I deal a lot with CSV so that's why I had to made a consistent utility instead of a simple one time use code.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThomasView Question on Stackoverflow
Solution 1 - PhpDave DeLongView Answer on Stackoverflow
Solution 2 - PhpAlix AxelView Answer on Stackoverflow
Solution 3 - PhpknagodeView Answer on Stackoverflow
Solution 4 - PhpIvan GView Answer on Stackoverflow
Solution 5 - PhpManu ManjunathView Answer on Stackoverflow
Solution 6 - PhpDeenadhayalan ManoharanView Answer on Stackoverflow
Solution 7 - PhpclemView Answer on Stackoverflow
Solution 8 - PhpsameeraliView Answer on Stackoverflow
Solution 9 - PhpForGoodView Answer on Stackoverflow
Solution 10 - PhpghakView Answer on Stackoverflow
Solution 11 - PhpGabrielView Answer on Stackoverflow
Solution 12 - PhpgrcView Answer on Stackoverflow
Solution 13 - PhpKamil SułekView Answer on Stackoverflow
Solution 14 - PhpIndrajeet SinghView Answer on Stackoverflow
Solution 15 - PhpRafael BitencourtView Answer on Stackoverflow