how to handle duplicate records in SQL? - php

I am uploading a file to mysql database. Now the file contains records of login and logout of users. Below is its structure.
I am using PHP codeigniter to upload that file and insert its data into SQL.
Here date_data is Defined as UNIQUE So that i dont get any duplicate records for same day as it contains information of daily user's login and logout data.
Now in a case where i have uploaded a data of 1st Nov to 10th December. and then again i upload data from 1st December to 1St January i will get an error because it will give error for the duplicate data from 1st Dec and other consecutive days. Is it possible that i can skip the duplicate data and insert the remaining unique data??
As for my current code it stops the execution when it finds duplicate data. i want to insert only that data which is unique.
Below is my code to insert into SQL table:
Controller
public function upload()
{
$file = rand(1000, 100000) . "-" . $_FILES['file']['name'];
$file_loc = $_FILES['file']['tmp_name'];
$file_size = $_FILES['file']['size'];
$file_type = $_FILES['file']['type'];
$folder = "uploads/";
$location = $_FILES['file'];
$new_size = $file_size / 1024; // new file size in KB
$new_file_name = strtolower($file);
$final_file = str_replace(' ', '-', $new_file_name); // make file name in lower case
if (move_uploaded_file($file_loc, $folder . $final_file))
{
$handle = fopen($folder.$final_file, "r") or die("file cannot open");
if ($handle) {
while (($line = fgets($handle)) !== false)
{
$lineArr = explode("\t", "$line");
$result = $this->attendance_m->insert_file_content($lineArr) ;
}
if (fclose($handle)) {
$this->alert('successfully uploaded', 'admin/attendance.php?success');
redirect('admin/attendance');
}
}
else{
echo "file cannot open";
}
}
}
The Model:
public function insert_file_content($lineArr)
{
$data = array(
'emp_id' => $lineArr[0],
'date_data' => $lineArr[1],
'abc' => $lineArr[2],
'def' => $lineArr[3],
'entry' => $lineArr[4],
'ghi' => $lineArr[5],
);
$this->db->insert('daily_data2', $data);
}

To ignore a duplicate record on insert
$data = array(
'emp_id' => $lineArr[0],
'date_data' => $lineArr[1],
'abc' => $lineArr[2],
'def' => $lineArr[3],
'entry' => $lineArr[4],
'ghi' => $lineArr[5],
);
$sql = "INSERT IGNORE INTO `daily_data2`
(`emp_id`,`date_data`,`abc`,`def`,`entry`,`ghi`)
VALUES
(?,?,?,?,?,?)";
$this->db->query($sql, $data);
You could also try out this way
$result = $this->db->get_where('daily_data2', array('date_data' => $data['date_data'));
if(count( $result->result_array() ) < 1)
{
//insert a new record
}

Related

How to inspect empty rows in uploaded csv

Here i have a csv file which have contains numerous contacts rows, and these rows ae saved to my database table. Now i just want to inspect empty rows from uploaded csv by customer.
Here is an example csv with some empty rows
In this above csv, have 3rd and 6th rows are empty. so want to inspect these empty row number and discard csv with error.
Here is my csv code
$filename = $_FILES["csv_file"]["tmp_name"];
if ($_FILES["csv_file"]["size"] > 0) {
$file = fopen($filename, "r");
$importdata = fgetcsv($file, 10000, ",");
$counter = 1;
while (!feof($file)) {
if ($counter > 1) {
$alldata[] = fgetcsv($file);
}
$counter++;
}
fclose($file);
$csvfieldcounter = 1;
foreach ($alldata as $importdata) {
$userdata = $this->session->userdata();
$userId = $userdata['id'];
$status = 'Y';
if ($importdata[4] == 'Disable' || $importdata[4] == 'disable')
$status = 'N';
else if ($importdata[4] == 'Enable' || $importdata[4] == 'enable')
$status = 'Y';
$data = array(
'customer_name' => $importdata[0],
'customer_email' => $importdata[1],
'customer_mobile' => $importdata[2],
'birth_date' => $importdata[3],
'status' => $status,
'user_id' => $userId,
'cat_type' => $file_cat
);
if ($importdata[2]) {
$run = $this->db->insert('customer', $data);
$csvfieldcounter++;
$id = $this->db->insert_id();
}
}
$this->session->set_flashdata('csv_imported','Your CSV have been successfully imported.');
redirect('/customer', $csvfieldcounter);
}
I just want a little help for get that. your kind efforts would be appreciated Thanks :)
I suggest you to use below mentioned library. This will help you address above issue also it will decrease lines of code in your controller.
https://github.com/parsecsv/parsecsv-for-php
This will help you.
If you worried about how to use than check below mentioned code.
$this->load->library('Parsecsv');
$csv = new Parsecsv($file);
$users = $csv->data;
$noOfUsers = count($users);
foreach($users as $user):
if(!empty($user)):
// Write your code
endif;
endforeach;

