Problems embedding PDF file sent with XSendFile in a webpage - php

I'd like to embed a PDF file in a webpage. I need to dynamically produce the PDF so I can authenticate the user first, so I'm using XSendFile on Apache. The PHP file I have works fine when I visit a browser with the PDF file being immediately offered for download. Here is the code I'm using (courtesy of http://www.brighterlamp.com/2010/10/send-files-faster-better-with-php-mod_xsendfile/)
// Get a list of loaded Apache modules
$modules = apache_get_modules();
if (in_array('mod_xsendfile', $modules)) {
// Use XSendFile if possible
header ('X-Sendfile: ' . $pathToFile);
header ('Content-Type: ' . $documentMIME);
header ('Content-Disposition: attachment; filename="' . $actualFilename . '"');
exit;
} else {
// Otherwise, use the traditional PHP way..
header ('Content-Type: ' . $documentMIME);
header ('Content-Disposition: attachment; filename="' . $actualFilename . '"');
#ob_end_clean();
#ob_end_flush();
readfile($pathToFile);
exit;
}
So far so good. Now I want to embed this PDF in a webpage using an object tag e.g.:
<object data="dynamicpdf.php" type="application/pdf">
<p>PDF embed failed</a></p>
</object>
But this fails. If I switch the data attribute to a static PDF file then it works fine.
Any ideas what is going wrong?

Is iframing the PDF an option for you?
Like <iframe src="dynamicpdf.php">
The Content-Disposition header forces the download. Remove it.
General Advise:
I would not use functions like apache_get_modules that asume a specific webserver environment.
What if you switch away from mod_php or apache in future? Your code will break.
Instead I would do the delivery in a streamed php response that is more memory efficient than output buffering the whole PDF into RAM and then send it.
By streaming the PDF out with PHP you would also have only one implementation and it would be same speed as x-sendfile is:
Streaming a large file using PHP

Related

Php header() User Agent Change

$file_name = $_GET['title'];
$file_url = $_GET['url'] . $file_name;
header('Content-Type: video/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"".$file_name."\"");
readfile($file_url);
exit;
I'm using this code to download files in my site fetching from another websites.
It works if my url looks like:-
https://www.example.com/video_download.php?title=video.mp4&url=http://googlevideo.com/video/download/223689/289048
(example)
So, it starts downloading by fetching the video file from http://www.googlevideo.com/video/play/221589 to my site.
But my problem is that the file can be accessed if the person uses a PC.
Can I change the User Agent by using header()?
Is it possible?
So if I change the user agent into a PC user agent, so it can be downloaded from a mobile!
I'm sorry, but the User Agent has nothing to do with readfile() function. Readfile() will just throw the raw file input into your browser. Useful for e.g. rendering images through PHP to the client without having to expose the real file name.
Indeed, it is possible to render video to the client with readfile(), but using a HTML5 video tag will dramatically improve performance. This will also provide better mobile support.
Hope this helps you,
You can use stream_compy_to_stream
$video = fopen($file_url);
$file = fopen('videos/' . $title . '.mp4', 'w');
stream_copy_to_stream($video, $file); //copy it to the file
fclose($video);
fclose($file);
I wrote a class for downloading youtube video files. you can find it here.

How to force download a file in PHP with multi-parallel download? [duplicate]

I'm trying to download multiple files using header() in a while loop, but only one file gets downloaded. Why?
while ($row = mysql_fetch_array($sql)) {
header('Content-Type: text/x-vcard');
header('Content-Disposition: attachment; filename=' . $row['name'] . '.vcf');
}
You can only transfer one file from server side at a time. Typical workarounds are:
tar/zip them up into one file on server side.
use javascript to window.open multiple files for download.
This is not possible. The HTTP protocol does not have support for downloading multiple files. The most common workaround is to put the files in a zip archive for the client to download.
headers ca be set only once before outputting any data.
As you loop you set some headers after that you must output something. In the next loop you will not set any headers.
Please read php.net

opening mp4 via php results in full download before playback

I'm trying to feed an mp4 file to flash player via php and the video is downloaded completely before starting playback.
$src = '/var/www/user/data/www/domain.com/video.mp4';
if(file_exists($src) and is_readable($src)) {
header('Content-Type: video/mp4');
header('Content-Length: '.filesize($src));
readfile($src);
} else die('error');
I've tried curl with similar results. Any ideas what's causing this delay?
Most likely your Flash player is hoping you'll handle HTTP Range requests so it can get started faster on the playback.
The HTML5/Flash audio player jPlayer has a section in their developer guide about this. Scroll to the part about Byte-Range Requests:
Your server must enable Range requests. This is easy to check for by
seeing if your server's response includes the Accept-Ranges in its
header.
Also note that they offer a PHP solution for handling Range requests if you have to use PHP instead of a direct download.
smartReadFile.php
https://groups.google.com/forum/#!msg/jplayer/nSM2UmnSKKA/bC-l3k0pCPMJ
Another option would be to just have apache send the file it self as opposed to reading it in php and dumping it to the output using X-Sendfile.
First make sure apache is compiled with sendfile support then alter your output code to be:
header ('X-Sendfile: ' . $src);
header ('Content-Type: video/mp4');
header ('Content-Disposition: attachment; filename="' . $filename . '"');
exit;
This is normally faster than doing it via PHP.

download simultaneously while displaying in pdf format

My intention is to convert a total php page into html, and subsequently convert the html to pdf and render it through the browser.Which is done , apart from that while showing it on the browser , it will simultaneously download the pdf automatically which is not happening.
Its with PHP.
Can to tell me the basic concept ..as to how to do this.
Thanks in advance
You already render the page in the browser. Before displaying the page, header() the user to the location which will serve the same page as an attachment, but do not exit. This will allow them to download the file, but it will still load the file on the page. Not 100% sure that this will work, but it's worth a shot.
BTW different browsers will handle pdfs differently and depending on settings, plugins, etc. For instance, some might try to download the file anyway instead of showing it in the browser.
I think you need to look over the question again. As I read it, you're asking how to display something that hasn't yet been downloaded (while it's downloading), and that is obviously not possible and so cannot be what you mean.
Try creating a header, which tells the browser what to do when it receives the file.
<?php
header("Content-Type: $filedatatype" );
header("Content-Disposition: attachment; filename=\"" . $FileObject->name . "\";");
header("Content-Transfer-Encoding:­ binary");
header("Content-Length: " . $filesize);
?>

Get output file with a .pdf extension in FPDF

This question is for those who have used PHP library FPDF (http://www.fpdf.org ) to generate PDF documents using PHP. I am generating a PDF file using the php file 'my_file.php'. I want users to be able to download that PDF file. But in the browser the see the file in the address bar as ..somepath..../my_file.php . I want them to see it as a file with .pdf extension. Any idea how this can be done ?
when you create the object and then try to make output like this
$filePath = "files/cache/myPdf.pdf";
$pdf=new FPDF('p');
...
$pdf->Output($filePath,'I');
you can change and send the file name
To force download:
$pdf->Output('D'); //Force download and set filename as 'doc.pdf'
or setting your own filename:
$pdf->Output('MyFilename.pdf','D');
Your browser shall not open another tab whit yourpath/my_file.php
You can't change the browser address bar, but you can change the address on your server. For example if you're using Apache, there's mod_rewrite which allows you to do such things.
If your problem is that when downloading the file, the browser wants to save it as .php, you could use those headers to force the download and a filename.
header('Content-Type: application/octet-stream');
header('Content-Length: ' . FILESIZE_HERE);
header('Content-Disposition: attachment; filename=' . FILENAME.pdf_HERE);

Categories