问题
I am importing rims from an csv file to a webshop project. nothing for sell, just a personal project for learning how importers work. I am trying to map my $EANColumn variable to the first row field name in my csv.
So currently i have a csv with the following fields :
EAN;Brand;...and-more-comming
1234-WB;WheelBrand...and-more-comming
5678-BW;BrandWheel...and-more-comming
At the moment in my importer, it works when i map:
$EANColumn = str_replace('’', '', $importData_arr["EAN"]);
And inserting it to my database through an array :
foreach($importData_arr as $importData){
// var_dump($importData);
$insertData = array(
"EAN" =>$EANColumn);
RimsUpload::insertData($insertData);
My complete code for this part is here :
if ($request->input('submit') != null ){
$file = $request->file('file');
// File Details
$filename = $file->getClientOriginalName();
$extension = $file->getClientOriginalExtension();
$tempPath = $file->getRealPath();
$fileSize = $file->getSize();
$mimeType = $file->getMimeType();
// Valid File Extensions
$valid_extension = array("csv");
// 2MB in Bytes
$maxFileSize = 2097152;
// Check file extension
if(in_array(strtolower($extension),$valid_extension)){
// Check file size
if($fileSize <= $maxFileSize){
// File upload location
$location = 'uploads';
// Upload file
$file->move($location,$filename);
// Import CSV to Database
$filepath = url($location."/".$filename);
// Reading file
$file = fopen($filepath,"r");
$importData_arr = array();
$i = 0;
while (($filedata = fgetcsv($file, 1000, ";")) !== FALSE) {
$num = count($filedata );
$EANColumn = str_replace('’', '', $importData_arr["EAN"]);
$BrandColumn = $importData_arr["Brand"];
// Skip first row (Remove below comment if you want to skip the first row)
if($i == 0){
$i++;
continue;
}
for ($c=0; $c < $num; $c++) {
$importData_arr[$i][] = $filedata [$c];
}
$i++;
}
fclose($file);
dump($importData_arr);
// Insert to MySQL database
foreach($importData_arr as $importData){
// var_dump($importData);
$insertData = array(
"EAN" =>$EANColumn,
"Brand"=>$BrandColumn,
"Name"=>$importData[2],
"Size"=>$importData[3],
"PCD"=>$importData[4],
"Offset"=>$importData[5],
"Bore"=>$importData[6],
"Color"=>$importData[7],
"Price"=>$importData[8],
"Stock"=>$importData[9],
"ImageURL"=>$importData[10]);
RimsUpload::insertData($insertData);
}
Session::flash('message','Import Successful.');
}else{
Session::flash('message','File too large. File must be less than 2MB.');
}
}else{
Session::flash('message','Invalid File Extension.');
}
}
// Redirect to index
// return redirect()->action("RimsUploadController@index", [$request]);
return response()->redirectToAction('App\Http\Controllers\RimsUploadController@index', [$request]);
}
But the real problem is that i do not want to map my columns like [0],[1],[2],[3]... I would like to take them from the first row colum name : ["EAN"],["Brand"],["Name"],["Size"]... So if EAN is column 1 or column 7, it wont make a difference, since it will detect it by name and not by row number. So it will then be able to handle files with different column orders.
When trying to do this, i get the error :
Undefined index: EAN on $EANColumn = str_replace('’', '', $importData_arr["EAN"]);
The whole point is to make an easy way to import data from suppliers through csv into mysql. then display it to the webshop site.
回答1:
Before your while loop, extract the field names from the first row of your csv:
$file = fopen($filepath,"r");
$keys = fgetcsv($file, 1000, ';');
Then, fetch the data lines and combine the $keys
array with the data into an associative array:
$importData_arr = [];
while ($line = fgetcsv($file, 1000, ';')) {
$data = array_combine($keys, $line);
// Do something with the data
$data['EAN'] = str_replace('’', '', $data['EAN']);
$importData_arr[] = $data;
}
fclose($file);
You can now access all data fields by their name, independent of the order in the CSV:
foreach($importData_arr as $importData){
echo $importData['EAN'];
}
As long as the field names stay intact, you don't have to change your import code when the field order or count changes.
回答2:
Here is some simple proposal how to map your data to an array with given keys.
while ($row = fgetcsv($fp, 100, ',')) {
$columnName = ['a','b','c','d','e','f'];
$myRow = array_combine($columnName,$row);
....
来源:https://stackoverflow.com/questions/64912682/php-how-to-map-importer-fields-to-csv-first-row-fields