When import CSV skip header or first row

I know this is duplicate question. But I have tried all the answers which I have found on the https://stackoverflow.com/ .
I think in my case I am inserting and updating data if same date match than record will update if not than it will insert.
Below is my file code:
<?php
if ( isset( $_POST['submit'] ) && $_POST['upload-csv'] == 'upload' ) {
$error = array();
$success = array();
$filename = $_FILES['file']['name'];
$filetype = wp_check_filetype( $filename );
if ( $filetype['ext'] == 'csv' && $filetype['type'] == 'text/csv' ) {
$handle = fopen( $_FILES['file']['tmp_name'], "r" );
$row = 0;
$skip_row_number = array("1");
while ( ($data = fgetcsv( $handle, 1000, "," )) !== FALSE ) {
$data = array_map("utf8_encode", $data);
if ($row > 0)
{
$table_name = $wpdb->prefix . 'prayer';
$ipquery = $wpdb->get_results("SELECT * FROM `$table_name` WHERE `date` = '".$data[0]."'");
$query_res = $wpdb->num_rows;
// Check if same date data
if($query_res >=1){
$updateQuery = "UPDATE `$table_name` SET
`date` = '".$data[0]."',
`first_start` = '".$data[1]."',
`first_end` = '".$data[2]."',
`second_start` = '".$data[3]."',
`second_end` = '".$data[4]."',
`third_start` = '".$data[5]."',
`third_end` = '".$data[6]."',
`forth_start` = '".$data[7]."',
`forth_end` = '".$data[8]."',
`five_start` = '".$data[9]."',
`five_end` = '".$data[10]."',
`done` = '".$data[10]."'
WHERE `$table_name`.`date` = '".$data[0]."';";
$up_res = $wpdb->query($updateQuery);
}else{
$query = "INSERT INTO $table_name (date, first_start, first_end, second_start,
second_end, third_start, third_end, forth_start, forth_end, five_start, five_end, done)
VALUES ('".$data[0]."','".$data[1]."','".$data[2]."','".$data[3]."','".$data[4]."','".$data[5]."','".$data[6]."','".$data[7]."','".$data[8]."','".$data[9]."','".$data[10]."','".$data[11]."')";
$insert_res = $wpdb->query($query);
}
}
$row++;
}
fclose( $handle );
$success[] = 'Import done.';
} else {
$error[] = 'Please upload CSV file only';
}
}
?>
I have tried the below answer for skip the header:
Skip the first line of a CSV file
Import CSV, exclude first row
skip first line of fgetcsv method in php
Help me sort out this issue.
ParseCSV is latest and easy way to get data from CSV and you can get control of data from CSV easily.
in which you have to add library file as per proper path
e.g. require_once 'parsecsv.lib.php';
After then it return title and data seperately.
$filename = 'abc.csv'; // path of CSV file or after upload pass temp path of file
$csv = new parseCSV();
$csv->auto($filename);
foreach ($csv->titles as $value):
$getcsvtitle[] = // get header in variable
endforeach;
foreach ($csv->data as $key => $row):
//$getdataasperrow = // get data row wise.
endforeach;
ParseCSV return data in array format after just adding library, so you can easily separate header and other data, and compatible to new line and special character as well as i have been always using it as well.
Please refer below link for further detail as well.
ParseCSV GitHub

How to upload multiple image with rename in php and insert database?

