Reputation: 444
I want to import a csv file from a html form and process it in php. Dynamically create a table and append it to my div for preview purposes.
I want array only of unique records inside the table.
I have following code in php:
$tmpName = $_FILES['blk_csv']['tmp_name'];
$csvAsArray = array_unique((array_map('str_getcsv', file($tmpName))),SORT_REGULAR);
$table_data = '<table id="template_table" name="template_table" class="table">';
$csvAsArrayU = $csvAsArray;
for ($i = 0; $i < count($csvAsArrayU); $i++) {
if($i == 0){
$table_data .= '<thead><tr>';
for($h = 0 ; $h < count($csvAsArrayU[$i]); $h++){
$table_data .= '<th class="text-center">'.$csvAsArrayU[$i][$h].'</th>';
}
$table_data .= '</tr></thead><tbody>';
}
else{
$table_data .= '<tr id="row-'.$i.'">';
for($r = 0 ; $r < count($csvAsArrayU[$i]); $r++){
$table_data .= '<td class="text-center">'.$csvAsArrayU[$i][$r].'</td>';
}
$table_data .= '</tr>';
}
}
$table_data .= ' </tbody></table>';
My csv structure
NAME,EMAIL
Morris,[email protected]
Morris,[email protected]
Morris,[email protected]
Jacob,[email protected]
If you print_r($csvAsArray)
it gives me following output:
Array ( [0] => Array ( [0] => NAME [1] => EMAIL ) [1] => Array ( [0] => Morris [1] => [email protected] ) [8] => Array ( [0] => Jacob [1] => [email protected] ) )
If you notice the index for third element is 8 and not 2. Thus the DataTable library fails to load the data and shows something like this :
Can any one guide me how to fix this ? Or may be a different approach to load only unique rows in array ?
Upvotes: 0
Views: 674
Reputation: 4889
OP asked for a different approach in the comments. Here's a rewrite that implements my suggestions. I've fluffed out function cascades into one-function-per-line to keep this more educational. Please read the comments, understand the functions used, and remember: the manual is your best friend. Now, the code:
$tmpName = 'tmp/file.csv';
// Read lines; Filter for unique lines; Map array as CSV:
$rawLines = file($tmpName, FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES);
$uniqLines = array_unique($rawLines);
$csvAsArray = array_map('str_getcsv', $uniqLines);
// Get the header row:
$csvHeaderRow = array_shift($csvAsArray);
// Build table header:
$table_data = '<table id="template_table" name="template_table" class="table">';
$table_data .= '<thead><tr>';
// Iterate each header field:
foreach($csvHeaderRow as $field){
$table_data .= '<th class="text-center">'.$field.'</th>';
}
$table_data .= '</tr></thead><tbody>';
// Build table body, iterate lines/rows:
foreach($csvAsArray as $i => $row){
$table_data .= '<tr id="row-'.$i.'">';
// Iterate each field in the row:
foreach($row as $field) {
$table_data .= '<td class="text-center">'.$field.'</td>';
}
$table_data .= '</tr>';
}
// Wrap up table
$table_data .= ' </tbody></table>';
Above code follows OP's code as far as possible. We use appropriate flags for file
to remove clutter in the beginning. We filter the array of strings for unique values, rather than parsing everything as CSV and comparing arrays (as in OP), to avoid redundant processing. We use a foreach
loop that's agnostic to having consecutive indices, and the typical way of iterating an array. This results in the following output (without newlines, hard to read):
<table id="template_table" name="template_table" class="table"><thead><tr><th class="text-center">NAME</th><th class="text-center">EMAIL</th></tr></thead><tbody><tr id="row-0"><td class="text-center">Morris</td><td class="text-center">[email protected]</td></tr><tr id="row-1"><td class="text-center">Jacob</td><td class="text-center">[email protected]</td></tr> </tbody></table>
If you wanted an easy way to add newlines and make your HTML output more readable. And would rather not tack a "\n"
at the end of each line (ugly!). Then, instead of string concatenation ($table_data .=
), you can append to an array ($table_data[] =
), and in the end implode("\n", $table_data)
, and your HTML output will be much more readable.
Upvotes: 1
Reputation: 1367
$csvAsArray = array_values($csvAsArray)
should work for you, this would reset the keys of the array, so that the index of the third element is 2.
:)
Upvotes: 1