Extract process with ZipArchive Slow in php

Hello Experts Exchange!

I'm fairly new to php so please be gentle!

Once a day, I receive a .zip file to my ftp account and I would like to build a script that unzips the file into the current directory. The code that I'm using is below.

$zip = new ZipArchive;    
$res = $zip->open($filename);

if ($res === TRUE) {
	$zip->extractTo('./');	
	echo 'Unzip was successful';
} else {
	echo 'Unzip was not successful';
	die();
}

$zip->close();

Open in new window


The problem I'm running into is my execution time. Every time I run the script, it times out. I've used set_time_limit(300); and the script still times out and the file I'm trying to unzip is only 50,437 B. Is there something amiss in my code or is there a faster alternative to ZipArchive?

I'm running PHP Version 5.3.6.
danswillAsked:
Who is Participating?
 
gr8gonzoConnect With a Mentor ConsultantCommented:
If it's sensitive (semi or not) data, then don't send it out to anyone, especially not over email (even though I can tell you that I'm trustworthy, you have no way to fully validate that).

That is bizarre that you could unzip it from Windows but not from any common utilities on the server. Almost every ZIP file uses the standard deflate algorithm, which should be supported everywhere. Usually when there is any difference, the built-in ZIP file support in Windows is the one that cannot open a ZIP file, not the other way around.

1. Are you 110% sure that the file is exactly the same on Windows as on the server? Do the md5 hashes match?

2. On the server, try running this command:
hexdump /path/to/your/zipfile.zip | head -n1

That should display the first 16 bytes of your ZIP file in hex, like this:
[root@server ~]# hexdump test.zip | head -n1
0000000    4b50 0403 0014 0000 0008 8213 4102 0a29

Open in new window


That line is broken down into:
0000000 - just the offset of the bytes you're looking at - not file data
4b50 0403 - the standard "hey, I'm a ZIP file!" signature (these 4 bytes should be the same across all standard ZIP files)
0014 - the 2-byte version of the application used to create the file
0000 - any special flags crammed into a 2-byte value
0008 - the compression used (0008 = deflate algorithm)

Can you show the output when you run the same hexdump on your file (the first 16 bytes will have nothing sensitive - it is all ZIP structure)?
0
 
gr8gonzoConsultantCommented:
It's probably not that bit of code that is causing the problem. If there are errors in the script, it will usually just abort right away and tell you about the error. What's the rest of the code look like?
0
 
gr8gonzoConsultantCommented:
Most timeouts are due to either:

1. Infinite loops:
$somecondition = true;
while($somecondition)
{
   ... code that never changes $somecondition to false ...
}

2. Network timeouts:
Connecting to a database, FTP server, or other remote resource improperly or in a way that does not get through security properly.

3. Slow or nested database queries:
$rs = mysql_query("SELECT ton, of, data FROM atable");

or

$rs1 = mysql_query("SELECT ten,thousand,rows FROM tableA");
while($row1 = mysql_fetch_assoc($rs1))
{
  $rs2 = mysql_query("SELECT something FROM tableB WHERE some_criteria=".$row1["bit_of_data"]);
  ... etc ...
}

See if your code has any of those types of connections (I'm banking on the FTP connection timing out).
0
Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
danswillAuthor Commented:
Thank you for your comments! I ran a test with a dummy.zip that's only 1,789 B (compared to the original file which is 50,437 B) and it ran just fine.

Since it seems that network timeouts is the real issue, how do I go about solving this? Do I need to make changes to my ftp server?
0
 
gr8gonzoConsultantCommented:
I'm not sure I understand. You said dummy.zip works just fine, but the original file doesn't, so I'm not sure why it would be a network timeout. Unless you are trying to download the original file from the FTP server using PHP immediately before unzipping it. If so, what does your code look like? (Just erase or change any sensitive info like host names, user names, and passwords).
0
 
danswillAuthor Commented:
Hello again,

The original file is 50,437 B and the dummy.zip is 1,789 B. Since the original file is 10 times larger, I was assuming this was causing the issue.

The file is located as the same location as the script, so I'm not connecting to a ftp site. Below is the my entire code, nothing fancy.

ftp screenshot

$filename = "dummy.zip";
$zip = new ZipArchive;    
$res = $zip->open($filename);

if ($res === TRUE) {
	$zip->extractTo('./');	
	echo 'Unzip was successful';
} else {
	echo 'Unzip was not successful';
	die();
}

$zip->close();

print('Unzipping process was successful.');

Open in new window

0
 
gr8gonzoConsultantCommented:
No, there should not be any problem with a 50k file. That is a very small file and PHP should be able to unzip that in less than a second.

If those 15 lines are truly ALL of the code that you have (and I mean everything - not excluding code that you think is not relevant), then I'm not quite sure what to tell you except that you should check your error logs. There's no reason ZipArchive should take any longer than milliseconds to open and extract a 50k file.

When you say that it times out, what are the final results that you see? Do you see a PHP error message about it?
0
 
danswillAuthor Commented:
Hello again,

Below is the full source code of my file. The only thing I've left out is a couple of variables.

Here's the error that I see when I run the script.

Fatal error: Maximum execution time of 300 seconds exceeded in /home/tucker15/public_html/sierrainteractive/openhouses.php on line 14

$year = date(Y);
$month = date(m);
$day = date(d);

$filename = "144-FCTUCKERINDI-". $year . $month . $day . "-44619.zip";

$zip = new ZipArchive;    
$res = $zip->open($filename);

if ($res === TRUE) {
	$zip->extractTo('./');	
	echo 'Unzip was successful';
} else {
	echo 'Unzip was not successful';
	die();
}

$zip->close();

print('Unzipping process was successful.');

Open in new window

0
 
gr8gonzoConsultantCommented:
Hmmm... so the error is on line 14, but in the code above, line 14 is an echo statement. If you add a blank line above the echo, like:

} else {

echo 'Unzip was not....';
Does the error change to line 15?

On a side note, always put quotes around strings:

date("Y") or date('Y') but not date(Y)

Otherwise, you're forcing PHP to look for a constant called Y before it gives up and tries to assume that you meant a string. It will also throw a warning that it can't find a variable called Y so it assumes you meant "Y".

(The quoted string thing is not the problem here, but it's good programming practice.)
0
 
danswillAuthor Commented:
Hello,

I'm really sorry, I didn't include the opening php tag and a couple of comment lines at the beginning of the script. It seems the culprit is really $zip->extractTo('./'); as seen in the following message.

And thank you so much for the tips about the date.


Error Message
Fatal error: Maximum execution time of 300 seconds exceeded in /home/tucker15/public_html/sierrainteractive/openhouses.php on line 12

Code
<?php
$year = date("Y");
$month = date("m");
$day = date("d");

$filename = "144-FCTUCKERINDI-". $year . $month . $day . "-44619.zip";

$zip = new ZipArchive;    
$res = $zip->open($filename);

if ($res === TRUE) {
	$zip->extractTo('./');	
	echo 'Unzip was successful';
} else {
	echo 'Unzip was not successful';
	die();
}

$zip->close();

print('Unzipping process was successful.');

Open in new window

0
 
gr8gonzoConsultantCommented:
Well, it's infrequent, but I would say that it's either a problem with your ZIP file or a bad install of the ZIP PECL extension. You could try updating the extension to whatever the latest version is to see if that fixes it, or you could use a variety of other classes to do it.

http://www.phpclasses.org/package/3864-PHP-Create-and-extract-ZIP-archives-in-purely-in-PHP.html

That package doesn't use the PECL extension and might give you a different result (if it's a bad file it might tell you rather than simply timing out).
0
 
danswillAuthor Commented:
Hello again, after a lot of searching, I found out that if I run 'unzip -tq filename' I could find out more information about the zip file. So, I ran this line of code and received the following message.

Caution: zero files tested in 144-FCTUCKERINDI-20130709-44619.zip. 1 file skipped because of unsupported compression or encoding.

This led to even more searching and I installed p7zip on my server, but it's still not working. The .zip file came from an asp.net environment.
0
 
gr8gonzoConsultantCommented:
It sounds like the asp.net application didn't correctly create the ZIP file. Can you post the file here, or if not, open it up in a text editor and see if it actually looks like a binary ZIP file.
0
 
danswillAuthor Commented:
I can unzip the file without a problem on my Windows machine but not from the server. My file actually has some (semi) sensitive data. Is there a way I can email it just to you?
0
 
danswillAuthor Commented:
1. Are you 110% sure that the file is exactly the same on Windows as on the server? Do the md5 hashes match?
Honestly, I'm not sure how to check the two. The file gets dropped onto our ftp site from our vendor.

2) Here's the output.
0000000 4b50 0403 002d 0000 0008 2015 42e9 cf7c
0
 
danswillAuthor Commented:
After even further search, I feel like I've been searching forever, this command now works in unzipping the file.

system('7za x filename');
0
 
danswillAuthor Commented:
Although this was not the exact solution, this additional information led me to the correct solution of getting p7zip installed on my server and using system('7za x filename') to extract my zipped file.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.