Hi how to upload multiple image in php with rename and insert databse?
my code is below but not rename and insert 1 rows in datase.
$uploads_dir = 'uploaded/up/';
foreach ($_FILES["layout_plan_no_of_images"]["error"] as $i => $k) {
if ($k == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["layout_plan_no_of_images"]["tmp_name"][$i];
$name = $_FILES["layout_plan_no_of_images"]["name"][$i];
move_uploaded_file($tmp_name, "$uploads_dir/$name");
}
$sql="INSERT INTO projects (layout_plan_no_of_images)VALUES(':layout_plan_no_of_images')";
$sql_result = $db->queryPrepared($sql, array(
':layout_plan_no_of_images' => $_FILES['layout_plan_no_of_images']['name']
));
Hi try to below code may be help for with rename
foreach($_FILES["layout_plan_no_of_images"]['name'] as $key=>$tmp_name){
$file_name=$_FILES["layout_plan_no_of_images"]["name"][$key];
$file_tmp=$_FILES["layout_plan_no_of_images"]["tmp_name"][$key];
$ext=pathinfo($file_name,PATHINFO_EXTENSION);
$filename=basename($file_name,$ext);
$newFileName=(string)$filename.time().".".$ext;
move_uploaded_file($file_tmp=$_FILES["layout_plan_no_of_images"]["tmp_name"][$key],"uploaded/".$newFileName);
$concateFiles .= $comma.$newFileName;
$comma = ',';
}
$sql="INSERT INTO projects (`layout_plan_no_of_images`, `pid`)VALUES($concateFiles)";
$sql_result = $db->queryPrepared($sql, array(
':layout_plan_no_of_images' => $concateFiles,
));

SQL query via Medoo taking too long to finish

My script allows you to upload a zip file and then inserts the individual file information into a database using Medoo, after extracting them. My script takes way too long to finish, even after I've set the max execution time to 5 minutes I get the notice saying the max execution time has been exceeded.
There are only about 650 files in the zips that will be upload-able and the script only manages to extract and insert about half in to the DB before it times out. Is this query more memory intensive than I realize?
EDIT: I should mention that it only hangs with zip files with a larger amount of files, like the 650 figure I mentioned above, the program seems to execute fine with a small number of files.
Code (Offending query near bottom of script):
<?php
ini_set('max_execution_time', 300);
require_once 'vendor/medoo.min.php';
require_once 'scripts/class.file.php';
$database = new medoo([
'database_type' => 'mysql',
'database_name' => 'invoice_files',
'server' => 'localhost',
'username' => 'root',
'password' => 'pass',
'charset' => 'utf8'
]);
$file = new File();
$file->set("filename", $_FILES['uploaded-file']['name']);
$file->set("category", "Invoice Statement");
$file->set("file_temp_path", $_FILES["uploaded-file"]["tmp_name"]);
$file->set("uploadedFilePath", $file->path("uploads/") . basename($file->get("filename")));
$counter = 0;
if($file->getPathInfo()["extension"] == "zip")
{
$zip = new ZipArchive;
$zipFile = $file;
echo "Source: " . $zipFile->get("file_temp_path") . "<br>";
if($zip->open($zipFile->get("file_temp_path")))
{
for($i = 0; $i < $zip->numFiles; $i++)
{
$zipName = $zip->getNameIndex($i);
$zipFile->set("uploadedFilePath", $file->path("uploads/"));
$zipFile->set("filename", $zipName);
for($x = 0; $x < $zip->numFiles; $x++)
{
$extension = $zip->getNameIndex($x);
$pathInfo = pathinfo($extension);
if($pathInfo["extension"] != "pdf" && $pathInfo["extension"] != "xls")
{
echo "Non PDF or excel sheet detected<br>";
return false;
}
if($pathInfo["extension"] == "xls")
{
$excelFile = $extension;
$excelFlag = true;
}
else
{
$excelFlag = false;
}
}
if($zip->extractTo($zipFile->get("uploadedFilePath")))
{
$pathInfo = pathinfo($zipName);
$database->insert('files',[
'name' => $zipFile->get("filename"),
'category' => $zipFile->get("category"),
'date' => $zipFile->setDate(),
'extension' => $pathInfo["extension"],
'size' => filesize($zipFile->get("uploadedFilePath") . $zipFile->get("filename")) / 1000 . 'KB',
'path' => $zipFile->get("uploadedFilePath") . $zipFile->get("filename")
]);
}
else
{
echo "Failure to extract<br>";
}
}
}
if($excelFlag)
{
$url = "insert-new-clients.php?excelfile=" . urlencode($excelFile);
//header("location:$url");
}
}
else
{
echo "File not in zip format";
return false;
}
?>
I figured it out. I realized that $zip->extractTo($zipFile->get("uploadedFilePath")) was attempting to extract 650 files for each iteration of the loop, which is 650 times.
I just moved the extraction code outside the loop and the script executed quickly.

How to insert "Null" value in MySQL Database Cell if no Files are added?

I have a form that sends input data to corresponding field on MYSQL database.Right now I have it setup where any files that are uploaded are packaged in a zip and placed in the "uploads" folder while it sends to the database the file name/location. How do I make it where when the user uploads no files it sends to the database as NULL result in the corresponding database "file" cell and no zip file is sent to the "uploads" folder ?
**UPDATE: OK I started with suggested answer but don't get "NULL" when no file is uploaded just the usual that I have written.I tried an if/else statement and it's the same. What am i doing wrong?
This what the array looks like when no file is uploaded: Array (
[name] => Array ( [0] => ) [type] => Array ( [0] => ) [tmp_name] =>
Array ( [0] => ) [error] => Array ( [0] => 4 ) [size] => Array ( [0]
=> 0 ) )
The error field contains 4. i think this might the reason why its not working.I don't understand why this error field has this number. Any suggestions please?
PHP
<?php
$project = $_POST['project'];
$assignto = $_POST['assignto'];
$asdate = $_POST['asdate'];
$chdate = $_POST['chdate'];
$ddate = $_POST['ddate'];
$notes = $_POST['notes'];
$asdate=date('Y-m-d', strtotime($asdate));
$chdate=date('Y-m-d', strtotime($chdate));
$ddate=date('Y-m-d', strtotime($ddate));
$timestamp = time();
if (isset ($_POST['submit']))
{
$filesArray= $_FILES["files"];
for ($num=0; $num<count($filesArray["name"]);$num++)
{
$fileName = $filesArray["name"][$num];
$tempName= $filesArray["tmp_name"][$num];
move_uploaded_file($tempName,"tmp/".$fileName);
}
$archiveName= $timestamp.".zip";
$filesArrayNames= $_FILES["files"]["name"];
$zipsDir= scandir ("uploads/");
$error = false;
foreach($zipsDir as $zipDirfile)
{
if($zipDirfile == $archiveName)
{
$error= true ;
break;
}
}
if ($error== false)
{
$tmpDir = scandir ("tmp/");
$zip = new ZipArchive;
$zip->open("uploads/".$archiveName, ZipArchive::CREATE);
for ($num =0; $num<count($filesArray["name"]);$num++)
{
$fileName = $filesArray["name"][$num];
foreach($tmpDir as $tmpDirfile)
{
if($tmpDirfile == $fileName)
{
$zip->addFile("tmp/".$fileName);
echo " Adding: ".$fileName."<br/>";
}
}
}
$zip->close();
for ($num=0; $num<count($filesArray["name"]);$num++)
{
$fileName = $filesArray["name"][$num];
foreach($tmpDir as $tmpDirFile)
{
if($tmpDirfile == $fileName)
{
unlink("tmp/".$fileName);
}
}
}
}
else
{
echo "Name already exists";
}
} if (!empty($filesArray)) {
$filepath = "NULL";
}else
{$filepath = addslashes("https://docs.google.com/viewer?url=www.art.com/uploads/".$archiveName.""); }
print_r($filepath);
mysql_connect("tre.com","amadast","ufco1954") or die ('Error:' .mysql_error());
//database connection
mysql_select_db("mediamanagement");
$sql = "INSERT INTO demo (`name`, `id_continent`, `lastvisit`, `cdate`, `ddate`, `file`,`notes`)
VALUES ('".$project."', '".$assignto."','".$asdate."','".$chdate."','".$ddate."','".$filepath."','".$notes."')";
mysql_query($sql);
header('Location: edit-projects.html');
?>
Where you create the $filepath variable, simply check whether you have files uploaded, and if you don't use "NULL" as the content.
For example:
$filepath = addslashes("https://docs.google.com/viewer?url=www.amada-stage.com/uploads/".$archiveName."");
if (empty($filesArray)) {
$filepath = "NULL";
}
You can do a similar thing to prevent the upload occuring:
Change
if ($error== false)
to
if ($error == false && !empty($filesArray))
BTW: I hope those aren't real database credentials in your mysql_connect line!

Categories