PHP - Zipping Files On Demand
Hello Everyone,
I seem to have stumbled upon something that looks like it is next to impossible in PHP; zipping files/folders on demand in php :p So, after doing some extensive google searching, I have found various functions; some work only zipping files, other have no comments, some just don't work at all, etc. After looking at multiple projects, I have finally compiled something that works and has some sort of comments on what the heck is going on. Code: [Select] <?php class zipfile { /** * Array to store compressed data * * @var array $datasec */ var $datasec = array(); /** * Central directory * * @var array $ctrl_dir */ var $ctrl_dir = array(); /** * End of central directory record * * @var string $eof_ctrl_dir */ var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00"; /** * Last offset position * * @var integer $old_offset */ var $old_offset = 0; /** * Add a directory * * @var string $name */ function add_dir($name) { $name = str_replace("", "/", $name); $fr = "\x50\x4b\x03\x04"; $fr .= "\x0a\x00"; $fr .= "\x00\x00"; $fr .= "\x00\x00"; $fr .= "\x00\x00\x00\x00"; $fr .= pack("V",0); $fr .= pack("V",0); $fr .= pack("V",0); $fr .= pack("v", strlen($name) ); $fr .= pack("v", 0 ); $fr .= $name; $fr .= pack("V", 0); $fr .= pack("V", 0); $fr .= pack("V", 0); $this -> datasec[] = $fr; $new_offset = strlen(implode("", $this->datasec)); $cdrec = "\x50\x4b\x01\x02"; $cdrec .="\x00\x00"; $cdrec .="\x0a\x00"; $cdrec .="\x00\x00"; $cdrec .="\x00\x00"; $cdrec .="\x00\x00\x00\x00"; $cdrec .= pack("V",0); $cdrec .= pack("V",0); $cdrec .= pack("V",0); $cdrec .= pack("v", strlen($name) ); $cdrec .= pack("v", 0 ); $cdrec .= pack("v", 0 ); $cdrec .= pack("v", 0 ); $cdrec .= pack("v", 0 ); $cdrec .= pack("V", 16 ); $cdrec .= pack("V", $this -> old_offset ); $cdrec .= $name; $this -> ctrl_dir[] = $cdrec; $this -> old_offset = $new_offset; } /** * Converts an Unix timestamp to a four byte DOS date and time format (date * in high two bytes, time in low two bytes allowing magnitude comparison). * * @param integer the current Unix timestamp * * @return integer the current date in a four byte DOS format * * @access private */ function unix2DosTime($unixtime = 0) { $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime); if ($timearray['year'] < 1980) { $timearray['year'] = 1980; $timearray['mon'] = 1; $timearray['mday'] = 1; $timearray['hours'] = 0; $timearray['minutes'] = 0; $timearray['seconds'] = 0; } // end if return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1); } // end of the 'unix2DosTime()' method /** * Adds "file" to archive * * @param string file contents * @param string name of the file in the archive (may contains the path) * * @access public */ function add_file($data, $name) { // Read the file $fp = fopen($data,"r"); $data = fread($fp,filesize($data)); fclose($fp); // Clean the file name $name = str_replace("", "/", $name); $dtime = dechex($this->unix2DosTime(0)); $hexdtime = '\x' . $dtime[6] . $dtime[7] . '\x' . $dtime[4] . $dtime[5] . '\x' . $dtime[2] . $dtime[3] . '\x' . $dtime[0] . $dtime[1]; eval('$hexdtime = "' . $hexdtime . '";'); $fr = "\x50\x4b\x03\x04"; $fr .= "\x14\x00"; // ver needed to extract $fr .= "\x00\x00"; // gen purpose bit flag $fr .= "\x08\x00"; // compression method $fr .= $hexdtime; // last mod time and date // "local file header" segment $unc_len = strlen($data); $crc = crc32($data); $zdata = gzcompress($data); $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug $c_len = strlen($zdata); $fr .= pack('V', $crc); // crc32 $fr .= pack('V', $c_len); // compressed filesize $fr .= pack('V', $unc_len); // uncompressed filesize $fr .= pack('v', strlen($name)); // length of filename $fr .= pack('v', 0); // extra field length $fr .= $name; // "file data" segment $fr .= $zdata; // add this entry to array $this -> datasec[] = $fr; // now add to central directory record $new_offset = strlen(implode("", $this->datasec)); $cdrec = "\x50\x4b\x01\x02"; $cdrec .="\x00\x00"; $cdrec .="\x14\x00"; $cdrec .="\x00\x00"; $cdrec .="\x08\x00"; $cdrec .="\x00\x00\x00\x00"; $cdrec .= pack("V",$crc); $cdrec .= pack("V",$c_len); $cdrec .= pack("V",$unc_len); $cdrec .= pack("v", strlen($name) ); $cdrec .= pack("v", 0 ); $cdrec .= pack("v", 0 ); $cdrec .= pack("v", 0 ); $cdrec .= pack("v", 0 ); $cdrec .= pack("V", 32 ); $cdrec .= pack("V", $this -> old_offset ); $this -> old_offset = $new_offset; $cdrec .= $name; $this -> ctrl_dir[] = $cdrec; } /** * Dumps out file * * @return string the zipped file * * @access public */ function file() { $data = implode('', $this -> datasec); $ctrldir = implode('', $this -> ctrl_dir); return $data . $ctrldir . $this -> eof_ctrl_dir . pack('v', sizeof($this -> ctrl_dir)) . // total # of entries "on this disk" pack('v', sizeof($this -> ctrl_dir)) . // total # of entries overall pack('V', strlen($ctrldir)) . // size of central dir pack('V', strlen($data)) . // offset to start of central dir "\x00\x00"; // .zip file comment length } } // Test this class $zipTest = new zipfile(); $zipTest->add_dir("images/"); $zipTest->add_file("images/test.jpg", "test.jpg"); $zipTest->add_file("images/test2.jpg", "images/test2.jpg"); // Return Zip File to Browser Header("Content-type: application/octet-stream"); Header ("Content-disposition: attachment; filename=zipTest.zip"); echo $zipTest->file(); ?> On windows and linux, this class works flawlessly. On a Mac, this works with the stuffit program, but the default archive program does not like the zips if it contains a directory. If you comment out $zipTest->add_dir("images/");, the archive will work great on a Mac as well. Could someone help me get this class to create a working directory on a Mac as well? I am at a point where I would be willing to pay for your time if you can help me get this working (via paypal of course). Thanks in advance! weeee Similar TutorialsHello, I never dealt with such a feature before but I found a small script online that I am editing that works just fine. The problem is that it includes all of the directories in the path of my site in the zip. So if the path of my webhost is: /home/bob/files/ the zip will create a folder such as /home (inside that folder) /bob (inside that folder) /files (then the zipped files I wanted). I just want the zip files and I did store them out of the www/public_html directory to prevent people from downloading the files directly from the web but is there no way to make it not include all of those directories in the zip and only show the files? If so I will post the code that I have. Thanks I'm trying to find a way to back up an entire servers file through PHP. I have a script that can take selected files into a zip file but I'm not sure how to make sure that when I loop through directory and files that I get every single file. I was thinking of just foreach(glob('*') as $file up to 10 times but I'm hoping there's something more definite then that method... Thanks Hi guys, i have an array of data, with customers and their pics. something like: Quote array (customerid=>customerpic,...........); something like Quote 123412=>'https://mylink.com/mypic343545.tiff' 433453=>'https://mylink.com/mypic3434345.tiff' my goal is to: 1. go through the array and download all the pics, with names like customerid.tiff 2. when done renaming, make a zip file ON-THE-FLY 3. download the zip file to my PC. i know i can use file_put_contents and things like that, but i am not able to really connect the dots, especially the zipping of them all on the fly.....anyone has an idea on this? Hello I have a simple question about file handling... Is it possible to list all files in directories / subdirectories, and then read ALL files in those dirs, and put the content of their file into an array? Like this: array: [SomePath/test.php] = "All In this php file is being read by a new smart function!"; [SomePath/Weird/hello.txt = "Hello world. This is me and im just trying to get some help!";and so on, until no further files exists in that rootdir. All my attempts went totally crazy and none of them works... therefore i need to ask you for help. Do you have any ideas how to do this? If so, how can I be able to do it? Thanks in Advance, pros So far I have managed to create an upload process which uploads a picture, updates the database on file location and then tries to upload the db a 2nd time to update the Thumbnails file location (i tried updating the thumbnails location in one go and for some reason this causes failure) But the main problem is that it doesn't upload some files Here is my upload.php <?php include 'dbconnect.php'; $statusMsg = ''; $Title = $conn -> real_escape_string($_POST['Title']) ; $BodyText = $conn -> real_escape_string($_POST['ThreadBody']) ; // File upload path $targetDir = "upload/"; $fileName = basename($_FILES["file"]["name"]); $targetFilePath = $targetDir . $fileName; $fileType = pathinfo($targetFilePath,PATHINFO_EXTENSION); $Thumbnail = "upload/Thumbnails/'$fileName'"; if(isset($_POST["submit"]) && !empty($_FILES["file"]["name"])){ // Allow certain file formats $allowTypes = array('jpg','png','jpeg','gif','pdf', "webm", "mp4"); if(in_array($fileType, $allowTypes)){ // Upload file to server if(move_uploaded_file($_FILES["file"]["tmp_name"], $targetFilePath)){ // Insert image file name into database $insert = $conn->query("INSERT into Threads (Title, ThreadBody, filename) VALUES ('$Title', '$BodyText', '$fileName')"); if($insert){ $statusMsg = "The file ".$fileName. " has been uploaded successfully."; $targetFilePathArg = escapeshellarg($targetFilePath); $output=null; $retval=null; //exec("convert $targetFilePathArg -resize 300x200 ./upload/Thumbnails/'$fileName'", $output, $retval); exec("convert $targetFilePathArg -resize 200x200 $Thumbnail", $output, $retval); echo "REturned with status $retval and output:\n" ; if ($retval == null) { echo "Retval is null\n" ; echo "Thumbnail equals $Thumbnail\n" ; } }else{ $statusMsg = "File upload failed, please try again."; } }else{ $statusMsg = "Sorry, there was an error uploading your file."; } }else{ $statusMsg = 'Sorry, only JPG, JPEG, PNG, GIF, mp4, webm & PDF files are allowed to upload.'; } }else{ $statusMsg = 'Please select a file to upload.'; } //Update SQL db by setting the thumbnail column to equal $Thumbnail $update = $conn->query("update Threads set thumbnail = '$Thumbnail' where filename = '$fileName'"); if($update){ $statusMsg = "Updated the thumbnail to sql correctly."; echo $statusMsg ; } else { echo "\n Failed to update Thumbnail. Thumbnail equals $Thumbnail" ; } // Display status message echo $statusMsg; ?> And this does work on most files however it is not working on a 9.9mb png fileĀ which is named "test.png" I tested on another 3.3 mb gif file and that failed too? For some reason it returns the following Updated the thumbnail to sql correctly.Updated the thumbnail to sql correctly. Whereas on the files it works on it returns REturned with status 0 and output: Retval is null Thumbnail equals upload/Thumbnails/'rainbow-trh-stache.gif' Failed to update Thumbnail. Thumbnail equals upload/Thumbnails/'rainbow-trh-stache.gif'The file rainbow-trh-stache.gif has been uploaded successfully. Any idea on why this is? I am using WPSQT plugin in my blog site .I code some files in PHP also.how to add that files in plugin files.
lets say I own a file, and you own a file, both these files are the exact same file, the only difference is the filename. So lets say we both have The Gimp 2.6 but one is named TG2.6.exe and the other is named the_Gimp-2.6.exe. What would be the best way to count the files that are the same even if they have a different file name? Another example would be: I have a file called me.jpg and someone else has a file me.jpg but they are two completely different pictures. What would I do to tell that? I have told that the php files I was working on contains BOM by default cause of the editor I m using. I have installed other editor that can create php files without BOM. So my question is what's the difference between 2 files, one with BOM and other without BOM ? Any problems I may face for long term usage ? Which one is better to use ? first of all...its good to see the site back .
my question guys is i'm wondering is there a way of getting the column number when reading a .cvs file?
ie. a, b, c, d, aa, ab etc?
$row = 1; if (($handle = fopen($file, "r")) !== FALSE) { while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $num = count($data); echo "<p> $num fields in line $row: <br /></p>\n"; $row++; for ($c=0; $c < $num; $c++) { //echo $data[$c] . "<br />\n"; } } fclose($handle); }now $num counts the columns...but i want to convert that into a alphabetical column...is there a easy solution? thanks guys Hey, Trying to learn to generate PDF files, something apparently WAAAAYYY more complex than I thought. Can someone please give me an explanation on '$optlist' from this function..... PDF_load_image ( resource $pdfdoc , string $imagetype , string $filename , string $optlist ) What is it? PHP.net doesn't have any info at all. Thanks, IceKat. BTW - Any (recent) tutorials or pages would be appreciated. Everything I find is out of date or doesn't work. This topic has been moved to Miscellaneous. http://www.phpfreaks.com/forums/index.php?topic=345120.0 I am using xammp with FileZilla running on it. I've changed my php.ini settings to "C:/xxx/tmp" directory but am unable to upload a file. Th cod is running but it dos not seem to upload the temporary fil. Plase somebody help me. ALso my form in upload.html has <form action="upload_file.php" method="post" enctype="multipart/form-data"> the files are created upon registration. just i get this error.. Warning: include(1) [function.include]: failed to open stream: No such file or directory in /home/bob/public_html/mysite/profiles/write.php on line 129 Warning: include(1) [function.include]: failed to open stream: No such file or directory in /home/bob/public_html/mysite/profiles/write.php on line 129 Warning: include() [function.include]: Failed opening '1' for inclusion (include_path='.:/usr/lib/php:/usr/local/lib/php') in /home/bob/public_html/mysite/profiles/write.php on line 129 Code: [Select] $check = mysql_query("SELECT * FROM users WHERE username = '$username'")or die(mysql_error()); while($info = mysql_fetch_array( $check )) $filename = "/home/bob/public_html/mysite/profiles/profileinfo/$username.info.php" or exit("Unable to open file!"); $handle = fopen($filename, 'w')or die; $content = "<b>Firstname: </b>$firstname <br> <b> Lastname: </b> $lastname <p> <b> Birthday: </b>$day $month $year <br> <b> Location: </b> $location"; fwrite($handle, $content)or die; fclose($handle); } $check = mysql_query("SELECT * FROM users WHERE username = '$username'")or die(mysql_error()); while($info = mysql_fetch_array( $check )) include ("/home/bob/public_html/mysite/profiles/profileinfo/$username.info.php")or die; Hi, I have a script where employees of a company can upload invoices to their clients. This is done via a simple upload form. My question is, What would be most secure way to do this? How should i upload files, should i make different directories for each customer, or should i have one huge, where file names will be random or, what would you do? hello my problem is this I`m trying to search in two different files. Code: [Select] <?php $file=file($argv[1]); /// old users $file1=file($argv[2]); //// new users $err=0; foreach($file as $files){ $split=explode("\n",$files); for($i=0;$i<count($file1);$i++) { if($split[0]==$file1[$i]){ $err=1; }else{ $save=$file1[$i].chr(10); $fp=fopen('aa',"a+"); fputs($fp,$save); fclose($fp); } } } ?> that that i tried above it doesnt save good my purpose is to read the old users and the new ones and in the new ones there are old ones and what i want to do is to extract the old ones and replace it it ' ' in the newones file I almost have it but can't figure why the code below only shows one file per folder. I think it is showing the last file. I need $ul somehow looping to show all the files in $file. <?php $year = date('Y'); if ($handle = opendir("results/$year/Boys")) { while (false !== ($file = readdir($handle))) { if ($file != "." && $file != "..") { if ($handle2 = opendir("results/$year/Boys/$file")) { while (false !== ($file2 = readdir($handle2))) { if ($file2 != "." && $file2 != "..") { $ul = "<li><a href=\"#\">$file2</a></li>"; $li = "<li><a target=\"_blank\" href=\"javascript:void(0)\">$file</a> <ul> $ul </ul> </li>"; } // close if file2 }echo $li; } } } }closedir($handle);closedir($handle2); ?> Hi, I gave the following php script: #!/usr/bin/php -f <?php require_once(dirname(dirname(__FILE__))."/modules/common/common.config.inc.php"); $path = $conf["root"]."/media/images/tricouri/tmp/"; $command = "rm -Rf".$path."*"; if(exec($command)) { echo "Folder cleared\n"; } else { echo "Folder clear failed\n"; } ?> I want to delete some .png files from the ./tmp folder and I receive a rm error: Quote rm: invalid option -- / Try `rm --help' for more information. Folder clear failed The rm -rf command sintax is ok on the linux bash, but from php i receive the error. Php safe mode is off. Can someone help, please ? i am able to create csv's and can do so with no trouble .. but what i am having difficulty with is being able to auto save the csv and then email it all in one script. anybody every dealt with something like this? I'm an intermediate php coder however I have a new situation. I need to do some remapping of categories from CSV files we get from our supplier for our php ecommerce store. We use mySQL back end. We are importing data from a Supplier and need to remap the category names for our online store. There are 16,000 entries in the CSV file. This is what I need to do. 1) grab the CSV from the suppliers (from their ftp location) 2) remap the suppliers category names on the acquired CSV to our stores category names. I can either create a new table with the category name relation ships (probably best?) or read my mapping CSV ? 3) save the new CSV to our server where our auto import program can grab it. Eventually, Id like a cron to run the new script but for now Ill do it manually during testing period. Thats it! but... as simple as it sounds, I dont know how to start this. Below is an example of what needs to be dont just to clarify. PHP Code: Our Category(A) | Their Category(B) | Product (C) | Product Cat (D) | New Product Cat (E) 1. dog/leash/long | Pet/walking | Item A | Pet/sleeping|bed ** This is what we need to get** 2. dog/leash|long | Pet/walking | Item B | Pet/walking 3. dog/leash|long | Pet/sleeping bed | Item C | Pet/walking Here is my pseudo code: Code: [Select] for each value in Column D (run the test on each value in Column D) for each value in B as i ( check each value in Column B) if B(i) = D1 then E1 =A(i) end for end for The new path in this example for Item A would be A3 and would be written to E1. I have 15,000 entries to do. Thank you for any help hello i`m trying something but cant seem to get it working it purpose is this ; open 2 files goodies.txt has : heavy big small goodies2.txt has : rock toy brick and i want it to pick from goodies.txt first word and combine it to all words in goodies2.txt something like this: heavy-rock heavy-toy heavy-brick and then big-rock big-toy big-brick read file <?php $file=file('goodies.txt'); $file1=file('goodies2.txt'); foreach($file as $files){ $split=explode("\n",$files); for($i=0;$i<count($file1);$i++) { $combine=$split[0].$file1[$i]; echo $combine; } } } i dont know if my logic is good in this case :| |