Large size CSV file upload - php

I want to know how to upload and retreive data from a large CSV or XLS file using PHP. Are there any available PHP libraries?
I tried using the code mentioned below but it is taking a large amount of time to upload. Is the only way it can be done by using cron, or is there another method?
$file=fopen(base_url()."/xml/sample.csv","r");
while(! feof($file))
{
pr(fgetcsv($file));
}
fclose($file);

One way of running the script this seems to be the best way
$this->db->query("LOAD DATA LOCAL INFILE '".base_url()."/xml/sample.csv'
REPLACE INTO TABLE TABLE_NAME FIELDS TERMINATED BY ','
ENCLOSED BY '\"' LINES TERMINATED BY '\r\n' IGNORE 1 LINES");
The alternate way of running the script is
<?php
$row = 1;
if (($handle = fopen("ptt.csv", "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
if($row == 1){ $row++; continue; }
$num = count($data);
$row++;
for ($c=0; $c < $num; $c++) {
if(strpos($data[$c], 'Finished') !== false) {
$c++;
echo "<TR> <TD nowrap>" . $data[$c] . "</ TD>"; }
Else{
echo "<TD nowrap>" . $data[$c] . "</ TD>";
}
}
}
fclose($handle);
}
?>

<?php
ini_set('max_execution_time',0);
$no = 0;
//validate whether uploaded file is a csv file
$csvMimes = array('text/x-comma-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain');
//$csvMimes = array('application/x-csv', 'text/x-csv', 'text/csv', 'application/csv');
if (!empty($_FILES['file']['name']) && in_array($_FILES['file']['type'], $csvMimes)) {
if (is_uploaded_file($_FILES['file']['tmp_name'])) {
//open uploaded csv file with read only mode
$csvFile = fopen($_FILES['file']['tmp_name'], 'r');
//skip first line
fgetcsv($csvFile);
//parse data from csv file line by line
while (($line = fgetcsv($csvFile)) !== FALSE) {
if ($line[0] != '') {
//check whether member already exists in database with same email
$sql = "SELECT * FROM `parts_master` WHERE PART_NUM = '$line[1]'";
$res = mysqli_query($conn, $sql);
$num = mysqli_num_rows($res);
if ($num != 0) {
$row = mysqli_fetch_array($res);
$row_id = $row['id'];
$sql2 = "UPDATE `parts_master` SET ROOT_PART_NUM = '$line[2]', PART_DESC = '$line[3]', MRP = '$line[4]', ISSUE_INDICATOR = '$line[5]', TAX_DESC = '$line[6]', HS_CODE = '$line[7]' WHERE id = $row_id";
} else {
$sql2 = "INSERT INTO `parts_master` (id, PART_NUM, ROOT_PART_NUM, PART_DESC, MRP, ISSUE_INDICATOR, TAX_DESC, HS_CODE, isdeleted)
VALUES (NULL ,'$line[1]','$line[2]','$line[3]','$line[4]','$line[5]','$line[6]','$line[7]',0)";
}
$res2 = mysqli_query($conn, $sql2);
if (!$res2) {
$no++;
}
}
}
//close opened csv file
fclose($csvFile);
}
} else {
$no++;
}
if ($no != 0) {
echo 'error';
} else {
echo 'success';
}
?>

Related

I can't work with SQL values inserted by PHP

i have inserted SQL values on tables with PHP that before has readed a .txt file.
The thing is that I can not work with those values.
PHP reads on the file .txt '8,00' and inserts this value correctly on the data base but if i do a strlen() this returns a 6 and it has tu return a 4.
TXT: the text on .txt
if (in_array($fileActualExt, $allowed)){
if ($fileError == 0){
if ($fileSize > 5000){
echo "Tu archivo es muy grande!";
} else{
$fileNameNew = uniqid('', true).".".$fileActualExt;
$fileDestination = 'uploads/'.$fileNameNew;
move_uploaded_file($fileTmpName, $fileDestination);
$file = fopen("uploads/$fileNameNew","r");
if ($file) {
if (($line = fgets($file)) !== false) {
$ram = $line;
}
if (($line = fgets($file)) !== false) {
$cpu = $line;
}
if (($line = fgets($file)) !== false) {
$so = $line;
}
if (($line = fgets($file)) !== false) {
$gpu = $line;
}
if ($i=1) {
$sql = "INSERT INTO comparar (ram,cpu,gpu,so) VALUES ('$ram','$cpu','$gpu','$so')";
$conn->query($sql);
}
session_start();
$session_array2 = array($ram,$cpu,$gpu,$so);
$_SESSION['nombre2'] = $session_array2;
fclose($file);
Thanks for the clarification above. Seems that when you are extracting the text from the txt file you are also extracting the new line character \n.
Clean the value you want to insert with something like:
strlen(str_replace(array("\n", "\r\n", "\r"), '', $ram));
This should now return the correct length for the value are trying to work with.

PHP read lines not working on some computers but works on most

So im reading an CSV file and splitting it apart to get email,name,last name, however this outputs differently on different computers in my platform, let's say when I upload the same file it reads 38 lines and save them. However in 2 specific computers it reads only 1.
Before I was reading only TEMP file, but now im saving it to a directory and reading from there, however the problem is still here, I compared the file size and is the same even the content.
Is this a PHP bug ?
<?php
global $user;
if(isset($_POST['submit'])) {
if ($_FILES['file']['tmp_name']) {
$nome = $_POST['nome'];
$file = $_FILES['file']['tmp_name'];
$user->criarLista($nome, $file);
} else {
$user->mensagem(1, "Não existe nenhum ficheiro");
}
}
?>
public function criarLista($nome,$file){
// ADDED TO SAVE THE FILE IN THE SYSTEM AND READ FROM IT
if(file_exists("uploads/lista.txt")){ unlink("uploads/lista.txt"); }
move_uploaded_file($file, "uploads/lista.txt");
$file = file_get_contents("uploads/lista.txt");
$user = $this->user;
$get = $this->connect->query("SELECT * FROM users WHERE email = '$user'");
$fetch = $get->fetch_array(MYSQLI_ASSOC);
$user_id = $fetch['id'];
if($insert = $this->connect->prepare("INSERT INTO lista(user_id,nome) VALUES(?,?)")){
$insert->bind_param("is", $user_id,$nome);
$insert->execute();
$list_id = $insert->insert_id;
$file = preg_replace('#\\x1b[[][^A-Za-z]*[A-Za-z]#', '', $file);
$file = strip_tags($file);
$lines = file("uploads/lista.txt");
$emails = array();
$fnames = array();
$lnames = array();
$linha = 0;
foreach($lines as $line) {
if($linha == 0){
}else{
echo $Linha."</br>";
if (strpos($line, ',') !== false) {
$arr = explode(",", $line);
// Email \ FNAME | LAST
$emailx = trim($arr[0]);
$emailx = trim(preg_replace("/[\\n\\r]+/", "", $emailx));
array_push($emails,$emailx);
if(isset($arr[1])){
$fname = trim($arr[1]);
$fname = str_replace('"','',$fname);
array_push($fnames,$fname);
}
if(isset($arr[2])){
$lname = trim($arr[2]);
array_push($lnames,$lname);
}
}else{
array_push($emails,trim($line));
}
}
$linha++;
}
array_map('trim', $emails);
array_map('trim', $fnames);
array_map('trim', $lnames);
$emails = implode(",",$emails);
$fnames = implode(",",$fnames);
$lnames = implode(",",$lnames);
if($insert_list = $this->connect->prepare("INSERT INTO listas(lista_id,email,primeiro_nome,ultimo_nome) VALUES(?,?,?,?)")){
$insert_list->bind_param("isss", $list_id,$emails,$fnames,$lnames);
$insert_list->execute();
$this->mensagem(2,"Lista adicionada com sucesso");
}else{
echo
'
<div class="alert alert-danger">
Erro: '.$this->connect->error.'
</div>
';
}
}else{
echo
'
<div class="alert alert-danger">
Erro: '.$this->connect->error.'
</div>
';
}
}
FIXED this adding this on top of the function :
ini_set('auto_detect_line_endings',true);
I am not sure this is an 'answer' to what is going on, though it is what I had to do to fix an issue with a Mac user sending files.
What I found was that, every time he did an upload, it would send a .zip file, not just the file (like the PCs did). I did not have other Mac users to test against, so, again, I can't say this is exactly the issue you have, but I trust it will at least help in your search.
Note that I had to chop a lot of code out of this (where I was doing various other functions with the database, etc.), so this may not run directly, but I think I closed all the 'ifs' and such - or you can figure it out (if not, let me know and I'll go through it again).
Hope this helps!
$save_file = basename($_FILES["fileToUpload"]["name"]);
$zipfile='maps/'.$save_file; // location of a temp location (stops double uploads)
$alert_upload_file_exists = "Uploaded file exists!";
$alert_upload_successful = "UPLOAD SUCCESSFUL";
$action_failed_text = "Action FAILED";
if(file_exists($zipfile) && (empty($_GET['overwrite']) || $_GET['overwrite'] == 'false'))
die($alert_upload_file_exists);
if (move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], $zipfile))
{
// I found this mac to be sending a .zip file, not a standard one..... :(
$uploadOk = 0;
$mac_file = 0;
if($basename = basename($_FILES["fileToUpload"]["name"],".zip"))
{
$zip = new ZipArchive;
if($zip->open($zipfile) === true){
// echo "basename is $basename<BR>";
for($i = 0; $i < $zip->numFiles; $i++) {
$filename = $zip->getNameIndex($i);
$fileinfo = pathinfo($filename);
// look for the file we really want (in our case, any sort of img file)
if($fileinfo['basename'] == $basename . '.png' || $fileinfo['basename'] == $basename . '.jpg' || $fileinfo['basename'] == $basename . '.gif') {
$imgfile = $_GET['loc_data_id'].".".$fileinfo['extension'];
$files[]=$fileinfo['basename'];
// echo "file added to the list <BR>";
}
// echo "filename is $filename, basename is ->".$fileinfo['basename']."<- fileinfo = ";print_r($fileinfo);
// CHECK TO SEE IF THIS WAS THE 'WEIRD' MAC FILE
if($fileinfo['basename'] == "__MACOSX")
$mac_file = 1;
// echo "mac_file is $mac_file ";
}
if(($imglist = array_keys(array_flip(preg_grep('/^.*\.(jpg|jpeg|png|gif)$/i',$files))))
{
// echo "imglist = ";print_r($imglist);
// echo "files = ";print_r($files);
foreach($files as $key => $value)
{
if ($imglist[0]==$value) {$file = $imgfile;}
$upgrade += file_exists('maps/'.$file);
// echo "imgfile is $imgfile, file is $file upgrade is $upgrade and value is ".$basename."/".$value." ............";
// more 'FUNNY BUSINESS' to work the Mac file....
if($mac_file){
$extracted = $zip->extractTo('maps/',$basename."/".$value);
rename("maps/$basename/$value","maps/$file");
}
else {
$extracted = $zip->extractTo('maps/',$value);
rename("maps/$value","maps/$file");
}
}
// AND A BIT MORE.....
if($mac_file){
rmdir ("maps/$basename");
}
$zip->close();
$imgcount=0;$mapcount=0;$uploadOk=1;
$html = file_get_html('maps/'.$mapfile);
$imgck = strpos($html,'<img ');
if(($imgck===false) || $imgck<>0) {
$uploadOk += 2;
}
// echo "uploadOk is $uploadOk<br>";
if($uploadOk==1)
{
$mapname = pathinfo('maps/'.$mapfile);
// echo "mapfile is $mapfile, mapname = ";print_r($mapname);
}
}
else $uploadOk += 20;
}
}
if($uploadOk==1) echo basename($_FILES["fileToUpload"]["name"])." ".$alert_upload_successful;
else echo $action_failed_text . " ".$uploadOk;
// delete the original .zip file (and any that are in the 'maps/' folder)
array_map('unlink', glob("maps/*.zip"));
}
else
{
echo "Sorry, there was an error uploading your file.";
echo "temp name is " . $_FILES["fileToUpload"]["tmp_name"]. " save file is ". $save_file."<br>";
}

Import csv into database only take one row

i have this code but it only take the first row of my csv file ..I already search the internet but none make me understand since i am very new in php ..i m sorry if this question is a duplicate.
if(isset($_POST["Import"])){
echo $filename=$_FILES["file"]["tmp_name"];
if($_FILES["file"]["size"] > 0)
{
$file = fopen($filename, "r");
while (($getData = fgetcsv($file, 10000, ",")) !== FALSE)
{
$sql = "INSERT INTO book (book_id,total_book,price,title,author,surname,genre,location) values
('$getData[0]','$getData[1]','$getData[2]','$getData[3]','$getData[4]','$getData[5]','$getData[6]','$getData[7]')";
$result = mysqli_query($con, $sql);
var_dump($sql);die;
// var_dump(mysqli_error_list($con));
// exit();
if(!isset($result))
{
echo "<script type=\"text/javascript\">
alert(\"Invalid File:Please Upload CSV File.\");
window.location = \"bookList.php\"
</script>";
}
else {
echo "<script type=\"text/javascript\">
alert(\"CSV File has been successfully Imported.\");
window.location = \"bookList.php\"
</script>";
}
}
fclose($file);
}
}
You can try in my way i did this to process user attendance save in database.
here my code below i am giving upload to data save in server/db.
//after form post with file
if (isset($_POST["frmUplaod"])) {
extract($_POST);
$filename = basename($_FILES['attendance_file']['name']);
$targetfolder = 'Attendance/'. $filename .'';
if ($filename != "") {
move_uploaded_file($_FILES['attendance_file']['tmp_name'], $targetfolder);
chmod($targetfolder, 0777);
$msg = "Attendance file succesfully updated";
}
}
after that i process this csv file using this code :
function MakeID($id) {
$refine_id = "";
if (strlen($id) == "1") {
$refine_id = "SUL00" . $id;
} elseif (strlen($id) == "2") {
$refine_id = "SUL0" . $id;
} elseif (strlen($id) == "3") {
$refine_id = "SUL" . $id;
} else {
$refine_id = "SUL".$id;
}
return $refine_id;
}
//336668677
//Read directory
$FileArray = scandir("Attendance");
$i = 0;
$existsdate = array();
foreach ($FileArray as $f) {
$filename = "Attendance/" . $f;
$extensiondebug='';
if(!empty($f))
{
$splitex=explode(".",$f);
$extensiondebug=$splitex[1];
}
if ($extensiondebug == "csv") {
$row = 1;
if (($handle = fopen("Attendance/".$f, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
$row++;
$terminal_id=1;
$emp_code=MakeID($data['1']);
$pd=split('/',$data[0]);
#$raw_date=$pd[2]."-".$pd[1]."-".$pd[0];
$unixtime=strtotime($raw_date);
$date=date('Y-m-d',$unixtime);
//echo $date."<br>";
if($data['1']!="ID" && $date!="1970-01-01")
{
if($data['6']!="00:00" && $data['6']!="0:00")
{
//echo $data['6']."<br>";
//echo $date;
$time=date('g:i:s',strtotime($data['6']));
//exit();
$res = $con->existsByCondition("attendance_raw", " employee_id='$emp_code' AND date='$date' AND time='$time'");
if ($res <= 0) {
$array = array(
"machine_id" => $terminal_id,
"date" => $date,
"time" => $time,
"employee_id" => $emp_code,
"result" => "1"
);
$con->insert("attendance_raw", $array);
}
}
if($data['7']!="00:00" && $data['7']!="0:00")
{
$time2=date('g:i:s',strtotime($data['7']));
$res = $con->existsByCondition("attendance_raw", " employee_id='$emp_code' AND date='$date' AND time='$time2'");
if ($res <= 0) {
$array = array(
"machine_id" => $terminal_id,
"date" => $date,
"time" => $time2,
"employee_id" => $emp_code,
"result" => "1"
);
$con->insert("attendance_raw", $array);
}
}
}
//echo "<br />\n";
}
fclose($handle);
}
rename($filename, 'read/' . $filename);
echo "file moved to specified directory.";
}
}
I hope this will help you to complete your csv file process.
Thank you all for the help ..I already solve the problem ,the problem in my code is only the delimiter that i used ,i used a wrong delimiter

How to read Multiple CSV file data in php

I am trying to import 6 files which are in zip files. First I extract those files after that I want to get all the data in these files. But currently I am getting only the first file data. The script had not read the second file. I don't understand how to get rid from this problem.
Here is my code.
<?php
if ($_FILES) {
$filename = $_FILES["zip_file"]["name"];
$source = $_FILES["zip_file"]["tmp_name"];
$type = $_FILES["zip_file"]["type"];
$name = explode(".", $filename);
$accepted_types = array(
'application/zip',
'application/x-zip-compressed',
'multipart/x-zip',
'application/x-compressed'
);
foreach ($accepted_types as $mime_type) {
if ($mime_type == $type) {
$okay = true;
break;
}
}
$continue = strtolower($name[1]) == 'zip' ? true : false;
if (!$continue) {
$message = "The file you are trying to upload is not a .zip file. Please try again.";
}
$target_path = "zip/" . $filename;
if (move_uploaded_file($source, $target_path)) {
$zip = new ZipArchive();
$x = $zip->open($target_path);
$col = array();
if ($x === true) {
for ($x = 0; $x < $zip->numFiles; $x++) {
$csv = $zip->getNameIndex($x);
$zip->extractTo("zip/");
$csv_path = "zip/" . $csv;
if (($handle = fopen($csv_path, "r")) !== FALSE) {
fgetcsv($handle);
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
for ($c = 0; $c < $num; $c++) {
$col[$c] = $data[$c];
}
echo "<pre>";
print_r($col);
}
fclose($handle);
}
}
$zip->close();
unlink($target_path);
exit;
}
$message = "Your .zip file was uploaded and unpacked.";
} else {
$message = "There was a problem with the upload. Please try again.";
}
}
?>
Any help would be Highly appreciated.
Look at this part of your code...
<?php
// ...code...
$zip->extractTo("zip/");
$csv_path = "zip/" . $csv;
if (($handle = fopen($csv_path, "r")) !== FALSE) {
fgetcsv($handle);
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
// ...code...
?>
extractTo() extracts the files. There are six files, you said. Then you do fopen(), and you do it once. You want to do that fopen() on each of the files.
What you'll want is...
<?php
// ...code... (files are extracted at this point)
$files = files('zip/');
for($i = 0; i < count($files); $i++) {
$file = $files[$i];
// ...do csv stuff here for $file
}
// ...code...
?>

if(in_array) mime check always returns FALSE

Variables:
$csvFile = $_FILES['uploadfile']['tmp_name'];
$csvFile = $con->real_escape_string($csvFile);
$mimes = array('application/vnd.ms-excel','text/plain','text/csv','text/tsv','csv');
if statement:
if(in_array($csvFile, $mimes))
{
$file = fopen($csvFile, 'r');
$i = 0;
$row = 1;
while (($line = fgetcsv($file)) !== FALSE)
{
if($row == 1){ $row++; continue; }
$data_array[$i] = $line[0];
$data_array[$i] = mysqli_real_escape_string($con, trim($data_array[$i]));
$encrypted_numbers[$i] = encryption::encrypt($data_array[$i]);
$encrypted_numbers[$i] .= mysqli_real_escape_string($con, trim($line[1]));
$i++;
}
fclose($file);
}
else
{
die("Sorry, file type not allowed");
};
I've been trying stuff for 30 min, anyone know why I always get false even if the file is named csv.csv?
$_FILES['uploadfile']['tmp_name'];
you should be looking in 'type' not 'tmp_name'
$_FILES['uploadfile']['type'];
However, there is an SO discussion here about why a csv file can have the application/octet-stream mime-type. It suggests that you need to verify the file-type yourself, and not rely on ['type']. The best way would be to use fgetcsv() to try to parse it as csv. If this fails then assume it is not a csv.

Categories