in my project I need to upload pdf file and download it afterwards.
everything works fine , but after i download the pdf file its been currupted and i can't view it.
if i try to open it with Adobe Acrobat Reader i get this error that says the file been currupted and didn't encoded correctly.
can someone help me to resolve this? thanks!
php script for download and upload:
<?php
// connect to the database
require_once 'connectionoop.php';
require_once 'core/init.php';
$query1 = sprintf("SELECT files.id, files.name,files.size ,files.downloads , association.Aname ,projects.Pname,files.project
FROM files
INNER JOIN projects ON files.project = projects.id INNER JOIN association ON projects.Aid = association.id
");
$result1 = $mysqli->query($query1);
$files=array();
foreach ($result1 as $row) {
$files[] = $row;
}
// Uploads files
if (isset($_POST['save'])) { // if save button on the form is clicked
// name of the uploaded file
$filename = $_FILES['myfile']['name'];
$proj = $_POST['Aid'];
// destination of the file on the server
$destination = 'uploads/' . $filename;
// get the file extension
$extension = pathinfo($filename, PATHINFO_EXTENSION);
// the physical file on a temporary uploads directory on the server
$file = $_FILES['myfile']['tmp_name'];
$size = $_FILES['myfile']['size'];
if (!in_array($extension, ['zip', 'pdf', 'docx'])) {
echo "You file extension must be .zip, .pdf or .docx";
} elseif ($_FILES['myfile']['size'] > 1000000) { // file shouldn't be larger than 1Megabyte
echo "File too large!";
} else {
// move the uploaded (temporary) file to the specified destination
if (copy($file, $destination)) {
$query = sprintf("INSERT INTO files (name, size, downloads , project) VALUES ('$filename', $size, 0,$proj)");
//execute query
$result = $mysqli->query($query);
$sql = "INSERT INTO files (name, size, downloads) VALUES ('$filename', $size, 0)";
$pr=new Project($proj);
$pr->update(array(
'hasfile' =>1
));
Redirect::to('downloads.php');
} else {
echo "Failed to upload file.<br>".$destination;
}
}
}
if (isset($_GET['file_id'])) {
$id = $_GET['file_id'];
$query2 = sprintf("SELECT * FROM files WHERE id=$id");
// fetch file to download from database
$result2 = $mysqli->query($query2);
$data = array();
foreach ($result2 as $row) {
$data[] = $row;
}
$filepath = 'uploads/' .$data[0]['name'];
if (file_exists($filepath)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($filepath));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize('uploads/' . $data['name']));
readfile('uploads/' . $data['name']);
// Now update downloads count
$newCount = $data['downloads'] + 1;
$query3 = sprintf("UPDATE files SET downloads=$newCount WHERE id=$id");
// fetch file to download from database
$result3 = $mysqli->query($query3);
exit;
}
}
It should be header("Content-type:application/pdf");
Related
I have a database table which stores the document file name and on the local pc i have a folder named as uploads which stores the actual files the user uploads.
The way i upload files are as follows,
$filename = $_FILES['attachment']['name'];
// destination of the file on the server
$destination = 'uploads/' . $filename;
// get the file extension
$extension = pathinfo($filename, PATHINFO_EXTENSION);
// the physical file on a temporary uploads directory on the server
$file = $_FILES['attachment']['tmp_name'];
$size = $_FILES['attachment']['size'];
if (!in_array($extension, ['zip', 'pdf', 'docx'])) {
echo "You file extension must be .zip, .pdf or .docx";
} elseif ($_FILES['attachment']['size'] > 1000000) { // file shouldn't be larger than 1Megabyte
echo "File too large!";
} else {
// move the uploaded (temporary) file to the specified destination
if (move_uploaded_file($file, $destination)) {
$sender_name = $_POST['sender_name'];
$contact = $_POST['contactnumber'];
$sender_mail = $_POST['sender_email'];
$description = $_POST['description'];
$applied = date('Y-m-d');
$jobapply = "INSERT INTO `job_submission`(`NAME`, `CONTACT`, `EMAIL`, `MESSAGE`,
`APPLIED_ON`, `CAREER_ID`,`CV`) VALUES
('$sender_name','$contact','$sender_mail','$description','$applied','$idc','$filename')";
if (mysqli_query($connect, $jobapply)) {
echo "You Application Was Submitted Successfully! We Wish You All The Best";
}
} else {
echo "Failed to upload file.";
}
}
The results of this code is the file name along with the other data are stored in the database and on the other hand the file is also stored in the uploads directory.
Now i want to download the file stored in the folder to the machine by using a button. for which I have written a code as follows,
if (isset($_GET['file_id'])) {
$id = $_GET['file_id'];
// fetch file to download from database
$sql = "SELECT * FROM job_submission WHERE JOB_ID='$id'";
$result = mysqli_query($connect, $sql);
$file = mysqli_fetch_assoc($result);
$filepath = 'uploads/' . $file['CV'];
if (file_exists($filepath)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . basename($filepath));
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize('uploads/' . $file['CV']));
readfile('uploads/' . $file['CV']);
exit;
}
}
The above code is called from a button inside a table,
<td>Download </td>
The file gets downloaded but it doesn't open and throws an error saying
Error Failed to load PDF document.
I'm trying to force a zip-file's download after some checks ( hash , expiration date, download's number ) .
The link of the page contains the id ( hash ) to validate the download.
For example:
www.example.com/download.php?id=505fbeabfd97c0ab15a016d68512d8df5acdedd6e6cc6
Everything works, but the file is corrupted.
If I try to eliminate all checks and the connection to the database, the zip downloaded is ok.
Here's the code:
<?php
$maxdownloads = "80";
// Set the key's viable duration in seconds (86400 seconds = 24 hours)
$maxtime = "2592000";
require ('connect.php');
if(get_magic_quotes_gpc()) {
$id = stripslashes($_GET['id']);
}else{
$id = $_GET['id'];
}
echo $id;
// Get the key, timestamp, and number of downloads from the database
$query = sprintf("SELECT * FROM digital_orders WHERE hash= '%s'",
mysqli_real_escape_string($conn,$id));
$result = $conn->query($query);
$row = $result->fetch_assoc();
if (!$row) {
echo "The download key you are using is invalid.";
}else{
$timecheck = date('U') - $row['date'];
echo $timecheck;
if ($timecheck >= $maxtime) {
echo "This key has expired (exceeded time allotted).<br />";
}else{
$downloads = $row['download'];
echo $downloads;
$downloads += 1;
if ($downloads > $maxdownloads) {
echo "This key has expired (exceeded allowed downloads<br/>";
}else{
$sql = sprintf("UPDATE digital_orders SET download .$downloads."' WHERE hash= '%s'",
mysqli_real_escape_string($conn,$id));
$incrementdownloads = $conn->query($sql);
$result->close();
// chiusura della connessione
$conn->close();
// Debug echo "Key validated.";
// Force the browser to start the download automatically
/*
Variables:
$file = real name of actual download file on the server
$filename = new name of local download file - this is what the visitor's file will actually be called when he/she saves it
*/
// Get parameters
$file = "dante.zip"; // Decode URL-encoded string
$filename = "foto.zip";
$filepath = "digital_orders/Dante/" . $file;
// Process download
if(file_exists($filepath)) {
ob_start();
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$filename.'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($filepath));
flush(); // Flush system output buffer
ob_end_clean();
readfile($filepath);
exit;
}
}
}
}
?>
If I try to open the zip file that works with note-pad there is :
PK
ûe‹L dante.txtPK
ûe‹L $ dante.txt
CdÔ‹‚ÑÓCdÔ‹‚ÑÓÆ‹‚ÑÓPK [
'
If I try to open the corrupted zip file there is:
505fbeabfd97c0ab15a016d68512d8df5acdedd6e6cc61226822PK
ûe‹L dante.txtPK
ûe‹L $ dante.txt
CdÔ‹‚ÑÓCdÔ‹‚ÑÓÆ‹‚ÑÓPK [
Any suggestion? '
I have a database that is storing all my pdf files for a website. The table has columns for the library_item_id, filename(name of the file), mime_type, File size, file_item(the Blob) and I have a php file called download.php. This file is supposed to download the correct file from the database when they user clicks the link. But when the file is downloaded and clicked to open I get Adobe saying it cannot open the pdf. Saying its not decoded correctly. Here is my download.php file:
require_once("scripts/connection.php");
if(isset($_GET["id"])){
$fid = $_GET["id"];
}
else{
header("Location: literature.php");
}
$sql= "SELECT filename, mime_type, file_item FROM library_items WHERE library_item_id = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param('s', $fid);
$stmt->execute();
$stmt->bind_result($filename, $mime, $file_item);
while($stmt->fetch()){
$file_name = $filename;
$mime_type = $mime;
$file = $file_item;
}
header("Content-length: ".strlen($file));
header("Content-type: $mime_type");
header("Content-disposition: download; filename=$file_name");
echo $file;
mysqli_close($conn);
I have tried everything I could think of including add the obj_flush() commands and all that it still gives me the same error. What am I doing wrong on this?
Here is the edit for the code inserting the file into the database.
session_start();
$display = trim($_POST["file-display-name"]);
$company = trim($_POST["companies"]);
$lib_cat = trim($_POST["library-cats"]);
if(empty($display) || empty($company) || empty($lib_cat)){
$_SESSION["errormsg"] = "Required information is missing please fill out all required fields.";
header("Location: ../library.php");
}
else{
$file_name = $_FILES['library-file']['name'];
$tmp_name = $_FILES['library-file']['tmp_name'];
$file_size = $_FILES['library-file']['size'];
$file_type = $_FILES['library-file']['type'];
$fp = fopen($tmp_name, 'r');
$content = fread($fp, filesize($tmp_name));
$content = addslashes($content);
fclose($fp);
if(!get_magic_quotes_gpc()){
$file_name = addslashes($file_name);
}
if(empty($content)){
$_SESSION["errormsg"] = "Required information is missing please fill out all required fields.";
header("Location: ../library.php");
}
else{
require_once("connection.php");
// Insert the logo into the companies photo table
$sql = "INSERT INTO library_items(filename, mime_type, file_size, file_item, display_name, company_id, library_category_id) VALUES(?,?,?,?,?,?,?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param('sssssss', $file_name, $file_type, $file_size, $content, $display, $company, $lib_cat);
if(!$stmt->execute()){
$_SESSION["errormsg"] = "Failed to add library item: ".mysqli_error();
header("Location: ../library.php");
}
}
unset($_SESSION["errormsg"]);
$_SESSION["successmsg"] = "Library Item successfully added into the database.";
header("Location: ../library.php");
}
UPDATE:
I now have the file downloading and attempting to display once the downloaded file is double clicked to open. It is telling me there is an invalid colorSpace. From what I can tell this is a problem when the file is uploaded into the database. From my upload file posted is there anything I am not doing correctly?
You need following changes. In the insert file
Instead of
$content = addslashes($content);
use
$content = base64_encode($content);
So while downloading, decode it.
$file = base64_decode($file_item);
Replace the following code
header("Content-type: '".$mime_type."'");
header("Content-Disposition: inline; filename='".$file_name."'");
header('Content-Transfer-Encoding: binary');
header('Accept-Ranges: bytes');
readfile($file);
with
header("Content-length: ".strlen($file));
header("Content-type: $mime_type");
header("Content-disposition: download; filename=$file_name");
echo $file;
check if size of downloaded file is correct (matches size of file in database). If it is, you should be debugging the part where the file is inserted into database. If not - check if anything gets printed out before sending file to browser - maybe scripts/connection.php prints something like empty line, error message or BOM?
If you can't find it, try turning output buffering on and call ob_clean() before sending file.
Sorry for my english, I hope it's understandable.
I have created a upload form and a php file which extract the name, size, type of the file and stores it in a database upload script, in table files. The file is also given a uniqid which is also stored in the same table.
Now I am trying to build up a download.php file where I want that when a specific link with the uniqid in is opened the script look in databse for the file searching for the uniqid and show the information against it.?
Here is my upload.php
<?php
include('config.php');
function bytesToSize1024($bytes, $precision = 300) {
$unit = array('B','KB','MB');
return #round($bytes / pow(1024, ($i = floor(log($bytes, 1024)))), $precision).' '.$unit[$i];
}
$FileName = $_FILES['filename']['name'];
$FileType = $_FILES['filename']['type'];
$FileSize = bytesToSize1024($_FILES['filename']['size'], 1);
$Fileid = uniqid(rand());
$tmp_name = $_FILES["filename"]["tmp_name"];
if ($_FILES["filename"]["error"] > 0)
{
echo "Apologies, an error has occurred.";
echo "Error Code: " . $_FILES["fileToUpload"]["error"];
}
else
{
move_uploaded_file($_FILES["filename"]["tmp_name"],
"C:\wamp\www\upload\upload" . $_FILES["filename"]["name"]);
}
$query2 = "INSERT INTO files (id, name, size, type) VALUES ('$Fileid', '$FileName', '$FileSize', '$FileType')";
$result2 = mysql_query($query2);
echo <<<EOF
<p>Your file: {$FileName} has been successfully received.</p>
<p>Type: {$FileType}</p>
<p>Size: {$FileSize}</p>
<p>Temp Foler: {$tmp_name}</p>
<p>Download Link: localhost/upload/download.php?=$Fileid
EOF;
?>
Please first tell me which kind of link I should create like. localhost/download.php?=uniqid
will the above example work and how to make it work. I am confused?
Here I have tried to create a download.php file but it is not good
<?php
include('config.php');
$query = "SELECT * FROM files";
$result = mysql_query($query);
$row = mysql_fetch_array($result);
?>
<?php
echo <<<EOF
File Name: <?php echo $row['name']; ?>
$row
EOF;
?>
This is the code you need. Consider storing byte count in the database for file size.
Of course it might need some changes to be exactly what you want.
<?php
include('config.php');
//get id from GET method and make sure that it's safe to be used in the query
$id=mysql_real_escape_string($_GET['id']);
$query = "SELECT * FROM `files` WHERE `id`='$id'";
$result = mysql_query($query);
$row = mysql_fetch_array($result);
if (count($row)!=1) //check if our unique record has been found
die('Sorry but we could not find this file!');
$row=$row[0];
//send download headers
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.$row['name']);
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate');
header('Pragma: no-cache');
header('Content-Length: ' .$row['size']);
readfile(upload" . $row['name']); //I recommend you to change the path and file name of your uploaded files!
?>
Link example: http://yourdomain.com/download.php?id=123
I can't seem to download my files online which I'm uploading into a MySQL database I only get plain text, vague signs mostly. In localhost though downloading is no problem. I checked my database online and locally both are uploaded good in the upload table. I'll show you Upload.php(It's not called that in real, and this is also not the entire script, It's a big script) first:
if (isset($_POST['verstuur'])) {
$id = NULL;
if($_FILES['userfile']['size'] > 0)
{
$fileName = $_FILES['userfile']['name'];
$tmpName = $_FILES['userfile']['tmp_name'];
$fileSize = $_FILES['userfile']['size'];
$fileType = $_FILES['userfile']['type'];
$fp = fopen($tmpName, 'r');
$content = fread($fp, filesize($tmpName));
$content = addslashes($content);
fclose($fp);
if(!get_magic_quotes_gpc())
{
$fileName = addslashes($fileName);
}
$query = "INSERT INTO upload (name, size, type, content ) ".
"VALUES ('$fileName', '$fileSize', '$fileType', '$content')";
mysql_query($query) or die('Fout, query mislukt');
$query = "SELECT LAST_INSERT_ID() ID";
$result = mysql_query($query);
while($row = mysql_fetch_array($result)){
$id = $row['ID'];
}
}
Okay so I have another script where I create the download link:
$query = "SELECT U_ID, name FROM upload WHERE U_ID = '$opvraag[U_ID]'";
$result = mysql_query($query) or die('Error, query failed');
if(mysql_num_rows($result) == 0)
{
echo "<td>Geen Bijlage</td>";
}
else
{
while(list($id, $name) = mysql_fetch_array($result))
{
echo '<td>'.$name.'</td>';
}
}
And Last I have download.php
if(isset($_GET['id']))
{
$id = $_GET['id'];
$query = "SELECT name, type, size, content " .
"FROM upload WHERE U_ID = '$id'";
$result = mysql_query($query) or die('Fout, query mislukt');
list($name, $type, $size, $content) = mysql_fetch_array($result);
header("Content-length: $size");
header("Content-type: $type");
header("Content-Disposition: attachment; filename=$name");
echo stripslashes($content);
exit;
}
The Database Table:
Name: Type:
U_ID int(8) AUTO_INCREMENT
name varchar(255)
size int(8)
type text
content blob
Can you try replacing your 3 calls to headers() in your download.php with this:
header("Accept-Ranges: bytes");
header("Keep-Alive: timeout=15, max=100");
header("Content-Disposition: attachment; filename=$name");
header("Content-type: $type");
header("Content-Transfer-Encoding: binary");
header( "Content-Description: File Transfer");