php Undefined offset csv file upload - php

I'm trying to import and fetch data from CSV file and store it in my database
my database table schema is like this
users ( ID , Fname , Lname, user_type , major , Bday , Email,password , image , status )
csv ( 111 , Leo , pichon, , business, , leo#yzu.cn )
and this is my csv file schema , columns only matching the required filed of my database schema its somthing like this :
'' the empty filed either have default value or null ''
after importing i get the following notice for almost each row of my data file :
Undefined offset: 1 in php csv
here's my php function :
if ($_GET['action'] = 'UsersCvs') {
if (isset($_FILES['users_cvs']['name'])) {
$file = $_FILES['users_cvs']['tmp_name'];
if ($_FILES["users_cvs"]["size"] > 0) {
$handle = fopen($file, "r");
$c = 0;
while (($files = fgetcsv($handle, 2000, ",")) !== false) {
// $id = mysqli_real_escape_string($link , $files[0]);
// $fname = $files[1];
// $lname = $files[2];
// $user_type = $files[3];
// $major = $files[4];
// $email = $files[6];
// $gender = mysqli_real_escape_string($link, $filesop[6]);
//$sql = "INSERT INTO users(ID , Fname,Lname , user_type , major , Email) values ('" . $id . "','" . $fname . "' ,'" . $lname . "' ,'" .$user_type. "','" . $major . "','" . $email . "')";
// mysqli_query($link, $sql);
$num = count($files);
echo "<p> $num fields in row $c: <br /></p>\n";
$c++;
for ($i = 0; $i < $num; $i++) {
echo $files[$i] . "<br />\n";
}
}
fclose($file);
// if ($sql) {
// echo 1 ;
// } else {
// echo mysqli_error($link); ;
// }
} else {
}
}else{
echo 'no file found';
}
}
what seems strange to my and after inspection my data gets encoded to unreadable string
somthing like this
<p> 3 fields in line 2: <br /></p>
�Ѷѩ\h�1�������
��drKK(G~�S⼥���Nw|x���
�s�k�Ŗ�X���J�fb�fWш�eʬ�y�`hc�g�
1 fields in line 3:
���y��Q�b~���^�)�Ϸ�������LD?��r�:��DN��(����C��*T�?��C��!�&�e���!_�8��+[�|��PK�N�#}�":[docProps/core.xml��QK�0���C�{��cm*{r 8Q|��lҐD��{�v����c�9���^R������:��� Ah���%zٮ���gZ���P�8��no
2 fields in line 4:
I've really tried my best and did online research but i couldn't find any matching reference
i would highly appreciate help thanks in advance

The file you are trying to process is not a CSV file, but an Excel workbook (a ".xlsx" file).
There are two clues here:
First, the data you're seeing clearly isn't human-readable text. A CSV file is just a text file formatted to a particular convention, whereas this looks very much like binary data intended only for machine use.
The very short snippet you posted happened to include the string "docProps/core.xml". If you search for that online, you'll get lots of references to the "Office Open XML" format used by modern versions of Microsoft Office. The files are structured as a zip file containing multiple XML files, and that's the name of one of the internal files in the zip.
The first thing you should do is add some validation to your code. Input from the user always needs validating, and in this case a check for the expected number of fields, or a mandatory header row, would have given you an error straight away.
The second thing you should do is either a) tell the user to export the spreadsheet as a CSV file, or b) re-write the code using a library that can read Excel files, such as PhpSpreadsheet.

Related

PHP CSV MySql Import

I have the following issue that I hope ya'll can shed some light on. I am trying to import a csv that although it looks normal (, for seperators) yet when I attempt to import there is always a line break after the 40th ish column.
This is my code for the import:
<?php
// include mysql database configuration file
require_once "layouts/config.php";
if (isset($_POST['submit']))
{
// Open uploaded CSV file with read-only mode
$csvFile = fopen(__DIR__. '/uploads/upload.csv', 'r');
//fgetcsv($csvFile);
$values = array();
while (($getData = fgetcsv($csvFile, 300, ",")) !== FALSE)
{
$values[]= "('".$getData[0]."' , '".$getData[1]."' ,'".$getData[2]."' ,'".$getData[3]."' ,'".$getData[4]."' ,
'".$getData[5]."' , '".$getData[6]."' ,'".$getData[7]."' ,'".$getData[8]."' ,'".$getData[9]."' ,
'".$getData[10]."', '".$getData[11]."','".$getData[12]."','".$getData[13]."','".$getData[14]."',
'".$getData[15]."', '".$getData[16]."','".$getData[17]."','".$getData[18]."','".$getData[19]."',
'".$getData[20]."', '".$getData[21]."','".$getData[22]."','".$getData[23]."','".$getData[24]."',
'".$getData[25]."', '".$getData[26]."','".$getData[27]."','".$getData[28]."','".$getData[29]."',
'".$getData[30]."', '".$getData[31]."','".$getData[32]."','".$getData[33]."','".$getData[34]."',
'".$getData[35]."', '".$getData[36]."','".$getData[37]."','".$getData[38]."','".$getData[39]."',
'".$getData[40]."', '".$getData[41]."','".$getData[42]."','".$getData[43]."','".$getData[44]."',
'".$getData[45]."', '".$getData[46]."','".$getData[47]."','".$getData[48]."','".$getData[49]."',
'".$getData[50]."', '".$getData[51]."','".$getData[52]."','".$getData[53]."','".$getData[54]."',
'".$getData[55]."', '".$getData[56]."','".$getData[57]."')";
}
$sql = "INSERT INTO machine (PresetNumber, Dates, Starts, Stops, ProductCode, ProductName, Proper, TargetWeight1, Totals, Mean, StandardD, Maxs, Mins,
ProductRange, Under, Over, OverScale, ReCheckCnt, TotalNegErr, Preset, TargetWeight2, BagLength, BagWidth, StartIPS, StopIPS, TotalTime, PlannedTime, ITPSDownTime,
ITPSOff, LowProductTime, DownStreamDownTime, OperatingTime,FullProductTime,GoodBagMakingTime, NetOperatingTime, FacultyBagMakingTime, PlannedShutdown, Speed,
ITPSOEE, SystemAvalability, WeigherEfficiency, BagMakerEfficiency, WeightLossRatio, ProductWaste, InputProduct, OutputProduct, AverageWeight,
StandardDeviation, CombinationCount, FilledBags, GoodBags, GoodProductBags, FilmWaste, InputFilm, OutputFilm, FilmWasteUpstream, FilmWasteMiddle, FilmWasteDownStream)
VALUES " . implode(',',$values);
//fclose($csvFile);
if ($link->query($sql) === TRUE)
{
echo "File(s) uploaded successfully!";
}
else {
echo "Error: " . $sql . "<br>" . $link->error;
}
}
''''
My CSV File is
5,2022/05/17,16:22,11:21,AJ,,112965,39.0 g,4485.5 kg,39.707 g,0.495 g,42.0 g,39.0 g,3.0 g,1035,2218,451,58,0 g,5,39.0g,1.92inch,1.27inch,2022.5.19. 09:52,2022.5.19. 11:01,68min34sec,68min34sec,7min25sec,4min30sec,2min55sec,0min0sec,61min10sec,0min0sec,0min0sec,0min0sec,61min9sec,0,0bpm,0.0%,89.1%,0%,0.0%,0.0%,0.2%,226.3kg,225.8kg,0.000g,0.000g,5811,0,0,0,0.0%,0.00feet,0.00feet,0.0,0.0,0.0
Yet for some reason when I import this CSV the line always breaks after the 40th column. Now If I import a CSV with some dummy data (sequential count from 1 to 58) this file will import fine. Im pretty new to this so I am not sure what I am missing.
Thanks Much

Compare for equality two cyrillic strings from sql database and .xls file in PHP

I am using phpoffice/phpspreadsheet to process .xlss the file.
As the columns order in the file may varry depending on the file sender I have a table in database, where I store the sender name (in cirilic) and the number of columns for the rest of data.
So, before processing the file I need to compare if the sender name from database is the same as the content of a field in the file to get the coresponded columns values and process the file only if name values match.
Despite the fact, that I am 100% sure they are the same, whatever comparison I try return false.
1. File processing
$allowedFileType = [
'application/vnd.ms-excel',
'text/xls',
'text/xlsx',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
];
$targetPath = './tmp/' . $_FILES['file']['name'];
move_uploaded_file($_FILES['file']['tmp_name'], $targetPath);
$filename = $_FILES['file']['name'];
$error = 0;
//Check if file is already uploaded
if (!empty($importFromFile->getImportedFileName($filename))) {
setEventMessages($langs->trans('FileExists'), null, 'errors');
$error++;
}
if (!$error) {
$Reader = new Xlsx();
$spreadSheet = $Reader->load($targetPath);
$excelSheet = $spreadSheet->getActiveSheet();
$spreadSheetAry = $excelSheet->toArray();
$sheetCount = count($spreadSheetAry);
foreach ($externalsales->getImportSettings() as $obj) {
$name1 = $obj->ref; //This is the name from the database
$name_row = $obj->distributor_name_row - 1;
$name_column = $obj->distributor_name_column - 1;
$name2 = $spreadSheetAry[$name_row][$name_column]; //this is the name from the file
//At this point, I need to compare returned names from database to the name in the file
}
}
2. Compare
print $name1 . ' - ' . $name2;
//returns ДЕЛИВЪРИ ООД - ДЕЛИВЪРИ ООД
//You can see they are same
print strcasecmp($name1, $name2);
print strcasecmp(trim($name1), trim($name2));
print strcasecmp(mb_strtolower($name1), mb_strtolower($name2));
//all 3 return "176"
print strcmp($name1, $name2);
print strcmp(trim($name1), trim($name2));
print strcmp(mb_strtolower($name1), mb_strtolower($name2));
//all 3 return "1"
print strcoll($name1, $name2) . '<br>';
//returns "1"
$coll = collator_create( 'bg_BG' );
$res = collator_compare( $coll, $name1, $name2 );
print $res;
//returns "1"
For the test, I have inserted second record in the database with random name that I am not sure is in the files.
For the first 3 options, the return is 32,32,-176, for the second 3 is 1,1,-1, 1 for strcoll and -1 for the collator.
Any help appreciated.
To check what was causing the error, I've used bin2hex() for both values. The result showed that there were some white spaces (I presume the 20 stand for space as %20 in html) in the string coming from the .xls file.
The output was:
print bin2hex($name1)
//d094d095d09bd098d092d0aad0a0d09820d09ed09ed094
print bin2hex($name1)
//d094d095d09bd098d092d0aad0a0d0982020d09ed09ed0942020
So when I strip those white spaces with str_replace(' ', '', $name1); the if condition if ($name1 === $name2) returns true, which is what I was looking for.
If anyone can explain the reasons for this difference better than me feel free to reply.

Trouble inserting data from csv into mysql database with unknown number of columns

I'm having this very annoying problem for couple of days already, and I did research and everything, but it seems to be bigger than my programming skills and knowledge.
I have a situation where user can define custom columns in tables in my database, and now I need to import CSV files into that user's custom tables. Since I recently found out that tables need to be "dynamic" this is how I handled importing before:
$file = $_FILES['file']['tmp_name'];
$handle = fopen($file, "r");
$name = $_FILES['file']['name'];
if (strrpos($name, '.csv', -4)) {//handling the csv file
do {
if ($data[0]) {
$mysqli->query("INSERT INTO `test` (`name`, `surname`, `email`) VALUES
(
'" . addslashes($data[0]) . "',
'" . addslashes($data[1]) . "',
'" . addslashes($data[2]) . "'
)
");
}
} while ($data = fgetcsv($handle, 1000, ",", "'"));
And that worked perfectly with static tables. But since I dont't know how many columns table will have, I tried something like this:
Building query method
if (strrpos($name, '.csv', -4)) {//ubacije vrijednosti csv fajla u bazu
do {
if ($data[0]) {
$query = "INSERT INTO $tabela (";
$last = end($anotherArray);
foreach ($anotherArray as $something) {//$anotherArray contains names of fields in user's custom table
if ($something != $last) {
$query .= "" . $something . ",";
} else {
$query .= "" . $something . ")";
}
}
$query .= "VALUES (";
foreach($data as $val){
$query .= "'$val',";
}
}while ($data = fgetcsv($handle, 1000, ",", "'"));
$query=rtrim($query,',');
$query.=")";
//var_dump($query);
$rez=$mysqli->query($query);
//var_dump($rez);
But problem with this code is if csv file contains for example 2 or more colums like so:
everything becomes part of that VALUES part of query. So query looks like this: "INSERT INTO tabela12312334 (user_facebook_id,ime,prezime) VALUES('123123123','Ognjen','Babic','123123123','Neven',Babic)" and of course number of fields isn't same as number of values.
Please help me to solve this, I'm desperate.
Try this
LOAD DATA LOCAL INFILE
'c:/path-to-csv-file/your-file.csv'
INTO TABLE your_awesome_table
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS
(field_1,field_2 , field_3);
NB: the first row as the title for your fields, you might have to include a header in your CSV file

Export to CSV not same as table PHP

I am trying to download table data into a CSV format. The data in one of the fields contains ",".
Eg: Doe, John
When I download the csv file, the data after comma is shifted to next column. But I want the entire data i.e including comma in same column.
The Code I used as follows:
<?php
include('dbconfig.php');
//header to give the order to the browser
header('Content-Type: text/csv');
header('Content-Disposition: attachment;filename=download.csv');
//select table to export the data
$sql ="SELECT * FROM tablename";
$select_table=mysqli_query($db, $sql);
$rows = mysqli_fetch_assoc($select_table);
if ($rows)
{
getcsv(array_keys($rows));
}
while($rows)
{
getcsv($rows);
$rows = mysqli_fetch_assoc($select_table);
}
// get total number of fields present in the database
function getcsv($no_of_field_names)
{
$separate = '';
// do the action for all field names as field name
foreach ($no_of_field_names as $field_name)
{
if (preg_match('/\\r|\\n|,|"/', $field_name))
{
$field_name = '' . str_replace('<em>', '', $field_name) . '';
}
echo $separate . $field_name;
//sepearte with the comma
$separate = ',';
}
//make new row and line
echo "\r\n";
}
?>
Can someone help me get through this issue.
Thanks
Make sure you escape the ,. Typically values that contain sensitive characters (such as , and \n) are surrounded in ".
So your output can be:
"Doe, John",52,New York
You can either write your own escape function or use PHPs fputcsv. It writes to a file handler that's a bit inconvenient but you can make it stdout.
$handle = fopen("php://stdout");
fputcsv($handle, array("Doe, John", 52, "New York"));

PHP Zip Code Losing Leading Zero

I am storing zip codes in a MySQL database as varchar(10). For some reason storing it in one table is not working like the other one. The only difference between the fields is that one is varchar(10) Nullable, and one is varchar(10). The Nullable column is saving the zip code without a leading zero so '05415' becomes 5415. This is working in the other table just fine. I think they are being stored on the same page, but I can't seem to find the problem. I'm not very good with PHP, so I would really appreciate some help here.
This is the function for registration on the site....the registration table in the db is saving the zip code with the leading 0, so I assume that this works.
$Zip = strip_tags(trim($_POST['MembersZip']));
if (strlen($Zip = trim($Zip)) == 0) {
$isError = true;
print "<script>$('#MembersZip').addClass('error');</script>";
print '<div class="errors">Please enter zip / postal code</div>';
}
if (strlen($Zip = trim($Zip)) < 5) {
$isError = true;
print "<script>$('#MembersZip').addClass('error');</script>";
print '<div class="errors">Zip code must be at least 5 digits</div>';
}
$sql = "INSERT INTO tbl_ecommerce_addresses (
ead_postal_code
) VALUES (
'" . addslashes($Zip) . "'
)";
This is what the process looks like for the orders. This is the table where the leading zero gets deleted before it gets inserted.
$fieldName = "BillingZip";
$fieldValue = strip_tags($_POST[$fieldName]);
if (!$fieldValue || strlen($fieldValue = trim($fieldValue)) == 0) {
$isError = true;
print "<script>$('#{$fieldName}').addClass('error');</script>";
print '<div class="errors">Please enter billing zip / postal code</div>';
} else {
$this->fields[$fieldName] = $fieldValue;
$this->record->eod_billing_postal_code = $fieldValue;
}
$Zip = $this->record->eod_billing_postal_code;
if (strlen($Zip = trim($Zip)) < 5) {
$isError = true;
print "<script>$('#BillingZip').addClass('error');</script>";
print '<div class="errors">Billing Zip Code must be at least 5 digits</div>';
}
It looks like this line
$newId = $this->record->insert();
is doing the insert, but when I do a var_dump of $this->record, the zip code still shows the leading 0. The only other thing I can think of is that the payment gateway is changing it somehow.
$paymentType = urlencode("Authorization"); // 'Sale' or 'Authorization'
$firstName = urlencode($this->fields["BillingFirst"]);
$lastName = urlencode($this->fields["BillingLast"]);
$creditCardType = urlencode($this->fields["CardType"]);
$creditCardNumber = urlencode($this->fields["CardNumber"]);
$padDateMonth = urlencode(str_pad($this->fields["CardMonth"], 2, '0', STR_PAD_LEFT));
$expDateYear = urlencode($this->fields["CardYear"]);
$cvv2Number = urlencode($this->fields["CardCode"]);
$address1 = trim(urlencode($this->fields["BillingAddress"]));
$address2 = urlencode($this->fields["BillingAddress2"]);
$city = urlencode($this->fields["BillingCity"]);
$state = urlencode($this->fields["BillingState"]);
$zip = urlencode($this->fields["BillingZip"]);
$country = urlencode($CountryCode); // US or other valid country code
$amount = urlencode($this->fields["PurchasedTotal"]);
$currencyID = urlencode($this->siteConfig->cy_code);
$ipAddress = $main->getIP();
$invoice = substr($this->fields["CardNumber"],-4,4) . substr($this->fields["BillingZip"],0,4) . substr($this->fields["PurchasedTotal"],0,2);
$nvpStr = "&PAYMENTACTION=$paymentType&IPADDRESS=$ipAddress&AMT=$amount&CREDITCARDTYPE=$creditCardType&ACCT=$creditCardNumber".
"&EXPDATE=$padDateMonth$expDateYear&CVV2=$cvv2Number&INVNUM=$invoice&FIRSTNAME=$firstName&LASTNAME=$lastName".
"&STREET=$address1&CITY=$city&STATE=$state&ZIP=$zip&COUNTRYCODE=$country&CURRENCYCODE=USD";
To get the zip code to display correctly, I updated the code with this, and the 0 showed up:
$zip = str_pad($order->eod_shipping_postal_code, 5, '0', STR_PAD_LEFT);
If I had a guess I would assume that somewhere along the way your variable is being stored as an integer, and if that happens then you would definitely lose that leading '0'. A few options to look at could be looking where the variable is stored and making sure it is stored as a string.
Alternatively, you can always make sure it has 5 numbers in php by using this:
str_pad($zip, 5, '0', STR_PAD_LEFT)
See this: http://www.php.net/str_pad
(Though I would advise that you find where it is being stored as a number over 'faking it' in php. but if you can't find it, this would work)
The data type in the database should be char(5) for the zip-code.

Categories