Hello,
I have a script that allows user to upload a file to a mysql 5 database. That is working OK. The File size is accurate. However, my download script is for some reason downloading the files without any content - 0KB. The files are OK when I open them directly. I have tried code with .doc, .pdf, .txt and the same result.

Here is my code for viewing the files:

<?php
ini_set('display_errors', E_ALL);
include "open_db.inc";

$sql = "SELECT * FROM tbl_Files ";
$sql .= "ORDER BY filename ASC";
$result = mysql_query($sql, $db);
$rows = mysql_num_rows($result);

echo "<table>\n";
echo " <tr>\n";
echo "  <td>ID</td>\n";
echo "  <td>Filename</td>\n";
echo "  <td>Type</td>\n";
echo "  <td>Size</td>\n";
echo "  <td>Description</td>\n";
echo "  <td> </td>\n";
echo " </tr>\n";

while ($rows = mysql_fetch_object($result))
  {
  echo " <tr>\n";
  echo "  <td>$rows->id_files</td>\n";
  echo "  <td>$rows->filename</td>\n";
  echo "  <td>$rows->filetype</td>\n";
  echo "  <td>$rows->filesize</td>\n";
  echo "  <td>" . stripslashes($rows->description) . "</td>\n";
  echo "  <td>( <a href='download.php?id_files=$rows->id_files'>Download</a> )</td>\n";
  echo " </tr>\n";

  }

mysql_free_result($result);
mysql_close($db);
?>

The code for download.php is:

<?php
ini_set('display_errors', E_ALL);
if (isset($_GET['id_files']))
 {
 $id_files = $_GET['id_files'];
 include "open_db.inc";
  $sql = "SELECT id_files, bin_data, filetype, filename, filesize FROM tbl_Files WHERE id_files=$id_files";
	
  $result = @mysql_query($sql, $db);
  $dataT = @mysql_result($result, 0, "bin_data");
  $name = @mysql_result($result, 0, "filename");
  $size = @mysql_result($result, 0, "filesize");
  $type = @mysql_result($result, 0, "filetype");
	
  header("Content-type: $type");
  header("Content-length: $size");
  header("Content-Disposition: attachment; filename=$name");
  header("Content-Description: PHP Generated Data");
  header("Content-transfer-encoding: binary");
  echo $dataT;
}
else
{
echo 'id_files not set'; 

}
?>

I would appreciate any help.
Thanks,
TMLAH

Recommended Answers

All 17 Replies

Hello,
I have a script that allows user to upload a file to a mysql 5 database. That is working OK. The File size is accurate. However, my download script is for some reason downloading the files without any content - 0KB. The files are OK when I open them directly. I have tried code with .doc, .pdf, .txt and the same result.

Here is my code for viewing the files:

<?php
ini_set('display_errors', E_ALL);
include "open_db.inc";

$sql = "SELECT * FROM tbl_Files ";
$sql .= "ORDER BY filename ASC";
$result = mysql_query($sql, $db);
$rows = mysql_num_rows($result);

echo "<table>\n";
echo " <tr>\n";
echo "  <td>ID</td>\n";
echo "  <td>Filename</td>\n";
echo "  <td>Type</td>\n";
echo "  <td>Size</td>\n";
echo "  <td>Description</td>\n";
echo "  <td> </td>\n";
echo " </tr>\n";

while ($rows = mysql_fetch_object($result))
  {
  echo " <tr>\n";
  echo "  <td>$rows->id_files</td>\n";
  echo "  <td>$rows->filename</td>\n";
  echo "  <td>$rows->filetype</td>\n";
  echo "  <td>$rows->filesize</td>\n";
  echo "  <td>" . stripslashes($rows->description) . "</td>\n";
  echo "  <td>( <a href='download.php?id_files=$rows->id_files'>Download</a> )</td>\n";
  echo " </tr>\n";

  }

mysql_free_result($result);
mysql_close($db);
?>

The code for download.php is:

<?php
ini_set('display_errors', E_ALL);
if (isset($_GET['id_files']))
 {
 $id_files = $_GET['id_files'];
 include "open_db.inc";
  $sql = "SELECT id_files, bin_data, filetype, filename, filesize FROM tbl_Files WHERE id_files=$id_files";
	
  $result = @mysql_query($sql, $db);
  $dataT = @mysql_result($result, 0, "bin_data");
  $name = @mysql_result($result, 0, "filename");
  $size = @mysql_result($result, 0, "filesize");
  $type = @mysql_result($result, 0, "filetype");
	
  header("Content-type: $type");
  header("Content-length: $size");
  header("Content-Disposition: attachment; filename=$name");
  header("Content-Description: PHP Generated Data");
  header("Content-transfer-encoding: binary");
  echo $dataT;
}
else
{
echo 'id_files not set'; 

}
?>

I would appreciate any help.
Thanks,
TMLAH

Have you verified that content of bin_data is the table is actually some binary data and not an empty value?

Also, what are the sizes of files you are trying to download? Is the size not exceeding some settings in php.ini like max_file_size and memory_limit?

Finally try to comment out the headers (one by one) and see it that helps.

And of cause you can use logging to actually send to result of mysql select to a log file then inspect the log file to see if binary file was actually selected

See if changing

header("Content-Disposition: attachment; filename=$name");

to

header("Content-Disposition: attachment; filename=" $name);

works for you.

Thanks khess. Tried your suggestion but just get a blank browser page now.

uncle_smith - the file i am testing with is only 1kb.
I have tried commenting out the headers 1 by 1 but either still get 0kb file or a blank page.

