I have a PHP routine that reads a .csv file that has been uploaded to my site.
The number of fields in the file may be different from upload to upload.
I want to be able to establish the size of the .csv file (the number of fields) and then store its contents in an array.
This is what I have so far:
//get the csv file
$file = $_FILES[csv1][tmp_name];
$handle = fopen($file,"r");
//loop through the csv file and insert into array
$dataline = fgetcsv($handle,1000,",","'");
$fieldnum = count($dataline);
$recordloop = 0;
while ($dataline)
{
for ($fieldloop=0; $fieldloop <$fieldnum; $fieldloop++)
{
//this is the bit that is wrong
$dataarray[]=array($dataline[$fieldloop]);
}
$data = fgetcsv($handle,1000,",","'");
$recordloop++;
}
If for example, there are 30 fields and 200 records I am trying to get the array to be of the structure $dataarray[200][30]
.
How do I get the data into the array of this structure?
Example .csv:
Row 1 will be field headings
Name, Gender, Ethnicity, DOB, etc .... the number of fields is not fixed - it could be from 30 to 40 fields in this row
Rows 2 onwards will be the records
John, M, British, 10/04/49, etc
Simon, M, British, 04/03/65, etc
ANSWER - did just what I wanted
$file = $_FILES[csv1][tmp_name];
$handle = fopen($file,"r");
$matrix = array();
while (($row = fgetcsv($handle, 1000, ",")) !== FALSE)
{
$matrix[] = $row;
}
You already have this kind of implementation in PHP:
$csv = array_map('str_getcsv', file('someCSVfile.csv'));
Explanation:
str_getcsv()
- Parse a CSV string into an array.file()
- Reads entire file into an array.array_map(Function, Array)
- Returns an array containing all the elements of the array after applying the callback function to each one.Example output:
//CSV
NAME,CLASS,ROOM
Sally,2018,312
Belinda,2017,148
//OUTPUT:
Array(
[0] => Array([0] => NAME, [1] => CLASS, [2] => ROOM),
[1] => Array([0] => Sally, [1] => 2018, [2] => 312),
[2] => Array([0] => Belinda, [1] => 2017, [2] => 148)
)
Associative keys
Two quick functions to parse with associative keys - both based on the array_map
method:
METHOD 1: running twice
function assoc_getcsv($csv_path) {
$r = array_map('str_getcsv', file($csv_path));
foreach( $r as $k => $d ) { $r[$k] = array_combine($r[0], $r[$k]); }
return array_values(array_slice($r,1));
}
METHOD 2: running once
function assoc_getcsv($csv_path) {
$f = array();
function parse_csv_assoc($str,&$f){
if (empty($f)) { $f = str_getcsv($str); }
return array_combine($f, str_getcsv($str));
}
return array_values(array_slice(array_map('parse_csv_assoc', file($csv_path), $f),1));
}
Example output:
//CSV
NAME,CLASS,ROOM
Sally,2018,312
Belinda,2017,148
//OUTPUT:
Array(
[0] => Array([NAME] => Sally, [CLASS] => 2018, [ROOM] => 312),
[1] => Array([NAME] => Belinda, [CLASS] => 2017, [ROOM] => 148)
)
this function will read a CSV and generate a multi-dimensional array
function fromCSVFile( $file) {
// open the CVS file
$handle = @fopen( $file, "r");
if ( !$handle ) {
throw new \Exception( "Couldn't open $file!" );
}
$result = [];
// read the first line
$first = strtolower( fgets( $handle, 4096 ) );
// get the keys
$keys = str_getcsv( $first );
// read until the end of file
while ( ($buffer = fgets( $handle, 4096 )) !== false ) {
// read the next entry
$array = str_getcsv ( $buffer );
if ( empty( $array ) ) continue;
$row = [];
$i=0;
// replace numeric indexes with keys for each entry
foreach ( $keys as $key ) {
$row[ $key ] = $array[ $i ];
$i++;
}
// add relational array to final result
$result[] = $row;
}
fclose( $handle );
return $result;
}
So if your .CSV file looks like this:
Name,Gender,Ethnicity,DOB
John,M,British,10/04/49
Simon,M,British,04/03/65
You will get this:
(
[0] => Array
(
[name] => John
[gender] => M
[ethnicity] => British
[dob] => 10/04/49
)
[1] => Array
(
[name] => Simon
[gender] => M
[ethnicity] => British
[dob] => 04/03/65
)
)
1.csv:
Name,Gender,Ethnicity,DOB
John,M,British,10/04/49
Simon,M,British,04/03/65
Use file()
to read the csv file into an array, then iterate through this array and get all the fields into an array element with explode()
and make your new $array
<?php
$file = '1.csv';
$content = file($file);
$array = array();
for($i = 1; $i < count($content); $i++) {
$line = explode(',', $content[$i]);
for($j = 0; $j < count($line); $j++) {
$array[$i][$j + 1] = $line[$j];
}
}
print_r($array);
?>
Output:
Array
(
[1] => Array
(
[1] => John
[2] => M
[3] => British
[4] => 10/04/49
)
[2] => Array
(
[1] => Simon
[2] => M
[3] => British
[4] => 04/03/65
)
)
If you want get record:2 and field:4 you can do this:
echo $array[2][4];
Output:
04/03/65
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With