I'm writing a PHP program that will get an image from the filesystem and display it on the returned page. The catch is that the file isn't stored in the /var/www directory. It's stored in /var/site/images. How can I do this? Do I have to read it into memory with fopen, then echo the contents?
Use fpassthru to dump the contents from the file system to the output stream. In fact the docs for fpassthru contains a demo of exactly what you're trying to do: http://us3.php.net/fpassthru
<?php
// open the file in a binary mode
$name = './img/ok.png';
$fp = fopen($name, 'rb');
// send the right headers
// - adjust Content-Type as needed (read last 4 chars of file name)
// -- image/jpeg - jpg
// -- image/png - png
// -- etc.
header("Content-Type: image/png");
header("Content-Length: " . filesize($name));
// dump the picture and stop the script
fpassthru($fp);
fclose($fp);
exit;
?>
Related
How may I display an image without using any kind of HTML.
Let's say I have some protected images, which may only be shown to some users.
The protected image is in directory images/protected/NoOneCanViewMeDirectly.png
Then we have a PHP file in the directory images/ShowImage.php, which check if the user is permitted to view the image.
How may I display the image using PHP only.
If you're not sure what I mean this is how I want to display the image. http://gyazo.com/077e14bc824f5c8764dbb061a7ead058
The solution is not echo '<img src="images/protected/NoOneCanViewMeDirectly.png">';
You could just header out the image with the following syntax
header("Content-type: image/png");
echo file_get_contents(__DIR__."/images/protected/NoOneCanViewMeDirectly.png");
if (<here your logic to show file or not>)
$path = $_SERVER["DOCUMENT_ROOT"].<path_to_your_file>; // to get it correctly
$ext = explode(".", $path);
header("Content-Type: image/".array_pop($ext)); // correct MIME-type
header('Content-Length: ' . filesize($path)); // content length for most software
readfile($path); // send it
}
Note: 1. image/jpg is not correct MIME-type, use image/jpeg instead (additional check needed), 2. readlfile() is better than echo file_get_contents() for binary data, 3. always try to provide content length for browsers and other software
You can use imagepng to output png image to browser:
$im = imagecreatefrompng("images/protected/NoOneCanViewMeDirectly.png");
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
I want to create xlsx file and send to the browser as an attachment, so the user downloads it immediately. I literally did copy-paste the code from this example.
But it doesn't work. I fixed the path in require_once, but the issue is somewhere else.
The xlsx file is generated corerctly - when I save ot on the server, I can open it. It is also sent to the browser - firebug's console shows some funny characters in output window. The headers are also correct.
But no Save as... dialog is shown. I did some basic checks based on google search results - I have no extra white space after ?>.
The only difference in my code is that I call php script from jQuery's $.post function with some additional arguments.
Could it be the reason why I can't download this file?
Any help would be greatly appreciated!
PHP version: 5.4.20
PHPExcel version: 1.8.0
Server: Apache/2.4.6 (Linux/SUSE)
This question is also posted on codeplex.
You can't download files via an ajax request such as $.post for security reasons.
You could use a link that opens in a new window instead.
<?php
// If user click the download link
if(isset($_GET['filename'])){
// The directory of downloadable files
// This directory should be unaccessible from web
$file_dir="";
// Replace the slash and backslash character with empty string
// The slash and backslash character can be dangerous
$file_name=str_replace("/", "", $_GET['filename']);
$file_name=str_replace("\\", "", $file_name);
// If the requested file is exist
if(file_exists($file_dir.$file_name)){
// Get the file size
$file_size=filesize($file_dir.$file_name);
// Open the file
$fh=fopen($file_dir.$file_name, "r");
// Download speed in KB/s
$speed=50;
// Initialize the range of bytes to be transferred
$start=0;
$end=$file_size-1;
// Check HTTP_RANGE variable
if(isset($_SERVER['HTTP_RANGE']) &&
preg_match('/^bytes=(\d+)-(\d*)/', $_SERVER['HTTP_RANGE'], $arr)){
// Starting byte
$start=$arr[1];
if($arr[2]){
// Ending byte
$end=$arr[2];
}
}
// Check if starting and ending byte is valid
if($start>$end || $start>=$file_size){
header("HTTP/1.1 416 Requested Range Not Satisfiable");
header("Content-Length: 0");
}
else{
// For the first time download
if($start==0 && $end==$file_size){
// Send HTTP OK header
header("HTTP/1.1 200 OK");
}
else{
// For resume download
// Send Partial Content header
header("HTTP/1.1 206 Partial Content");
// Send Content-Range header
header("Content-Range: bytes ".$start."-".$end."/".$file_size);
}
// Bytes left
$left=$end-$start+1;
// Send the other headers
header("Content-Type: application/octet-stream");
header("Accept-Ranges: bytes");
// Content length should be the bytes left
header("Content-Length: ".$left);
header("Content-Disposition: attachment; filename=".$file_name);
// Read file from the given starting bytes
fseek($fh, $start);
// Loop while there are bytes left
while($left>0){
// Bytes to be transferred
// according to the defined speed
$bytes=$speed*1024;
// Read file per size
echo fread($fh, $bytes);
// Flush the content to client
flush();
// Substract bytes left with the tranferred bytes
$left-=$bytes;
// Delay for 1 second
sleep(1);
}
}
fclose($fh);
}
else
{
// If the requested file is not exist
// Display error message
echo "File not found!";
}
exit();
}
?>
Download.
You can use this code for download you can edit extension and also speed
Can anyone tell me why I am unable to display a PDF file using PHP? It says LOADING in lower left corner which never goes away. I can use the control panel and view the pdf just fine, so I know it's a valid PDF file.
Here's the code:
<?php
session_start();
$path = '/show_bills/';
// The location of the PDF file on the server.
$filename = $path.$_SESSION['ShowID']."_show_bill.pdf";
header("Content-type: application/pdf");
header("Content-Length: " . filesize($filename));
readfile($filename);
exit;
?>
Thanks,
Vic
I am almost sure the file just does not exist. You have a trailing slash in the $path meaning the the script will look for the file in the very root of the server
You can check whether the file exists or not using file_exists function
http://uk3.php.net/manual/en/function.file-exists.php
Also, just try to output the file without specifying headers - probably it outputs a PHP warning
When writing .csv files i use fputcsv like this:
- open a temporary file $f = tmpfile();
- write content to file using fputcsv($f,$csv_row);
- send appropriate headers for attachment
- read file like this:
# move pointer back to beginning
rewind($f);
while(!feof($f))
echo fgets($f);
# fclose deletes temp file !
fclose($f);
Another aproach would be:
- open file $f = fopen('php://output', 'w');
- send appropriate headers for attachment
- write content to file using fputcsv($f,$csv_row);
- close $f stream
My question is: What would be the best approach to output the data faster and taking into account server resources ?
First method would use more writes and consume more resources but would output very fast.
Second method uses less writes and would output slower i think.
Eagerly waiting for your opinions on this.
Thanks.
fpassthru() will do what you're doing at a lower level. Use it like this:
# move pointer back to beginning
rewind($f);
while(fpassthru($f) !== false);
# fclose deletes temp file !
fclose($f);
Even though it may be a csv file, there is no need to restrict yourself to csv functions, unless you are generating the file at the time of output.
You could probably see a performance gain if you stream the CSV to output instead of to a file.
Why do you need to write the csv content to a tmp file/php's output stream ?
You just need to echo the csv content directly, there should not be any file operations.
send appropriate headers for attachment
echo the csv content.
header("Content-type: application/csv");
header("Content-Disposition: attachment; filename=file.csv");
header("Pragma: no-cache");
header("Expires: 0");
foreach ($csv_rows as $csv_row) {
echo $csv_row;
}
exit;
First of all, let me say that I have no actionscript knowledge, but I have PHP knowledge.
How can I make a movieclip display an image from a php file?
And how can I send the image from the php file to the movieclip?
Do I echo it?
Alright, i know you could have just used the googles to look this up, but I'm gonna explain how to do it anyway.
How can I make a movieclip display an image from a php file?
<?php
// open the file in a binary mode
$name = './img/ok.png';
$fp = fopen($name, 'rb');
// send the right headers
header("Content-Type: image/png");
header("Content-Length: " . filesize($name));
// dump the picture and stop the script
fpassthru($fp);
exit;
This code was copy-pasta'd from the php.net manual. In short you should use fpassthru
How can I send the image from the php file to the movieclip?
Use the Loader class. An example is at the bottom of the page.