I have this function whereby it allows people to download zip file but then i try to open it after downloading it, there was this error msg that says "Error reading zip".

Dani AI

Generated

Summary of likely causes and focused fixes (ties to earlier replies by and )

The symptom — MP3s intact via FTP but with missing ID3 after being served by the script — strongly suggests a binary-transfer problem rather than an MP3/zip library bug. correctly flagged header/variable issues and ’s advice about Content-Length/readfile was the right direction. Common causes in this situation are: files opened in text mode on a Windows host (CRLF or 0x1A treated as EOF), PHP output buffering or UTF‑8 BOM injecting extra bytes, or on-the-fly compression altering binary streams.

Concrete checklist and small fixes

  • Open files in binary mode (avoid plaintext mode on Windows).
  • Turn off PHP output compression for binary responses.
  • Clear any output buffers and ensure no whitespace or BOM is sent before headers.
  • When generating a ZIP in memory, set Content-Length from the actual string length; when streaming a filesystem file, use filesize.
  • Close file handles and stop script execution after sending the file.

Example snippets (do not copy the headers already shown in the thread):

fopen($pathname, 'rb');

if (ob_get_level()) ob_end_clean();
ini_set('zlib.output_compression', 0);

header('Content-Length: '.strlen($zipContent));
echo $zipContent;
exit;

Practical diagnostic steps

  • Compare checksums: compute server-side hash (e.g. md5_file) and compare to the downloaded file’s hash. Different hashes prove the transfer altered bytes.
  • Compare file sizes; inspect the downloaded file in a hex viewer to find extra leading bytes or truncation.
  • Create a tiny binary test (include a 0x1A byte) and serve it; if it’s truncated, the server/script is using text mode or translating bytes.

Notes and best practice

For filesystem files prefer streaming (readfile) with correct headers and Content-Length; for in-memory archives compute length with strlen and echo the buffer. Ensure no output (including BOM or stray whitespace) is emitted before headers. These steps address the ID3 truncation issue seen by and complement the header/readfile guidance from .

Recommended Answers

All 9 Replies

If you really want help you should post your code, or at least the portion you feel is causing the problem. Offhand it sounds like the zip file on the server has gotten corrupted somehow.

$zipfile = new zipfile();
             $zipfile -> add_dir("files/");
             $dir = '../files';
				
             $filename = "testing.mp3";
	$pathname = "$dir/$filename";	
					
	$fr   = fopen($pathname, 'r');
	$data = fread($fr, filesize($pathname));
					
	fclose($fr);
										
	$zipfile->add_file($filedata, "files/".$filename);   
					
					

            header("Content-type: application/octet-stream");
            header("Content-disposition: attachment; filename=testing.zip");
            echo $zipfile->file();

This is the part i feel is causing the problem. i have a zipfile class which creates zip files

Have you tried:

header("Content-type: application/x-zip");

Also, you open the file and put the data into $data. Then you use the class and use the variable $filedata. Should they be the same??

Have you tried:

header("Content-type: application/x-zip");

Also, you open the file and put the data into $data. Then you use the class and use the variable $filedata. Should they be the same??

oh that, it's the same, i forget to change it because these codes are edited to protect the privacy of the codes.

i try already but cannot still error reading zip but the file was in the downloaded because i see the file size of the zip is the same as the file size of the file.

Hi

You should be using a content length header so the browser does not add \r?\n to the stream buffer...

Also your application-x-type is wrong...

if ( strstr ( strtolower ( $_SERVER['HTTP_USER_AGENT'] ), 'msie 5.5' ) )
{
	$att = '';
}
else
{
	$att = ' attachment;';
}

header ( 'Cache-control: max-age=31536000' );
header ( 'Expires: Mon, 26 Jul 1997 05:00:00 GMT' );
header ( 'Content-Length: ' . filesize ( $filename ) );
header ( 'Content-Type: application/x-zip-compressed; name="' . basename ( $filename ) . '"' );
header ( 'Content-Disposition:' . $att . ' filename="' . basename ( $filename ) . '"' );
header ( 'Content-Transfer-Encoding: binary' );
readfile ( $filename );

demo

so this codes are the correct one then? oh k i will try n see then thanks :cheesy:

Hi

You should be using a content length header so the browser does not add \r?\n to the stream buffer...

Also your application-x-type is wrong...

if ( strstr ( strtolower ( $_SERVER['HTTP_USER_AGENT'] ), 'msie 5.5' ) )
{
	$att = '';
}
else
{
	$att = ' attachment;';
}

header ( 'Cache-control: max-age=31536000' );
header ( 'Expires: Mon, 26 Jul 1997 05:00:00 GMT' );
header ( 'Content-Length: ' . filesize ( $filename ) );
header ( 'Content-Type: application/x-zip-compressed; name="' . basename ( $filename ) . '"' );
header ( 'Content-Disposition:' . $att . ' filename="' . basename ( $filename ) . '"' );
header ( 'Content-Transfer-Encoding: binary' );
readfile ( $filename );

demo

by using basename, other ppl can know what is the location of the mp3 but for security purposes, i dun want ppl to know the location of the mp3

i did not use zip file anymore then can work already. i am able to download the file successfully. the next problem arises up. :sad:

In the first place, the mp3 file has a ID3 tag. after it has been downloaded, the ID3 tag is deleted. I figure it must be the codinng though because when i download it straight from server through ftp. Everything is alright. i myself really do not know what is wrong. :?: :?:

This is the part of code which i think might be the problem

$currentdir = '../mp3_files';
$trackname = $trackdb->retrieveTrackName($track_oid);
$filename = "$trackname.mp3";
$pathname = "$currentdir/$filename";

$fr = fopen($pathname, 'r');
$filedata = fread($fr, filesize($pathname));

//fclose($fr);


//$zipfile->add_file($filedata,$filename);

header ( 'Content-Length: ' . filesize ( $pathname ) );
header("Content-type: application/octet-stream");
header("Content-disposition: attachment; filename=$filename");
header ( 'Content-Transfer-Encoding: binary' );
readfile($pathname);

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.