In the bin_data field I have "[BLOB - 0 B]". How do I verify that that is binary data? Does "0 B" indicate that the file does not contain data?
Thanks,
TMLAH

Member Avatar for diafol

Have you got a MySQL GUI? Try SQLyog (free community version) or Navicat to have a look at your records.

ardav, I use phpmyadmin. Via that I see that the entry into the bin_data field is: [BLOB - 0 B]

Member Avatar for diafol

I'm no expert, but it seems like you've got an empty field. Your upload function doesn't seem to be storing your bin data.Have you tried echoing your bin variable on upload?

Thanks khess. Tried your suggestion but just get a blank browser page now.

uncle_smith - the file i am testing with is only 1kb.
I have tried commenting out the headers 1 by 1 but either still get 0kb file or a blank page.

In the bin_data field I have "[BLOB - 0 B]". How do I verify that that is binary data? Does "0 B" indicate that the file does not contain data?
Thanks,
TMLAH

0KB means it's probably an empty field

You can try to send contents of that field to the log and look at it.
You can just create an empty file like log.txt, make sure it's writable
then in your script add
file_put_contents($dataT, 'log.txt')

If $dataT is not empty you will see some binary output in the log.txt
if log.txt is still empty, then you now you've got no content in that file

Hi,

I have added

file_put_contents($dataT, 'log.txt')

and log.txt is empty.

So, will you look at my upload code:

upload form:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Upload File to Database</title>
</head>

<body>


<form METHOD="post" action="processAddFile.php" ENCTYPE="multipart/form-data">
 <INPUT TYPE="hidden" NAME="MAX_FILE_SIZE" VALUE="1000000">

 <TABLE height="100%" width="100%" bgcolor="#00CCCC" BORDER="1">
  <TR>
   <TD>Description: </TD>
   <TD><TEXTAREA NAME="txtDescription" ROWS="10" COLS="50"></TEXTAREA></TD>
  </TR>
  <TR>
   <TD>File: </TD>
   <TD><INPUT TYPE="file" NAME="binFile"></TD>
  </TR>
  <TR>
   <TD COLSPAN="2"><INPUT TYPE="submit" VALUE="Upload"></TD>
  </TR>
 </TABLE>
</FORM>

</body>
</html>

And processAddFile.php:

<?php
var_dump($_FILES);

  include "open_db.inc";
$binFile= $_POST["binFile"];
$mytxtDescription= $_POST["txtDescription"];
$mybinFile_name= $_FILES['binFile']['name'];
$mybinFile_type = $_FILES['binFile']['type'];
$mybinFile_size = $_FILES['binFile']['size'];
 
    $data = addslashes(fread(fopen($binFile, "r"), filesize($binFile)));
    $strDescription = addslashes(nl2br($mytxtDescription));
    $sql = "INSERT INTO tbl_Files ";
    $sql .= "(description, bin_data, filename, filesize, filetype) ";
    $sql .= "VALUES ('$strDescription', '$data', ";
    $sql .= "'$mybinFile_name', '$mybinFile_size', '$mybinFile_type')";
	$result = mysql_query($sql, $db);
	mysql_free_result($result); 
    echo "Thank you. The new file was successfully added to our database.<br><br>";
    echo "<a href='viewFiles.php'>Continue</a>";
 
  mysql_close();


?>

I think the variables $binFile and $data have no value. Why isn't the form sending the data?

Any more suggestions?

Thanks alot.
TMLAH

Member Avatar for diafol

Is this correct?

$binFile= $_POST["binFile"];

Shouldn't you be an accessing an attribute of $_FILES["binFile"] .

Since $data depends on $binFile , it seems that this may be the problem. If $binFile is empty, so will $data be.

Do you mean ardav:
that instead of

$binFile= $_POST["binFile"];

I should have?

$binFile=$_FILES["binFile"];

If, so I have tried this and it didn't help.
TMLAH

Member Avatar for diafol
$tmpName  = $_FILES['binFile']['tmp_name'];
$fp      = fopen($tmpName, 'r');
$binFile = fread($fp, filesize($tmpName));
$binFile = addslashes($binFile);
fclose($fp);

This will put your content into the $binFile variable. Just insert this into your SQL.

Thanks ardav - a bit of progress.

When I echo $binFile the data is there.
When I download a .txt file the data is there but surrounded by code. When I download a .doc file
I get

<b>Warning</b>:  file_put_contents(ÐÏ à¡± á) [<a href='function.file-put-contents'>function.file-put-contents</a>]: failed to open stream: Invalid argument in <b>C:\Program Files\Apache Software Foundation\Apache2.2\htdocs\gearsTut\download.php</b> on line <b>20</b><br />
ÐÏ à¡± á                >   þÿ	                 !           #       þÿÿÿ        ¬       ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì¥Á `	   ø ¿

I haven't tried a .pdf yet.
Any ideas why this is happening?
I really appreciate your help with this matter.
TMLAH

Member Avatar for diafol

Your $binFile has been 'slashed' to place it in the field safely. So you will need to unslash with stripslashes(...) before outputting. In fact, you should encode the file (e.g. htmlentities() ) and then decode with its equivalent (I think html_decode_entities() or some mix of these words). The slashes could 'escape' or create mumbo jumbo for key info.

Thanks ardav for all your suggestions. I now have it working as it shoud be.

TMLAH:)

i just got a blank page that name is download.php when i click the download link

how can i download xml dom file dynamically which not saved in system?

code written by tmalh is working fine.
but i am getting blank text file when i click on download.
pl help

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.