Jump to content

A question for PHP, how to make a temp link to file?

QQ_cazo
Go to solution Solved by mariushm,

You would send the required headers and then send the file to the user either by using function readfile or by opening the file and then looping through reading a chunk and outputting a chunk until you're at the end of file.

 

The minimum you'd need to send is content-type  ("video/mp4" for mp4 files) and content-length (can be determined using filesize function or fstat function once you open the file) headers.

This allows the browser to start running the mp4 file in the browser or whatever player is configured.

 

To force download you need to add a few headers... for example

 

<?php
$file = 'monkey.gif';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="'.basename($file).'"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}
?>

Code above is from readfile function documentation.

The content-disposition is mostly what pushes browser into popping the save as box, and the last things are to force proxies and local browser caches to not cache the file.

 

Note that such code doesn't support resume ... to add resume support, your code would need to initially tell the browser that it supports resume or starting download from a random position in the file, by sending the header "Accept-Ranges: bytes"

Then the browser would be able to send the "Range: bytes=x-y"  that you have to read in your code and take out the x (read from x byte) and y (read until y byte) from the string and validate them  (make sure both are not outside the file size, if y is outside you would limit it to end of file).  (though browser can send multiple ranges but whatever, start simple and then cover all situations later)

Then you can use fopen to open the file, fseek to go to that position in the file, and then start reading chunks and sending them.

Here's an example from stack overflow , Theo's answer with 109 score - https://stackoverflow.com/questions/157318/resumable-downloads-when-using-php-to-send-the-file

Though note he's using fread to read the whole range, which could be the whole 1 GB mp4 file and your script would run out of memory because fread tries to put the whole amount in a string. You'd do fread with some small amount like 512 KB - 4 MB and loop until you read the amount of bytes specified in the range request.

 

There's also a "library" written by someone that handles Resume for you : https://github.com/DaveRandom/Resume

 

 

 

 

 

You would send the required headers and then send the file to the user either by using function readfile or by opening the file and then looping through reading a chunk and outputting a chunk until you're at the end of file.

 

The minimum you'd need to send is content-type  ("video/mp4" for mp4 files) and content-length (can be determined using filesize function or fstat function once you open the file) headers.

This allows the browser to start running the mp4 file in the browser or whatever player is configured.

 

To force download you need to add a few headers... for example

 

<?php
$file = 'monkey.gif';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="'.basename($file).'"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}
?>

Code above is from readfile function documentation.

The content-disposition is mostly what pushes browser into popping the save as box, and the last things are to force proxies and local browser caches to not cache the file.

 

Note that such code doesn't support resume ... to add resume support, your code would need to initially tell the browser that it supports resume or starting download from a random position in the file, by sending the header "Accept-Ranges: bytes"

Then the browser would be able to send the "Range: bytes=x-y"  that you have to read in your code and take out the x (read from x byte) and y (read until y byte) from the string and validate them  (make sure both are not outside the file size, if y is outside you would limit it to end of file).  (though browser can send multiple ranges but whatever, start simple and then cover all situations later)

Then you can use fopen to open the file, fseek to go to that position in the file, and then start reading chunks and sending them.

Here's an example from stack overflow , Theo's answer with 109 score - https://stackoverflow.com/questions/157318/resumable-downloads-when-using-php-to-send-the-file

Though note he's using fread to read the whole range, which could be the whole 1 GB mp4 file and your script would run out of memory because fread tries to put the whole amount in a string. You'd do fread with some small amount like 512 KB - 4 MB and loop until you read the amount of bytes specified in the range request.

 

There's also a "library" written by someone that handles Resume for you : https://github.com/DaveRandom/Resume

 

 

 

 

 

Link to comment
Share on other sites

Link to post
Share on other sites

13 hours ago, mariushm said:

You would send the required headers and then send the file to the user either by using function readfile or by opening the file and then looping through reading a chunk and outputting a chunk until you're at the end of file.

 

The minimum you'd need to send is content-type  ("video/mp4" for mp4 files) and content-length (can be determined using filesize function or fstat function once you open the file) headers.

This allows the browser to start running the mp4 file in the browser or whatever player is configured.

 

To force download you need to add a few headers... for example

 

<?php
$file = 'monkey.gif';

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="'.basename($file).'"');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}
?>

Code above is from readfile function documentation.

The content-disposition is mostly what pushes browser into popping the save as box, and the last things are to force proxies and local browser caches to not cache the file.

 

Note that such code doesn't support resume ... to add resume support, your code would need to initially tell the browser that it supports resume or starting download from a random position in the file, by sending the header "Accept-Ranges: bytes"

Then the browser would be able to send the "Range: bytes=x-y"  that you have to read in your code and take out the x (read from x byte) and y (read until y byte) from the string and validate them  (make sure both are not outside the file size, if y is outside you would limit it to end of file).  (though browser can send multiple ranges but whatever, start simple and then cover all situations later)

Then you can use fopen to open the file, fseek to go to that position in the file, and then start reading chunks and sending them.

Here's an example from stack overflow , Theo's answer with 109 score - https://stackoverflow.com/questions/157318/resumable-downloads-when-using-php-to-send-the-file

Though note he's using fread to read the whole range, which could be the whole 1 GB mp4 file and your script would run out of memory because fread tries to put the whole amount in a string. You'd do fread with some small amount like 512 KB - 4 MB and loop until you read the amount of bytes specified in the range request.

 

There's also a "library" written by someone that handles Resume for you : https://github.com/DaveRandom/Resume

 

 

 

 

 

A samll followup question, how do i make the video "preview" instead of download? (like act as a real file in the browser, not just to javascript)

 

== edit ==

 

Here is what changes i made to make it do what i want(ed?) it to do:

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: '.mime_content_type($file));
    // get mime type of file.
    header('Content-Disposition: inline; filename="'.basename($file).'"');
	//changed attachment to inline to prevent download.
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    readfile($file);
    exit;
}

 

Link to comment
Share on other sites

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×