JenniferLawrence Posted June 28, 2015 Share Posted June 28, 2015 Is it possible to get a .zip file without downloading it to a computer and just extract the file into a remote server? So something like this http://docs.google.com/random_zip_file.zip --------------> Extract using PHP | | V http://domain.com/extracted_files/ If I do something like this <?php $extract = new ZipArchive(); if($extract->open('/root_of_the_directory/directory_where_the_zip_file_exists/') === TRUE) { $extract->extractTo('/root_of_the_directory/extracted_files/'); if($extract->close() === TRUE) { print('Extraction was a success!'); } else { print('Something went wrong with extracting the file.'); } } else { print('Could not find the .zip file'); } It works, but then if I do something like this. <?php $extract = new ZipArchive(); if($extract->open('http://docs.google.com/random_zip_file.zip') === TRUE) { $extract->extractTo('/root_of_the_directory/extracted_files/'); if($extract->close() === TRUE) { print('Extraction was a success!'); } else { print('Something went wrong with extracting the file.'); } } else { print('Could not find the .zip file'); } It doesn't work because I was thinking that $extract->open only works for files on the same server. If it's on a different server, I would need to use file_get_contents. However, with file_get_contents along with $extract->open like so. <?php $extract = new ZipArchive(); $get_file = file_get_contents('http://docs.google.com/random_zip_file.zip'); if($extract->open($get_file) === TRUE) { $extract->extractTo('/root_of_the_directory/extracted_files/'); if($extract->close() === TRUE) { print('Extraction was a success!'); } else { print('Something went wrong with extracting the file.'); } } else { print('Could not find the .zip file'); } I get this error. Warning: ZipArchive::open(): Empty string as source in /root_of_the_directory/extract.php on line 102 What is the best approach to extract files to a remote server without actually downloading the .zip file to a desktop? Quote Link to comment Share on other sites More sharing options...
Ch0cu3r Posted June 28, 2015 Share Posted June 28, 2015 You cannot pass the binary contents of the zip file to $extract->open. As its expects a filename to be given. So you will need to download and store the zip file on the server and then use $extract->open Quote Link to comment Share on other sites More sharing options...
JenniferLawrence Posted June 30, 2015 Author Share Posted June 30, 2015 You cannot pass the binary contents of the zip file to $extract->open. As its expects a filename to be given. So you will need to download and store the zip file on the server and then use $extract->open The weird part is that it actually works for only zip folders within the server. If it is located on a different server, it won't open. I've tried this many times on my localhost and it seems to work. I'm looking to store zip folders in which I can use my code to download and extract without actually downloading the zip folder to my actual computer and re-uploading the zip folder and extracting it to the appropriate folder. This makes it take too much time and it is a hassel for some of my users. I would like to make it kind of like SMF where you can extract the zip folder straight from their website and extract it to your themes folder making it easier for users to use. Quote Link to comment Share on other sites More sharing options...
requinix Posted June 30, 2015 Share Posted June 30, 2015 It could very well be that ZipArchive won't work with http:// "files". Like Ch0cu3r said, copy the file to something temporary locally, then extract (and delete the file afterwards). $temp = tempnam(sys_get_temp_dir(), "zip"); if (copy($remote_file_location, $temp) && is_file($temp) && filesize($temp) > 0) { // extract $temp unlink($temp); } else { // error } Quote Link to comment Share on other sites More sharing options...
JenniferLawrence Posted July 2, 2015 Author Share Posted July 2, 2015 (edited) It could very well be that ZipArchive won't work with http:// "files". Like Ch0cu3r said, copy the file to something temporary locally, then extract (and delete the file afterwards). $temp = tempnam(sys_get_temp_dir(), "zip"); if (copy($remote_file_location, $temp) && is_file($temp) && filesize($temp) > 0) { // extract $temp unlink($temp); } else { // error } Tried that. Filesize always ends up being 0 and coping to local temp folder doesn't work. Would just copying the file to a folder within the local server work? And then just extract the zip file from the local folder. EDIT: Nvm, seems like we were on the same page, just that I thought of it differently. Seems to work now. Probably going to extract all of the content first before I delete the zip folder. Edited July 2, 2015 by JenniferLawrence Quote Link to comment Share on other sites More sharing options...
JenniferLawrence Posted July 2, 2015 Author Share Posted July 2, 2015 Ok so I got the copying the zip file to a local server with the right name all set up. The problem now is that it has 0 bytes in it. I know it has something to do with the header content-type and what not. Here's my code. $remote_file_location = 'http://docs.google.com/random_zip_file.zip'; $temp = '/root_of_the_directory/extracted_files/'; if(copy($remote_file_location, $temp)) { // extract $temp print($temp); die(); } else { print('error'); die(); } It seems that if I took away the error checking for the file size, I get the temp file. If I add in the file size checking, I get an error. What seems to be the problem? Quote Link to comment Share on other sites More sharing options...
requinix Posted July 2, 2015 Share Posted July 2, 2015 You can't copy to a directory name - it needs to be a file name. You should have gotten an error about that. $temp = '/root_of_the_directory/extracted_files/random_zip_file_or_whatever.zip';I suggest going back to using tempnam() too. Does the code work for any other $remote_file_location, like an image or webpage? Quote Link to comment Share on other sites More sharing options...
scootstah Posted July 2, 2015 Share Posted July 2, 2015 http://stackoverflow.com/a/15140604/1072631 This SO answer has concluded that after trying many things, it's simply not possible to unzip a file in any other way than to have the file in the local file system. You're going to need to download the file and then unzip it. Quote Link to comment Share on other sites More sharing options...
JenniferLawrence Posted July 2, 2015 Author Share Posted July 2, 2015 You can't copy to a directory name - it needs to be a file name. You should have gotten an error about that. $temp = '/root_of_the_directory/extracted_files/random_zip_file_or_whatever.zip';I suggest going back to using tempnam() too. Does the code work for any other $remote_file_location, like an image or webpage? Sorry, my mistake. I forgot to add the zip file for the temp variable in this comment. I already had it in my code, but it still doesn't work. I tried it with an image and the image seems to have file sizes, but the image as well can't be opened or displayed. http://stackoverflow.com/a/15140604/1072631 This SO answer has concluded that after trying many things, it's simply not possible to unzip a file in any other way than to have the file in the local file system. You're going to need to download the file and then unzip it. Umm, that's what we are doing here already. If you didn't read Ch0cu3r and requinix's response. They said the same thing. No need to repeat what is already said. She is already helping me achieve that. I have also Google searched how to download zip files to remote servers and extract them. They all give them same exact answer. None of them seems to be working. They achieve the same results, but all of them can't download the right bytes in order for the zip file to not be corrupted nor unable to be opened. Quote Link to comment Share on other sites More sharing options...
scootstah Posted July 2, 2015 Share Posted July 2, 2015 No need to repeat what is already said. She is already helping me achieve that. Well, pardon me then. I have also Google searched how to download zip files to remote servers and extract them. They all give them same exact answer. None of them seems to be working. They achieve the same results, but all of them can't download the right bytes in order for the zip file to not be corrupted nor unable to be opened. Do you have "allow_url_fopen" turned on in your PHP config? Otherwise things like copy() or fopen() with a remote file will not work. If you can't turn that on, or don't want to, the other option is to use CURL to download the file. Quote Link to comment Share on other sites More sharing options...
JenniferLawrence Posted July 4, 2015 Author Share Posted July 4, 2015 Do you have "allow_url_fopen" turned on in your PHP config? Otherwise things like copy() or fopen() with a remote file will not work. If you can't turn that on, or don't want to, the other option is to use CURL to download the file. I'm using xampp. It's enabled automatically. The problem I'm running into isn't whether things are enabled or not. When my script copies over files. The file gets copied, however only parts of it are copied and therefore the file won't open. Same thing with images. Since it isn't properly downloaded, the file is corrupted. I see bits of filesize being added and taken from the file, but not the actual filesize of the orginal file. I'm starting to think this is impossible so I'm probably going to just make a download link so that the clients can download it and upload them to their server. I think this is the best possible way because this auto download/ extract seems to not be working at all. Quote Link to comment Share on other sites More sharing options...
scootstah Posted July 5, 2015 Share Posted July 5, 2015 Working code: <?php $ch = curl_init('http://localhost/phpfreaks/test.zip'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $data = curl_exec($ch); curl_close($ch); file_put_contents(($zipPath = sys_get_temp_dir() . '/test.zip'), $data); $zip = new ZipArchive(); if ($zip->open($zipPath) !== false) { $extractPath = __DIR__ . '/extracted'; if (!file_exists($extractPath)) { mkdir($extractPath, null, true); } $zip->extractTo($extractPath); $zip->close(); } Quote Link to comment Share on other sites More sharing options...
JenniferLawrence Posted July 5, 2015 Author Share Posted July 5, 2015 Working code: <?php $ch = curl_init('http://localhost/phpfreaks/test.zip'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $data = curl_exec($ch); curl_close($ch); file_put_contents(($zipPath = sys_get_temp_dir() . '/test.zip'), $data); $zip = new ZipArchive(); if ($zip->open($zipPath) !== false) { $extractPath = __DIR__ . '/extracted'; if (!file_exists($extractPath)) { mkdir($extractPath, null, true); } $zip->extractTo($extractPath); $zip->close(); } Same thing is happening. sys_get_temp_dir() doesn't like Windows temp folder because I guess it's write protected so I changed the folder it's pointing to a writeable folder and same thing happens. The file is corrupted and can't be opened. The problem isn't really storing the file. It's more of getting the file with its original tribute. May I see screenshots or video clips of this working example? I don't know why it isn't working for me. Again, the folder storing isn't the problem, it's getting the file and keeping the original tribute on it. If I was to compare this example and they example reguinix had made (my modification version of hers), they do practically the same exact thing except yours uses cURL and hers just uses the copy command. The files are corrupted for both methods. If it doesn't work at all, I might have to just forget about this topic and do the actual download/ upload .zip file thing. Quote Link to comment Share on other sites More sharing options...
Solution scootstah Posted July 5, 2015 Solution Share Posted July 5, 2015 (edited) How big is the file you're trying to download? You can try adding these two CURL options. It seems these have worked for others with the same problem. curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); Edited July 5, 2015 by scootstah Quote Link to comment Share on other sites More sharing options...
JenniferLawrence Posted July 6, 2015 Author Share Posted July 6, 2015 How big is the file you're trying to download? You can try adding these two CURL options. It seems these have worked for others with the same problem. curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); Thanks for all your help. It worked. Part of it wasn't actually the downloading and storing I guess. I just looked at the source code where the zip files were being stored and I guess I had the headers do something like. header('Content-disposition: attachment; filename=' . dirname(__DIR__) . '/random_zip_file.zip'); header('Content-type: application/zip'); Which was wrong because the first header is not needed. I got it to work now. Thanks for you help. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.