Zipping and downloading multiple files from multiple columns in mysql database - php

I have simple script like add-to-cart where I can put multiple files for later downloading. When user click on add to cart I store the ID of the file in session and when he click download all based on ID's stored it lookup into database table and download the files.
All the files are stored in same folder and I keep the names in table. The problem that I faced is that in the table I have 3 columns which hold different files(items). This is what I have so far and is working for one column. Question is how to add other two columns?
$files = $_SESSION['itemid'];
$valid_files = array();
if(is_array($files)) {
foreach($files as $file) {
$sql = "SELECT * FROM document_upload WHERE upload_id = :id";
$result = $pdo->prepare($sql);
$result->bindParam(":id", $file);
$result->execute();
$resArray = $result->fetch();
if (file_exists($filePath . $resArray['upload_lesson_plan'])){
$valid_files[] = $resArray;
}
}
}
if(count($valid_files > 0)){
$zip = new ZipArchive();
$zip_name = "zipfile.zip";
if($zip->open($zip_name, ZIPARCHIVE::CREATE)!==TRUE){
$error .= "* Sorry ZIP creation failed at this time";
}
foreach($valid_files as $res){
$zip->addFile($filePath.$res['upload_lesson_plan']);
// columns that I want to add and take files from...
//$zip->addFile($filePath.$res['upload_worksheet']);
//$zip->addFile($filePath.$res['upload_materials']);
}
Those are both columns which I want to take files from
//$zip->addFile($filePath.$res['upload_worksheet']);
//$zip->addFile($filePath.$res['upload_materials']);
I have tried something like this but doesn't work.. just showing me blank page and doesn't download anything and no errors.
if (file_exists($filePath . $resArray['upload_lesson_plan'] || $filePath . $resArray['upload_worksheet'] || $filePath . $resArray['upload_materials']))
They are stored in columns and they are multiple files in same column comma separated.

Acording to what you said
They are stored in columns and they are multiple files in same column comma separated.
You can try this way. With explode them:
foreach($resArray as $col){
$items = explode(',', $col);
foreach ($items as $item) {
if (file_exists($filePath . trim($item))){
$valid_files[] = $filePath . trim($item);
}
}
And then call them like this
foreach($valid_files as $res){
$zip->addFile($res);
}

just
foreach(['upload_lesson_plan', 'upload_worksheet', 'upload_materials'] as $col){
if (file_exists($filePath . $resArray[$col])){
$valid_files[] = $resArray[$col];
}
}

Related

Renaming filenames and immediately reading files having issues in php

I have pdf files which are report cards of students.The report card names format is <student full name(which can have spaces)><space><studentID>.I need to download files.For this I have used the following code.
if(file_exists($folder_path.'/') && is_dir(folder_path)) {
$report_files = glob(folder_path.'/*'.'_*\.pdf' );
if(count($report_files)>0)
{
$result_data = '';
$result_data = rename_filenamespaces($report_files);
var_dump($result_data);//this shows the edited filename
foreach ($result_data as $file) {
if (strpos($file,$_GET['StudentID']) !== false) {
//code for showing the pdf docs to download
}
}
}
}
//function for renaming if filename has spaces
function rename_filenamespaces($location)
{
$new_location = $location;
foreach ($location as $file) {
//check file has spaces and filename has studentID
if((strpos($file," ")!==false)&& (strpos($file,$_GET['StudentID']) !== false))
{
$new_filename = str_replace(" ","-",$file);
rename($file,$new_filename);
$new_location = $new_filename;
}
}
return $new_location;
}
The variable $result_data gives me the filename without spaces,but the for each loop is showing Warning:Invalid argument supplied for foreach(). But the filename is changed in the server directory immediately after running the function. This warning shows only for first time. I am unable to solve this.
$new_location = $new_filename;
$new_location is a array
$new_filename is a string
You have to use $new_location[$index]
or try
foreach ($new_location as &$file) {
...
...
$file = $new_filename;

Compare document with database

on my server i have a folder, named: old_files
In that folder there are a couple of 100 documents.
I also have a database with an column named "filename" and a column named "transferFlag".
Now i want to read out the files in the Folder, compare the names of the files with the values in column "FILENAME" and is they match, update the column "transferFlag" to "NO" where the filename matches.
But i don't have a clue how to arrange this? Can somebody give me advise?
This is what i was thinking of:
$filename = 'http://www.mysite.com/old_files/';
$inhoud = file_get_contents($filename);
But how to get all the files in the folder and compare them one by one with the values in the DB?
Well, i now did this:
$dir = dirname(__FILE__)."/../files/oud/"; // de directory die hij uit moet lezen
if ($handle = #opendir($dir))
{
while (false !== ($file = #readdir($handle))) {
$bestand = $dir ."/". $file ;
$ext = pathinfo($bestand);
$sql_2 = "UPDATE documenten SET transfer_vlag = '' WHERE documentnaam = '".$file."'";
mysql_query($sql_2) or die(mysql_error());
}
#closedir($handle);
}
Only problem:
there are like 1000 files in the directory, so i get an time-out after a while.
What can i do?
Use glob for getting all the files from a directory..
foreach (glob("*.txt") as $filename) {
$inhoud = file_get_contents($filename);
}

Removing a file after sql execution in PHP

I am trying to read multiple .sql files and then execute them into the database. This works, although now I am in need of deleting the file after its been successfully been imported to the database.
How would I be able to accomplish this?
<?php
function scan_for_sql_files($path){
$itdir = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS),
\RecursiveIteratorIterator::SELF_FIRST,
\RecursiveIteratorIterator::CATCH_GET_CHILD);
$files = array();
foreach ($itdir as $path=>$dir){
if ($dir->isFile()){
$ext = substr(strtolower($path), -3);
if($ext == 'sql'){
$files[] = array('path' => $path);
}
}
}
return $files;
}
//get files
$files = scan_for_sql_files('mysqls');
//Do sql
foreach($files as $file){
$sql = file_get_contents($file['path']);
$qr = $dbh->exec($sql);
}
?>
You can use unlink() function to delete the file.
unlink('test.html');
foreach($files as $file){
$sql = file_get_contents($file['path']);
$qr = $dbh->exec($sql);
if(is_file($file['path'])){
unlink($file['path']);
}
}
Ref: http://us2.php.net/unlink
You can add the "unlink" function to get rid of the file
Simple modification :
foreach($files as $file){
$sql = file_get_contents($file['path']);
$qr = $dbh->exec($sql);
unlink($file['path']);
}
http://www.w3schools.com/php/func_filesystem_unlink.asp
"Unlink" reference
you can delete your sql file by this
unlink('database.sql');
or
you can delete sql file content by this
file_put_contents("database.sql", "");
if you are working on window os don't worry but if you are working in linux you have to set permission of all sql file other wise your file will not access by your php script

how to unzip txt.gz file and store into database using php

My zip file name is Product_Catalog.txt.gz. this zip file contain one txt file.
how can i extract and store into my database
i have already done in zip file unzip and store into my database. but i can't understand .gz format. so please advise
my zip file code is here
if (realpath($destinationname."/".$filename)){
if ($zip = zip_open(realpath($directory."/".$filename)))
{
while (($zip_entry = zip_read($zip))){
$zipfilename=zip_entry_name($zip_entry );
$zipfilename."<br>";
$tmpfname = tempnam("/tmp", "");
$handle = fopen($tmpfname, "w+");
while($data = zip_entry_read($zip_entry,50000000000)){
fwrite($handle,$data);
}// end while $data
fseek($handle,0);
if ($separatetables);
$table=strtok($zipfilename,"-");
$sql="CREATE TABLE IF NOT EXISTS `$table` LIKE `cjfeeds`";
mysql_query($sql);
how can i convert this code into txt.gz
gzip, which is generally used for single files, is not the same file format as ZIP. Although the same compression algorithm (DEFLATE) is used in both formats, the headers are entirely different, so PHP's Zip functions will not recognize your file.
Instead, you can use the compress.zlib:// wrapper to open gzip-compressed files. You can then use the normal stream functions to read the file.
$handle = fopen("compress.zlib://$filename", 'r');
However, there are some limitations; for example, opening a gzipped file in read-write mode is not possible, and seeking may be slow. If necessary, you can work around these by making a temporary uncompressed copy:
copy("compress.zlib://$filename", $tmpfname);
You don't extract.
if ($rrpath){
if ($zip = gzopen($rrpath, "rb"))
{
$filenamen = $_SESSION['files_list'][$i];
$zipfilename = str_replace('.gz', '', $_SESSION['files_list'][$i]);
$tmpfname = tempnam("/home/demoosiz/tmp", "");
$handle = fopen($tmpfname, "w+");
ini_set("max_execution_time",3000000000000);
while($data = gzread($zip, 4096)){
fwrite($handle,$data);
}// end while $data
fseek($handle,0);
if ($separatetables);
$table=strtok($zipfilename,"-");
// $sqly = "TRUNCATE TABLE `cjfeeds`";
//mysql_query($sqly);
// I'm not too sure if this is windows specific
$tmpfile=addslashes($tmpfname);
//if the script times out uncomment the next line
ini_set("max_execution_time",3000000000000);
$sql22 ="LOAD DATA LOCAL INFILE '$tmpfile' REPLACE INTO TABLE `cjfeeds` FIELDS TERMINATED BY '$fieldseparator' IGNORE 1 LINES;";
You can use this code. This code is very helpful for you.
You keep calling it a zip file. It's not a zip file (.zip). It's a gzip file (.gz). Different format.
You can use gzdecode() to decompress a gzip file.
You can interact with .gz files through the functions of the zlib module.
Responding to your comment:
You won't need to do the while($zip_entry = zip_read($zip)) since gz files don't hold multiple files within them. A .gz file is just a single file that has been compressed. Unfortunately, this also means that there is no equivalent to zip_entry_name either, since there is only one file.
If you're trying to read a tarball - an archive of files which have been concatenated together and gzipped to form a .tar.gz file - then Zlib isn't for you, since it's not designed to handle that. You'll want something like PharData instead:
$phar = new PharData($filename);
foreach ($phar as $phar_stream) {
$file_data = file_get_contents($phar_stream);
// process $file_data how you like
}
If these are just single-file gz files, then you can read the files with the gz versions of the usual filesystem functions.
You can use gzread to process chunks of the file the way you're currently doing with zip_entry_read, or you can read all lines into an array with gzfile. There is a readgzfile function which grabs the whole file, but unfortunately it seems like it just dumps the output directly to the client, rather than do a file. You could use output buffering to capture that output, but it seems like too much of a hassle considering your other options.
Try this....
if(isset($_FILES['zipfile']))
{
$filename = $_FILES['zipfile']['name'];
$source = $_FILES['zipfile']['tmp_name'];
$type = $_FILES['zipfile']['type'];
/*$name = explode('.zip', $filename); # $name[0] returns the name of the file. $name[1] returns the extension (zip)
; */ # Where the file will be saved. I.E. 'extracted/myFile-02151985/'
$target = PHYSICAL_PATH."upload/";
// Ensures that the correct file type was chosen.
$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;
}
}
$okay = strtolower($name[1]) == 'zip' ? true : false;
if(!$okay)
{
$msg="Please choose a zip file, dummy!";
}
$saved_file_location = $target.$filename;
if(move_uploaded_file($source, $target . $filename))
{
global $target;
global $unique_folder;
$zip = new ZipArchive();
$x = $zip->open($saved_file_location);
if ($x === true)
{
$folder=$zip->extractTo($target);
for ( $i=0; $i < $zip->numFiles; $i++ )
{
echo $entry = $zip->getNameIndex($i);
$filename=explode('/',$entry);
print_r($filename);
if($filename[1] != '')
{
$filename_folder=$filename[0];
$filename = $filename[1]; //
$name = explode('.zip', $filename_folder); # $name[0] returns the name of the file. $name[1] returns the extension (zip)
//echo 'sfkdf'.$name[0];
$target = PHYSICAL_PATH."upload/";
$sql = "select `id` from `tracks` order by `id` desc";
$list = mysql_query($sql);
$list_num = mysql_num_rows($list);
if($list_num > 0)
{
$res = mysql_fetch_array($list);
$new_id=$res['id'];
} else {
$new_id=1;
}
$check_for_jpg = strpos($filename, '.mp3');
if ($check_for_jpg === false ){
echo 'Check file format.';
$source=$target . $name[0].'/'.$filename;
unlink($source);
} else {
$srch = array(' ','--','"','!','#','#','$','%','^','&','*','(',')','_','+','{','}','|',':','"','<','>','?','[',']','\\',';',"'",',','/','*','+','~','`','=');
$rep = array('_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_');
$name_song[$i]= str_replace($srch,$rep,$filename);
$title_name=explode('.',$filename);
$new_id=$new_id+1;
$new_filename=$new_id.'-'.$name_song[$i];
mysql_query("insert into `tracks` set track='".addslashes(stripslashes($new_filename))."',title='".addslashes(stripslashes($title_name[0]))."',tape_id='".$id_last."',addDate=NOW(),status=1 ");
$source=$target . $name[0].'/'.$filename; $target_move=$target.$new_filename;
if(rename($source,$target_move)) { unlink($source); } else { echo 'not';}
echo 'folder zip';
echo '<li>' . $new_filename . '</li>';
}
rmdir($target . $name[0]);
}
else { echo $target = PHYSICAL_PATH."upload/";
$sql = "select `id` from `test_table` order by `id` desc";
$list = mysql_query($sql);
$list_num = mysql_num_rows($list);
if($list_num > 0) {
//and, instead of using "while":
$res = mysql_fetch_array($list); // will return the highest "id" number
echo $new_id=$res['id'];
} else {
$new_id=1;
}
$check_for_jpg = strpos($entry, '.mp3');
if ($check_for_jpg === false ){
echo 'Check file format.';
$source=$target .$entry;
unlink($source);
} else {
$srch = array(' ','--','"','!','#','#','$','%','^','&','*','(',')','_','+','{','}','|',':','"','<','>','?','[',']','\\',';',"'",',','/','*','+','~','`','=');
$rep = array('_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_','_');
$name_song[$i]= str_replace($srch,$rep,$entry);
$title_name=explode('.',$entry);
$new_id=$new_id+1;
$new_filename=$new_id.'-'.$name_song[$i];
mysql_query("insert into `tracks` set track='".addslashes(stripslashes($new_filename))."',title='".addslashes(stripslashes($title_name[0]))."',tape_id='".$id_last."',status=1 ");
$source=$target .$entry; $target_move=$target.$new_filename;
if(rename($source,$target_move)) { unlink($source); } else { echo 'not';}
echo 'only zip';
echo '<li>' . $new_filename . '</li>';
}
}
}
$zip->close();
unlink($saved_file_location); #deletes the zip file. We no longer need it.
} else {
die("There was a problem. Please try again!");
}
} else {
$msg="There was a problem";
}
}

Extracting values from multi dimensional array

I'm fairly new to php. I'm using the following script to upload multiple images to a directory. The script works fine. The problem I have is I don't know how to reference the second image so I can store it in a mysql database. The variable $filename stores the image elements of the array.
I want to add the second image to the column itm_pic_name2 in my mysql database. Please can someone point me in the right direction.
public function move($overwrite = false)
{
$field = current($this->_uploaded);
if (is_array($field['name'])) {
foreach ($field['name'] as $number => $filename) {
print_r($field);
//process the multiple upload
$this->_renamed = false;
$this->processFile($filename, $field['error'][$number], $field['size'][$number], $field['type'][$number], $field['tmp_name'][$number], $overwrite);
}
} else {
$this->processFile($field['name'], $field['error'],
$field['size'], $field['type'], $field['tmp_name'], $overwrite);
}
}
protected function processFile($filename, $error, $size, $type, $tmp_name, $overwrite)
{
$OK = $this->checkError($filename, $error);
if ($OK) {
$sizeOK = $this->checkSize($filename, $size);
$typeOK = $this->checkType($filename, $type);
if ($sizeOK && $typeOK) {
$name = $this->checkName($filename, $overwrite);
echo $filename;
echo $type;
echo $size;
$success = move_uploaded_file($tmp_name, $this->_destination . $name);
if ($success) {
//add the amended filename to the array of filenames
$this->_filenames[] = $name;
$this->execSQL("INSERT INTO itm_pic_detail(itm_pic_name, itm_pic_name2,itm_pic_type, itm_pic_size) VALUES (?,?,?)",
array('ssss', $filename, $not_sure_how_to_refence_this_image, $type, $size), true);
$message = "$filename uploaded successfully";
}
if ($this->_renamed) {
$message .= " and renamed $name";
}
$this->_messages[] = $message;
} else {
$this->_messages[] = 'Could not upload ' . $filename;
}
}
}
It's not enough to add a single itm_pic_name2 column to the database. The database structure contains more than just the file name. It contains the size and type as well. Instead, you should be inserting multiple rows in the database - one file per row. Every time you insert a picture, it should return a fileId for the file.
Essentially, what you need is a data table for your form data. That table would have two columns. One for file 1. One for file 2. In that table, you store the unique file id for each file. Then, you use joins to get the file information that you need.
I can't write it out for you exactly, because I don't have any background of what you're trying to do with the files. But, hopefully, you can take this as a start and run with it.

Categories