How to make temporary link for a downloadable file

二次信任 提交于 2019-12-03 06:55:53

Use some code like this

 $path="uploads/";
                  $actualfilename=$path.$filename;
                  $fakefilename="downloadfile.pdf";
                   if($typeofview=="download") {
                          @readfile($actualfilename);
                        header('Content-type: application/pdf');
                        header('Content-Disposition: attachment; filename="' . $fakefilename . '"');
                        header('Content-Transfer-Encoding: binary');
                        header('Content-Length: ' . filesize($actualfilename));
                        header('Accept-Ranges: bytes');
                        exit;

add this to your .htaccess file

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule fakefile.php(.*)$ orignalfile.php?$1 [L,QSA]

Link to something like /downloads/abb76b3acbd954a05bea357144d614b4, where abb... is a random string such as a salted hash of the current time. When you make this link for someone, store the random string in a database table. This table might look like:

+----+-------------+----------------------------------+---------------------+---------------------+
| id | filename    | token                            | created             | modified            |
+----+-------------+----------------------------------+---------------------+---------------------+
|  1 | image.jpg   | abb76b3acbd954a05bea357144d614b4 | 2012-03-26 19:36:41 | 2012-03-26 19:36:41 |
|  2 | program.exe | 19660d0f5e0ca3d42e1718de5d0a1d7e | 2012-08-29 11:07:58 | 2012-08-29 11:07:58 |
+----+-------------+----------------------------------+---------------------+---------------------+

When you get a request at /downloads/..., look up the random string and send back the correct file. If the created timestamp is too old, don't do so. Use a cronjob to clean out old table rows, or less ideally, do this every time someone makes a request to /downloads/....

The solution that comes to my mind is as follows: If you have table which represent file and for example FileModel you can save there name of the file, some details, size, also path to the file in your file system and unique, which can be result of md5 from some of data you choose for it based on some file details for example :

$data[FileModel]['unique'] = md5(time() . $data[FileModel]['file']);

Each time before letting someone download your file you check if there is such unique value in your table if so you let someone download it with ur downloadFile method created in FileModel, but just before that you make new unique to prevent from any more downloads

$data[FileModel]['unique'] = md5(time() . $data[$this -> name]['file']);
$this -> FileModel-> save($data[$this -> name]);
$this -> FileModel -> downloadFile($data[$this -> name]);

If there is no such unique value in ur database then you just show an error about timeouted link to the user

$this -> setFlashError('link expired');

Here I pase for you an example prototype of action which you can start with in your controller:

function download($file_data = ''){
        $data = $this->FileModel->find('first', array('conditions' => array('FileModel.unique' => $file), 'fields' => array('*')));

        if(!is_array($data[FileModel])) $this -> setFlashError('link expired');

        else
        {
            $data[FileModel]['unique'] = md5(time() . $data[$this -> name]['file']);
            $this -> FileModel-> save($data[$this -> name]);
            if(!$this -> FileModel -> downloadFile($data[$this -> name]))
            {
                $this -> setFlashError('error'));
            }
        }
}

Also you can create datetime field where you can for example add 1 day to current date and check wheter time left to download it expired.

the one i have found:

header('Content-Type: application/force-download');
$filee = "your_file.txt";
$filesLocation = dirname(__file__).'/the_sub_folder_for_the_file/'.$filee;
header('Content-Length:' . filesize($filesLocation));
header("Content-Disposition: inline; filename=\"".$filee."\"");
$filesPointer = fopen($filesLocation,"rb");
fpassthru($filesPointer);

i know this old question but i have way to download the file just 1 time without use database , fast way :)

if( isset($_GET['file']) && file_exists($_GET['file']) )
{
    $oldName = $_GET['file'];
    $newName = md5(time()).".txt";

    if( rename($oldName, $newName) ) { // rename file to download just once
        downloadFile( $newName ); // download file function
    } else {
        echo 'this file is not exist';
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!