I have a small problem with the php content-disposition, I kind of understand where the problem lies but I have no idea how to solve it (new to using databases). Calling this php page will result in not showing any of the echos and only showing the download box, which I intended for the "cv" only (not sure if it's working that way, because the downloadable file I receive cannot be opened)
Removing the header(content... line will result in showing the echos, but I won't be able to download the specified file. I want it to show as a link which would download its contents when clicked.
$newEmployeeName = $_POST['name'];
$newEmployeeArea = $_POST['area'];
$newEmployeeCV = $_POST['cv'];
include('databaseConnection.php');
$result = mysql_query("SELECT * FROM participants");
while($row = mysql_fetch_array($result))
{
$download_me = $row['cv'];
header("Content-Disposition: attachment; filename=$download_me");
echo $row['name'] . " " . $row['area_of_exp'] . " " . $download_me;
echo "<br />";
}
The Content-Disposition header will force the script to present anything echoed after it as a download. You would normally use this with reading a file from the file system, so you can offer that as a download. In your case, if you’re storing CVs on your server then you may offer them as a download as follows:
<?php
$sql = "SELECT * FROM table WHERE id = :id LIMIT 1";
$stmt = $db->prepare($sql);
$stmt->bindParam(':id', $id, PDO::PARAM_INT);
$stmt->execute();
$row = $stmt->fetchObject();
if ($row) {
header('Content-Disposition: attachment; filename=' . $row['filename']);
readfile($uploads_dir . $row['filename']);
exit;
}
else {
die('Invalid CV requested.');
}
Obviously the above is a simplified version of the process and you will need to tweak it to fit your application, but that’s the gist of it.
Also, don’t use the mysql_ functions. They’re deprecated (as per the warning on this page). Use either PDO or the new MySQLi (MySQL improved) extension.
Related
This is the image data retrieved from the database.
I want this to be the file name which is downloadable when clicked:
Here is my code for uploading the image:
if(isset($_POST['submit'])) {
include 'db1.php';
if(count($_FILES) > 0) {
if(is_uploaded_file($_FILES['userImage']['tmp_name'])) {
$docFile =addslashes(file_get_contents($_FILES['userImage']['tmp_name']));
$filetype = getimageSize($_FILES['userImage']['tmp_name']);
$docCode = $_POST['docCode'];
$docType = $_POST['docType'];
$subject = $_POST['subject'];
$comment = $_POST['comment'];
$dateWrit = $_POST['dateWrit'];
$signatory = $_POST['signatory'];
$sql = "INSERT INTO document (docCode, docType, docFile,fileType, subject, dateWrit, signatory,comment, status,staffid)
VALUES ('$docCode', '$docType', '{$docFile}','{$filetype['mime']}', '$subject', '$dateWrit', '$signatory','$comment', 'Unsent', '".$_SESSION['staffid']."')";
if ($conn->query($sql) === TRUE) {
echo "<script type='text/javascript'>alert('Succesfully added!')</script>";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
$conn->close();
and I called the data from the database:
echo "<tr><td>".$row['docCode']."</td>
<td>".$row['docType']."</td>
<td>".$row['subject']."</td>
<td>".$row['dateWrit']."</td>
<td>".$row['signatory']."</td>
<td> <a href=".$row['docFile']." download>".$row['docFile']."</a></td>
<td>".$row['comment']."</td>
<td>".$row['status']."</td>";
You can't dump a raw image into an href attribute and turn it into a download. The href is supposed to store a URL, not raw data.
You're going to have to set up a handler page to echo out the image data and apply appropriate headers. For example, set up a page that retrieves the image data in $row, then do something like this:
<?php
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file_url) . "\"");
// TODO: get the image here, based on some $_GET or $_POST parameter, and
// load it into $row
echo $row['docFile'];
(The above code is not meant to be exact, as the code in your question is pretty unclear regarding how you set $row and where, if anywhere, you save the image's name.)
Also, very important: you are wide open to SQL injection. Please read about it and use prepared statements to avoid having someone hack or hose your database.
Finally, be aware that many people consider it best practice note to store binary blobs (like images) in the database, but only a path to the file on the system. Passing binary data back and forth causes lots of problems, not least of which is bloating your database and putting a lot of load on it whenever you want to read an image.
as I was trying to load an image from the database on my dev environment, wasn't able to load the image instead giving back error saying "Image cannot be displayed because it contains errors."
<?php
require_once 'app_config.php'; //app config file
require_once 'database_connection.php'; //database connection
try{
//Get the image id.
if(!isset($_REQUEST['image_id'])){
handle_error("No image to load was specified.");
}
$image_id = $_REQUEST['image_id'];
//Build the SELECT statement
$select_query = sprintf("SELECT * FROM images WHERE image_id = %d", $image_id);
//Run the query
$result = mysql_query($select_query);
//Get the result and handle errors from getting no result
if(mysql_num_rows($result) == 0){
handle_error("We couldn't find the requested image.", "No image found with and ID of " . $image_id . ".");
}
$image = mysql_fetch_array($result);
//Tell the browser what's coming with headers
header('Content-type: ' . $image['mime_type']);
header('Content-length: ' . $image['file_size']);
echo $image['image_data'];
}catch(Exception $exc){
handle_error("Something went wrong loading your image.",
"Error loading image: " . $exc->getMessage());
}
?>
How are you encoding your image data when you store it? I'd recommend you try to base64_decode() it, as that's a common way image data is transmitted/stored.
echo base64_decode($image['image_data']);
exit;
$sql = mysql_query("SELECT * FROM images WHERE image_id = %d", $image_id");
header("Content-Type: image/jpeg");
$row = mysql_fetch_row($sql);
$im=imagecreatefromstring($row[$i]);
imagejpeg($im).'<br>';
echo("<img src=\"$im.$name\" width=\"200\" height=\"150\" />");
this might work..
I've seen this error on perfectly legitimate images when the image uses a CMYK colorspace - which many/most browsers do not support. Try loading the original image directly in the browser (without the PHP/DB process) and see if it throws the same error. If it does you should convert the image to RGB using an image editor (or imagemagick if you want to do it server-side).
This is also a known issue with certain FF extensions, namely Skype. Try disabling extensions or another browser to see if this issue affects you.
I have all my files stored in a mysql database as blobs. I am trying to add a speed limit to the rate at which a user can download them through our PHP website. I have tried to use the "sleep(1);" method, it does not seem to work or i am not doing it right. So if anyone knows a way to limit the speed, i would love your help.
Here is my download code
$query=mysql_query("SELECT * FROM file_servers WHERE id='$file_server_id'");
$fetch=mysql_fetch_assoc($query);
$file_server_ip=$fetch['ip'];
$file_server_port=$fetch['port'];
$file_server_username=$fetch['username'];
$file_server_password=$fetch['password'];
$file_server_db=$fetch['database_name'];
$connectto=$file_server_ip.":".$file_server_port;
if (!$linkid = #mysql_connect($connectto, $file_server_username, $file_server_password, true))
{
die("Unable to connect to storage server!");
}
if (!mysql_select_db($file_server_db, $linkid))
{
die("Unable to connect to storage database!");
}
$nodelist = array();
// Pull the list of file inodes
$SQL = "SELECT id FROM file_data WHERE file_id='$file_id' order by id";
if (!$RES = mysql_query($SQL, $linkid))
{
die("Failure to retrive list of file inodes");
}
while ($CUR = mysql_fetch_object($RES))
{
$nodelist[] = $CUR->id;
}
// Send down the header to the client
header("Content-Type: $data_type");
header("Content-Length: $size");
header("Content-Disposition: attachment; filename=$name");
// Loop thru and stream the nodes 1 by 1
for ($Z = 0 ; $Z < count($nodelist) ; $Z++)
{
$SQL = "select file_data from file_data where id = " . $nodelist[$Z];
if (!$RESX = mysql_query($SQL, $linkid))
{
die("Failure to retrive file node data");
}
$DataObj = mysql_fetch_object($RESX);
echo $DataObj->file_data;
}
One way of doing this may be the combination of flush and sleep:
read part of what you get from database
output some bytes
flush the output to the user
sleep for 1 second
But also take a loot at throttle function:
http://php.net/manual/en/function.http-throttle.php
It also have an example there. I think it is better suited.
it is in the very last echo line in your code where you would like to implement throtling. Im not familiar with whether php supports throtling output.
if not, you can try to split up that content ($DataObj->file_data) you wish to echo, and echo it little piece by little piece with small pauses in between
and be sure to disable outbut buffering. otherwise all that you echo will not be outputted until the entire script is done.
Here is my code for downloading attachment from Salesforce.com using php toolkit and enterprise wsdl:
header('Content-Type: application/force-download');
header('Content-Disposition: inline; filename="image.jpg"');
$mySforceConnection = getConnection();
$query = "SELECT Id, Name, Body from Attachment Where Id ='" .$id ."'";
$queryResult = $mySforceConnection->query($query);
$records = $queryResult->records;
print_r(base64_decode($records[0]->fields->Body));
When I do this the file gets downloaded correctly with correct number of bytes but when I open the image, the windows image viewer says its corrupt. Any idea why this is happening?
The same code works fine for PDFs and text files.
You really want to just echo the output, as #eyescream mentioned. When you use the print_r function, additional tab and newline characters are placed into the output to make it more readable. A plain echo would output properly.
header('Content-Type: application/force-download');
header('Content-Disposition: inline; filename="image.jpg"');
$mySforceConnection = getConnection();
$query = "SELECT Id, Name, Body from Attachment Where Id ='" .$id ."'";
$queryResult = $mySforceConnection->query($query);
$records = $queryResult->records;
echo base64_decode($records[0]->fields->Body);
Using the above technologies, I want to create a PDF, store it in my db, and email it. All with the click of one button.
I also want to call it up and have it be able to display with a hyperlink.
I am very new to FPDF. Therefore, I am trying to start off very slowly.
I began with this link stackoverflow Q
I put both parts of his code into the same page and tried with separate pages. I made the suggested changes/additions and even did a line by line comparison.
I still get the message, "format error: not a PDF or corrupted"
If I just $pdf->Output(); I get the pdf to display. It's either the way the string is being Output, or it's the header() function. It's not the storage method, unless my column setup is incorrect. BUt a blob is a blob, right?
If you want, I can upload the sanitized code. Just let me know what would help answer this.
Thanks
JJ
here's the code on request
here's where I enter it in:
<?php
session_start();
include "server.php";//my file to connect to db
require('fpdf.php');
$pdf=new FPDF();
$pdf->AddPage();
$pdf->SetFont('Arial','B',16);
$pdf->Cell(40,10,'Hello World!');
$content = $pdf->Output("", "S"); //return the pdf file content as string
$sql = "update table set table_pdf= '".addslashes($content)."' " .
"where table_id = '188'";
mysql_query($sql);
//here's where I retrieve it
$sql2 = "select table_pdf from table where table_id = '188'";
$result2 = mysql_query($sql2);
$rs = mysql_fetch_assoc($result2);
$content2 = $rs['rdngs_hdr_pdf'];
header('Content-Type: application/pdf');
header("Content-Length: ".strlen(content2));
header('Content-Disposition: attachment; filename=myfile.pdf');
print $content2;
?>
Like I said, I have tried the other ideas on the other question link above. right now it just sits on the version where the addslashes is there.
Thanks for any help.
Give this a try. Instead of using the addslashes to escape the content, try using unpack to get it in a binary represenation:
$content = $pdf->Output("", "S"); //return the pdf file content as string
$data = unpack("H*hex", $content);
$sql = "update table set table_pdf= " . 0x".$data['hex']." . " " .
"where table_id = '188'";
For retrieving the data you should be able to just do a select, and then output the content, just like you are already doing.