On this page, a user picks some options from drop downs and receives a list of files available for download. Download hyperlink next to each record. Currently the download hyperlink downloads a file with the correct FILE NAME as it exists in the database, but the file CONTENTS are incorrect. More specifically, it seems like a header is not being sent correctly: The contents of the file is the html markup from newpub_profile.php
This is the most current code:
newpub_profile.php
$q = "SELECT upload_id, title, genre, length, created
FROM upload
WHERE genre = '$genre' AND length = '$length'
ORDER BY created DESC, title DESC";
$r = mysqli_query ($dbc, $q); // Run the query
if($r)
{
// If it ran okay, display the records
echo '<table align="center"
cellspacing="3" cellpadding="3"
width="75%">
<tr><td align="left"><b>Title</b></td>
<td align="left"><b>Genre</b></td>
<td align="left"><b>Pages</b></td>
<td align="left"><b>Submitted</b></td>
<td align="left"><b>Download</b></td>';
// Fetch and print all the records:
while ($row = mysqli_fetch_array($r,MYSQLI_ASSOC))
{
echo '<tr><td align="left">' .
$row['title'] . '</td><td align="left">'
. $row['genre'] . '</td><td align="left">'
. $row['length'] . '</td><td align="left">'
. $row['created'] . '</td><td align="left">'
//. $row['views'] . '</td><td align="left">'
. "<a href='newpub_profile.php?id={$row['upload_id']}'>Download</a></td>" . '</td></tr>';
}
echo '</table>'; // Close the table
mysqli_free_result ($r); // Free up the resources
}
else // If it did not run okay
{
// Public Message:
echo '<p class="error">Your submissions could not be retrieved. We
apologize for any inconvenience.</p>';
// Debugging message:
echo '<p>' . mysqli_error($dbc) . '<br /><br />Query: ' . $q . '</p>';
} // End of if ($r) IF.
}
//END DOWNLOAD HANDLER ******************************************************
mysqli_close($dbc); // Close the database connection
?>
<?php
// Make sure an ID was passed DOWNLOAD HANDLER *******
if(isset($_GET['id'])) {
// Get the ID
$id = intval($_GET['id']); var_dump($id);
require_once ('../mysqli_connect.php'); //Connect to the db
// Fetch the file information
$downloadq = "
SELECT `file_type`, `size`, `title`, 'content', 'upload_id'
FROM `upload`
WHERE `upload_id` =".$id;
$result = mysqli_query ($dbc, $downloadq); // Run the query
if($result) {
// Make sure the result is valid
if (mysqli_num_rows($result) > 0) {
// Get the row
$row = mysqli_fetch_assoc($result);
//var_dump($row);
// Print headers
header("Content-Type: ". $row['type']);
header("Content-Length: ". $row['size']);
header("Content-Disposition: attachment; filename=". $row['title']);
// Print data
echo stripslashes($row['content']);
}
else {
echo 'Error! No such ID.';
}
// Free the mysqli resources
mysqli_free_result($result);
}
else {
echo "Error! Query failed: <pre>{$dbc->error}</pre>";
}
mysqli_close($dbc);
}
?>
newupload_sql.php
if(isset($_POST['upload']) && $_FILES['userfile']['size'] > 0) //check membership level here*******************************************
{
//------------------------------------------------------------------------------------------------
//$membercheck = "SELECT membership, uploaded
// FROM user
// WHERE user_id =". $_SESSION['user_id']; //gets membership level and upload count
//-----------------------------------------------------------------------------------------------
if($_FILES['userfile']['size'] > 2621440)
die("File larger than 2.5MB");
$mimeTypes = array('application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/msword');
if (in_array($_FILES['userfile']['type'], $mimeTypes))
{
$fileName = $_FILES['userfile']['name'];
$tmpName = $_FILES['userfile']['tmp_name'];
$fileSize = $_FILES['userfile']['size'];
$fileType = $_FILES['userfile']['type'];
$oid = $_SESSION['user_id'];
$views = 0;
$fp = fopen($fileName, 'r');
$content = fread($fp, filesize($fileName));
$content = addslashes($content);
fclose($fp);
//if(!get_magic_quotes_gpc())
//{
// $fileName = addslashes($fileName);
//}
$query = "INSERT INTO upload (title, file_type, size, content, length, genre, created, views, description, owner_id) ".
"VALUES ('$fileName', '$fileType','$fileSize', '$content', '$length', '$genre', NOW(), '$views', '$description', '$oid')";
$r = #mysqli_query ($dbc, $query); //Run the query. or die('Error, query failed');
if($r)
{
require_once ('login_functions.php');
$url = absolute_url ('newupload_thanks.php');
header("Location: $url");
exit();
}
else //if it didnt run ok...
{
//Public message:
echo '<h1>System Error</h1>
<p class="error">You could not upload due to a system
error. We apologize.</p>';
//debugging message:
echo'<p>' . mysqli_error($dbc) . '<br /><br />Query: ' . $r .
'</p>';
} // End of ($r) IF. // File's OK
}
}
else
{
die("Wrong tile type: Use .doc, .docx or ONLY");
}
}mysqli_close($dbc); //Close the database connection.
?>
Are you sure it is downloading the page itself? From the looks of it your issue is that you are not building the header correctly. Your SQL query and var_dump indicates that you are fetching a title but you use name for filename of the download offer (actually making the code send a header with empty filename.
I'd suggest you verify that your code uses the actual column name. i.e.:
header("Content-Disposition: attachment; filename=". $row['title']);
There is no row['name'] do you mean row['title']
You have these
$fileName = $_FILES['userfile']['name'];
$tmpName = $_FILES['userfile']['tmp_name'];
You have to rename/move $tmpName to $filename
EDITED
Check this
move_uploaded_file()
or change $fileName with $tmpName in the following block
$fp = fopen($fileName, 'r');
$content = fread($fp, filesize($fileName));
$content = addslashes($content);
fclose($fp);
Related
EDIT: This is a original code, that is working ok. sorry for formating.
<?php
$target = "images/";
if(!is_dir($target)) mkdir($target); $target = $target . basename( $_FILES['photo']['name']);
$uvod = $_POST['uvod']; $text = $_POST['text']; $nadpis = $_POST['nadpis']; $datum = date("Y-m-d");
if (isset($_POST['zobrazeno'])) {
$zobrazeno = 1; } else {
$zobrazeno = 0; }
$fname=($_FILES['photo']['name']); $funiquename = uniqid() . $fname; $tmpName = $_FILES['photo']['tmp_name']; $fileSize = $_FILES['photo']['size']; $fileType = $_FILES['photo']['type'];
$fp = fopen($tmpName, 'r'); $content = fread($fp, filesize($tmpName)); $content = addslashes($content); fclose($fp);
if(!get_magic_quotes_gpc()){ $fname = addslashes($fname);}
require_once 'db_config.php'; $db_server=mysql_connect($db_hostname,$db_username,$db_password);
if(!$db_server) die("Unable to connect to MySQL" .mysql_error());
mysql_select_db($db_database,$db_server) or die("Unable to connect to database" .mysql_error());
$sql = "INSERT INTO `aktuality` (`nadpis`, `uvod`, `text`, `datum`, `zobrazeno`, `obr_nazev`, `obr_pripona`, `obr_velikost`, `obr_data`) VALUES ('$nadpis', '$uvod', '$text', '$datum', '$zobrazeno', '$funiquename','$fileType','$fileSize','$content')";
mysql_query($sql);
if(move_uploaded_file($_FILES['photo']['tmp_name'], $target)) {
echo "The file ". basename( $_FILES['photo']['name']). " has been uploaded, and your information has been added to the directory";
} else {
echo "Sorry, there was a problem uploading your file.";
}
?>
Im a php beginner.
I have a problem with sending sql command as a string thru two php files.
This php file should call function sql_string() in sql.php, but there is nothing happens.
<?php
------some code here-------
include 'sql.php';
mysql_query(sql_string1());
------some code here------
?>
sql.php
<?php
function sql_string1()
{
$sql ="INSERT INTO `aktuality` (`nadpis`, `uvod`, `text`, `datum`, `zobrazeno`, `obr_nazev`, `obr_pripona`, `obr_velikost`, `obr_data`) VALUES ('$nadpis', '$uvod', '$text', '$datum', '$zobrazeno', '$funiquename','$fileType','$fileSize','$content')";
return $sql;
}
?>
Thanks for your help!
Try doing this for the query to work:
<?php
------some code here-------
include 'sql.php';
$sql = sql_string1() ;
mysql_query($sql) or die(mysql_error());
------some code here------
?>
You should also be able to see what the error is if that query failed.
I'm trying to download files via headers from my database. I'm not sure why my downloaded files are all corrupted when I change my download code to one that uses OOP but are fine when my code is non-OOP.
This is where I get the file id and call the download function:(handleDownload.php)
if (isset($_GET['id'])) {
$id = $_GET['id'];
//pump id into function getDBFiles to pull file with matching id
$fileData = $Download->getDBFiles($id);
header('Content-Type:"' . $fileData[2]. '"');
header('Content-Disposition: attachment; filename="' . $fileData[1]. '"');
echo $fileData[0];
exit;
}
This is the function that pulls the file from the database (download.php)
public function getDBFiles($id) {
global $database;
$sql = "SELECT * FROM ".self::$table_name." WHERE resume_id ='" . $id . "'";
$result = $database->query($sql);
if ($row = $result->fetch_array(MYSQLI_ASSOC)) {
$name = $row['resume_title'];
$type = $row['file_type'];
$content = $row['resume_data']; //content of file
//$size = $row['file_size']; //file size
return array($content, $name, $type);
}
}
$Download = new Download();
$download =& $Download;
The code works fine if it's all in one page as shown below though:
if (isset($_GET['id'])) {
$id = $_GET['id'];
mysqli_select_db($con, "apples");
$query = "SELECT * FROM resume where resume_id ='" . $id . "'";
$result = mysqli_query($con, $query) or die('Error, query failed');
if ($row = $result->fetch_array(MYSQLI_ASSOC)) {
$name = $row['resume_title'];
$type = $row['file_type'];
$content = $row['resume_data']; //content of file
$size = $row['file_size']; //file size
header('Content-Type:"' . $type . '"');
//header('Content-length:"' . $size . '"');
header('Content-Disposition: attachment; filename="' . $name . '"');
//var_dump($row);
echo $content;
}
}
UPDATE:
I'm now getting a download file is corrupted instead of a blank file. This is how the same file is outputted by the different download codes. The one on top is from the OOP code while the other is from the working non-OOP version.
This is my download code in its entirety.
try {
//execute retrieval of files from database
$Download-> showDBFiles();
//pass results to output array
$output = $Download->getMessages();
//if id is set then get file from database
if (isset($_GET['id'])) {
$id = $_GET['id'];
//pump id into function getDBFiles to pull file with matching id
$fileData = $Download->getDBFiles($id);
header('Content-Type:"' . $fileData[2]. '"');
header('Content-Disposition: attachment; filename="' . $fileData[1]. '"');
echo $fileData[0];
die();
}
} catch (Exception $e) {
$result[] = $e->getMessages();
}
After calling the functions, I would then echo out the output (the download links) with a foreach loop
<h2>Output</h2>
<?php if ($output) { ?>
<ul class="result">
<?php
foreach ($output as $message) {
$id = $message['id'];
$name = $message['name'];
?>
<li><?php echo $name; ?></li>
<?php }
?>
</ul>
In your non-OOP solution check for leading whitespaces inside the php file.
The following code would produce a corrupted file because of a leading whitespace.
<?php
if (isset($_GET['id'])) {...
This also applies to whitespaces after the closing php tag (which you should not use).
Those chars will be submitted by your browser, included in the download stream and corrupt the whole file.
This is the page where I click on the download button.
This is the things I found online but it did not work
why my downloaded file is alwayes damaged or corrupted?
Force Downloading a PDF file, corrupt file
$query = "SELECT id, name FROM docu";
$result = mysqli_query($con,$query) or die('Error, query failed');
if(mysqli_num_rows($result)==0){
echo "Database is empty <br>";
}
else{
while ( (list($id, $name) = mysqli_fetch_array($result, MYSQLI_BOTH))){
?>
<p>Name : <?= $name ?></p>
This is the download code. When I download the file, it say it is corrupted.
if(isset($_GET['id'])){
$id = $_GET['id'];
$con = mysqli_connect("localhost:3306", "waduser", "waduser", "fyp");
if(!$con) {
die("cannot connect: " . mysqli_error());
}
mysqli_select_db($con,"fyp");
$query = "SELECT * FROM docu where id ='" .$id ."'";
$result = mysqli_query($con,$query) or die('Error, query failed');
if($row = $result -> fetch_array(MYSQLI_ASSOC))
{
$name = $row['name'];
$type = $row['type'];
$content = $row['content']; //content of file
$size = $row['size']; //file size
header('Content-Type:"' . $type . '"');
header('Content-length:' . $size .'');
header('Content-Disposition: attachment; filename="' .$name. '"');
}
}
?>
I think what Jim is trying to say is that you have sent all the headers but you have not actually sent the file itself.
So try
$name = $row['name'];
$type = $row['type'];
$content = $row['content']; //content of file
$size = $row['size']; //file size
header('Content-Type:"' . $type . '"');
header('Content-length:' . $size .'');
header('Content-Disposition: attachment; filename="' .$name. '"');
echo $content;
Also I think its safer to remove the spaces around your short_tag usage at least in the href property.
<p>Name : <?= $name ?></p>
Here is my code. I am not getting an error statement, but the data is not inserted into the table. I tried running the query in PHPMyAdmin and it worked fine. It is also not because of user privileges.
if ($mysql->connect_errno) {
echo("Connect failed: ". $mysql->connect_error);
die();
}
echo "I am confused by this thing<br>";
if(isset($_POST['upload']) && $_FILES['userfile']['size'] > 0)
{
echo "Trying to figure out the errors!!!!<br>";
$fileName = $mysql->real_escape_string($_FILES['userfile']['name']);
$tmpName = $mysql->real_escape_string($_FILES['userfile']['tmp_name']);
$fileSize = intval($_FILES['userfile']['size']);
$fileType = $mysql->real_escape_string($_FILES['userfile']['type']);
echo $fileName."<br>";
echo $tmpName."<br>";
echo $fileSize."<br>";
echo $fileType."<br>";
//reads the file information
$fp = fopen($tmpName, 'r');
$content = fread($fp, filesize($tmpName));
$content = $mysql->real_escape_string(addslashes($content));
fclose($fp);
//this just adds slashes
This adds slashes
if(!get_magic_quotes_gpc())
{
$fileName = addslashes($fileName);
}
//This inserts into the databse
$query = "INSERT INTO upload VALUES ('', '$fileName', '$fileType', $fileSize, '$content')";
This is the line where the code messes up... It just hangs and never prints out the die message
$updateDB = $mysqli->query($query) or die($mysqli->error);
It never prints out this line.
echo "<br>File $fileName uploaded<br>";
}
You are working with $mysql object on the top and abruptly, you triggered your query on $mysqli object.
Change
$updateDB = $mysqli->query($query) or die($mysqli->error);
to
$updateDB = $mysql->query($query) or die($mysql->error);
I'm able to upload a file to mysql but when i download it, the content changes.. example i have test.txt with
"hello"
on it.. when i download it, the test.txt becomes
< pre class='xdebug-var-dump' dir='ltr'>string 'sfasfsafasfsaf' (length=14)
sfasfsafasfsaf
not sure, what's wrong..
this is my code for downloading the file:
<?php include("class_lib.php");
$db = new database();
$db->connect();
if(isset($_GET["file_id"])){
$file_id = $_GET["file_id"];
$query = "SELECT filename, filetype, filesize, bin_data " .
"FROM file_tbl WHERE id = '$file_id'";
$result = mysql_query($query) or die('Error, query failed' . mysql_error());
list($filename, $filetype, $filesize, $bin_data) = mysql_fetch_array($result);
var_dump($bin_data);
header("Content-length: $filesize");
header("Content-type: $filetype");
header("Content-Disposition: attachment; filename=$filename");
echo $bin_data;
}
?>
for images also, it downloads but there's no image anymore.. it only shows "no preview available".. is this with my download script above?
or maybe this upload script i have:
$fileid = (string) ($lastemp_id + 1);
$fileName = basename($_FILES['binFile']['name']);
$extension = pathinfo($fileName, PATHINFO_EXTENSION);
$fileName .= "_fileid_" . $fileid;
$fileName = $fileName.".".$extension;
$tmpName = $_FILES['binFile']['tmp_name'];
$fileSize = $_FILES['binFile']['size'];
$fileType = $_FILES['binFile']['type'];
$fileDesc = $_POST["txtDescription"];
$fp = fopen($tmpName, 'r');
$content = fread($fp, filesize($tmpName));
$content = addslashes($content);
fclose($fp);
if(!get_magic_quotes_gpc()){ $fileName = addslashes($fileName); }
if (isset($fileName)) {
$sql = "INSERT INTO file_tbl ";
$sql .= "(file_desc, bin_data, filename, filesize, filetype) ";
$sql .= "VALUES ('$fileDesc', '$content', ";
$sql .= "'$fileName', '$fileSize', '$fileType')";
mysql_query($sql, $db->connection) or die('Error: query failed' . mysql_error());
$message = "File uploaded.<br>"; var_dump($content);
}
else $message = "No file uploaded. (opt)";
what is wrong here exactly??
You're recklessly jamming binary data into your database without even a whiff of proper SQL escaping. What did you expect to happen? This short sample of code is so full of severe SQL injection bugs I hope for your sake it isn't deployed on the public internet.
For your own safety you should immediately stop using the creaky, old, deprecated mysql_query interface and spend the small amount of time necessary to switch your queries to PDO.
You would not have problems like this if you were using placeholders.
What you're seeing is probably the result of your spurious var_dump statement before you output your proper content.
Please try this, if upload file is flawless.
You can encode your binary data to 64 format when insert into database and also decode before download it.
<?php
ob_start();
include("class_lib.php");
$db = new database();
$db->connect();
if(isset($_GET["file_id"])){
$file_id = $_GET["file_id"];
$query = "SELECT filename, filetype, filesize, bin_data " .
"FROM file_tbl WHERE id = '$file_id'";
$result = mysql_query($query) or die('Error, query failed' . mysql_error());
list($filename, $filetype, $filesize, $bin_data) = mysql_fetch_array($result);
var_dump($bin_data);
ob_end_clean();
header("Content-length: $filesize");
header("Content-type: $filetype");
header("Content-Disposition: attachment; filename=$filename");
echo $bin_data;
exit;
}
?>