Jump to content

Extract .zip file from other server to current server


Go to solution Solved by scootstah,

Recommended Posts

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?

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.

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
}

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 by JenniferLawrence

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?

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?

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.

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.

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.

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.

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();
}

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.

  • Solution

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 by scootstah

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.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.