Web студия "GrandView"
  Главная   Написать Контакты
   
   
О проекте
Руководство php
 

readfile

(PHP 3, PHP 4, PHP 5)

readfile -- Выводит файл

Описание

int readfile ( string filename [, bool use_include_path [, resource context]] )

Читает файл и записывает его в буфер вывода.

Возвращает количество прочитанных из файла байт. В случае возникновения ошибки вернёт FALSE, если только функция не была вызвана как @readfile(), и выведет сообщение об ошибке.

Подсказка: Для этой функции вы можете использовать URL в качестве имени файла, если была включена опция "fopen wrappers". Смотрите более подробную информацию об определении имени файла в описании функции fopen(), а также список поддерживаемых протоколов URL в Прил. M.

Вы можете установить в TRUE необязательный второй аргумент, если вы также хотите попытаться найти файл в include_path.

См. также описание функций fpassthru(), file(), fopen(), include(), require(), virtual(), file_get_contents() и Прил. M.



readlink> <popen
Last updated: Fri, 26 Jan 2007
 
add a note add a note User Contributed Notes
readfile
lcampanis.com
31-Oct-2007 02:55
If you are trying to force a download from a script and you're having corrupted files, but the download was successful, just make sure you don't have spaces or news lines before and/or after <? script ?>

You can check this by opening your download with a text editor. If you see empty lines or spaces at the top, then that's the problem.
Hayley Watson
17-Oct-2007 09:27
To avoid the risk of choosing themselves which files to download by messing with the request and doing things like inserting "../" into the "filename", simply remember that URLs are not file paths, and there's no reason why the mapping between them has to be so literal as "download.php?file=thingy.mpg" resulting in the download of the file "thingy.mpg".

It's your script and you have full control over how it maps file requests to file names, and which requests retrieve which files.

But even then, as ever, never trust ANYTHING in the request. Basic first-day-at-school security principle, that.
Sohel Taslim
02-Aug-2007 02:44
If you use session and Secure Site(SSL- Secure Sockets Layer) to download files using PHP function readfile(), You can get an error message for Inetrnet Explorer (IE).
To avoid this problem try following function.
Hope it can help you. By, sohel62 at yahoo dot com.

<?php

session_cache_limiter
('none'); //*Use before session_start()
session_start();

$file = 'ASDFGgg.pdf';
_Download("files_dir/".$file, $file);

function
_Download($f_location,$f_name){
    
header ("Cache-Control: must-revalidate, post-check=0, pre-check=0");
   
header('Content-Description: File Transfer');
   
header('Content-Type: application/octet-stream');
   
header('Content-Length: ' . filesize($f_location));
   
header('Content-Disposition: attachment; filename=' . basename($f_name));
   
readfile($f_location);
 }

?>
hamdiya dot dev at gmail dot com
17-Jul-2007 09:41
Using FTP is also possible with readfile.

readfile('ftp://'.$ftp_user.':'.$ftp_pass.'@'.$ftp_host.'/'.$file);
Sinured
17-Jul-2007 06:00
In response to "grey - greywyvern - com":

If you know the target _can't_ be a remote file (e.g. prefixing it with a directory), you should use include instead.
If the user manages to set the target to some kinda config-file (configuration.php in Joomla!), he will get a blank page - unless readfile() is used. Using include will just behave as a normal request (no output).
For remote files however use readfile().
Kniht
07-Jul-2007 11:27
@Elliott Brueggeman
What's the point of a user's settings if not to determine their environment? If they have it set a specific way, honor their setting.
Elliott Brueggeman
25-Jun-2007 08:47
I have noticed some unusual behavior with Internet Explorer 6 that’s worth taking note of. I have a link on my site to a script that outputs an XML file to the browser with the below code:

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.$filename.'"');
@readfile($file);

When the popular IE setting “Reuse Window for Launching Shortcuts” is unchecked (access this setting in the Tools Menu > Internet Options > Advanced Tab) this script will output the file to the browser and open it in a different window if the user clicks the open button on the IE prompt. However, if this setting is checked, and browser windows are being re-used, then it will open up on top of the page where the link was clicked to access the script.

If I instead set the html link target option to be “_blank”, the script will open up in a new window as expected if the “Reuse Window for Launching Shortcuts” is checked. But, if the setting is unchecked, the output XML file will open up in a new window and there will be another blank window also open that has the address of the script, in addition to our original window.

This is far from ideal, and there is no way of knowing whether users have this option checked or not. We are stuck with the distinct possibility of half of our visitors seeing either an annoying third blank window being opened or the script writing over their original window, depending on their “Reuse Window for Launching Shortcuts” setting.
chad 0x40 herballure 0x2e com
17-May-2007 07:53
In reply to herbert dot fischer at NOSPAM dot gmail dot com:

The streams API in PHP5 tries to make things as efficient as possible; in php-5.1.6 on Linux, fpassthru is faster than 'echo fread($fp, 8192)' in a loop, and readfile is even faster for files on disk. I didn't benchmark further, but I'd be willing to bet non-mmap'able streams still win because they can loop in C instead of PHP.
MasterQ at 127 dot 0 dot 0 dot 1
22-Apr-2007 07:40
Do not forgot to call
exit;
after readfile else you will get trouble with the file checksum of the file, because there will be added \n at the end of the script.
mAu
10-Oct-2006 12:25
Instead of using
<?php
header
('Content-Type: application/force-download');
?>
use
<?php
header
('Content-Type: application/octet-stream');
?>
Some browsers have troubles with force-download.
ericlaw1979 at hotmail dot com
07-Jun-2006 12:18
It is an error to send post-check=0.  See http://blogs.msdn.com/ie/archive/2006/06/01/613132.aspx
irek at eccomes dot de
29-Mar-2006 08:35
Related to francesco at paladinux: HOW TO RESOLVE EXPLORER SAVE PROBLEM IN FORCE-DOWNLOAD.

To use "application/octetstream" instead of "application/octet-stream" may help in some cases. But the solution of this problem in most cases is to use

header ("Cache-Control: must-revalidate, post-check=0, pre-check=0");

See also message of ctemple below. This helps not only for pdf but also generally.
oryan at zareste dot com
26-Nov-2005 07:18
As Grey said below:  Readfile will send users un-executed PHP files, which makes it easy to exploit vulnerabilities.  It's common - and easy - to use GET variables pointing to downloadable files, like script.php?v=web/file.mov , but this lets users to change it to script.php?v=index.php and get damaging info.  Even POST variables can be exploited this way if the user's on a custom browser.

To keep secure, limit downloadable files to one directory, like 'web/', so that script.php?v=file.mov will send web/file.mov, and scan the variable for '..' and 'php' to make sure users can't go into other directories, or open php files you may have stupidly put under web/.  This should cover all the bases.
peavey at pixelpickers dot com
20-Oct-2005 06:38
A mime-type-independent forced download can also be conducted by using:

<?
(...)
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); // some day in the past
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Content-type: application/x-download");
header("Content-Disposition: attachment; filename={$new_name}");
header("Content-Transfer-Encoding: binary");
?>

Cheers,

Peavey
planetmaster at planetgac dot com
16-Oct-2005 11:44
Using pieces of the forced download script, adding in MySQL database functions, and hiding the file location for security was what we needed for downloading wmv files from our members creations without prompting Media player as well as secure the file itself and use only database queries. Something to the effect below, very customizable for private access, remote files, and keeping order of your online media.

<?
    # Protect Script against SQL-Injections
    $fileid=intval($_GET[id]);
    # setup SQL statement
    $sql = " SELECT id, fileurl, filename, filesize FROM ibf_movies WHERE id=' $fileid' ";

    # execute SQL statement
    $res = mysql_query($sql);

        # display results
        while ($row = mysql_fetch_array($res)) {
        $fileurl = $row['fileurl'];
        $filename= $row['filename'];
        $filesize= $row['filesize'];

           $file_extension = strtolower(substr(strrchr($filename,"."),1));

           switch ($file_extension) {
               case "wmv": $ctype="video/x-ms-wmv"; break;
               default: $ctype="application/force-download";
           }

// required for IE, otherwise Content-disposition is ignored
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');

           header("Pragma: public");
           header("Expires: 0");
           header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
           header("Cache-Control: private",false);
           header("Content-Type: video/x-ms-wmv");
           header("Content-Type: $ctype");
           header("Content-Disposition: attachment; filename=\"".basename($filename)."\";");
           header("Content-Transfer-Encoding: binary");
           header("Content-Length: ".@filesize($filename));
           set_time_limit(0);
           @readfile("$fileurl") or die("File not found.");

}

$donwloaded = "downloads + 1";

    if ($_GET["hit"]) {
        mysql_query("UPDATE ibf_movies SET downloads = $donwloaded WHERE id=' $fileid'");

}

?>

While at it I added into download.php a hit (download) counter. Of course you need to setup the DB, table, and columns. Email me for Full setup// Session marker is also a security/logging option
Used in the context of linking:
http://www.yourdomain.com/download.php?id=xx&hit=1

[Edited by sp@php.net: Added Protection against SQL-Injection]
antispam [at] rdx page [dot] com
20-Sep-2005 02:14
Just a note:  If you're using bw_mod (current version 0.6) to limit bandwidth in Apache 2, it *will not* limit bandwidth during readfile events.
23-Aug-2005 02:39
here is a nice force download scirpt

            $filename = 'dummy.zip';
            $filename = realpath($filename);

            $file_extension = strtolower(substr(strrchr($filename,"."),1));

            switch ($file_extension) {
                case "pdf": $ctype="application/pdf"; break;
                case "exe": $ctype="application/octet-stream"; break;
                case "zip": $ctype="application/zip"; break;
                case "doc": $ctype="application/msword"; break;
                case "xls": $ctype="application/vnd.ms-excel"; break;
                case "ppt": $ctype="application/vnd.ms-powerpoint"; break;
                case "gif": $ctype="image/gif"; break;
                case "png": $ctype="image/png"; break;
                case "jpe": case "jpeg":
                case "jpg": $ctype="image/jpg"; break;
                default: $ctype="application/force-download";
            }

            if (!file_exists($filename)) {
                die("NO FILE HERE");
            }

            header("Pragma: public");
            header("Expires: 0");
            header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
            header("Cache-Control: private",false);
            header("Content-Type: $ctype");
            header("Content-Disposition: attachment; filename=\"".basename($filename)."\";");
            header("Content-Transfer-Encoding: binary");
            header("Content-Length: ".@filesize($filename));
            set_time_limit(0);
            @readfile("$filename") or die("File not found.");
herbert dot fischer at NOSPAM dot gmail dot com
21-Jul-2005 08:01
readfile and fpassthru are about 55% slower than doing a loop with "feof/echo fread".
chrisputnam at gmail dot com
29-Jun-2005 01:44
In response to flowbee@gmail.com --

When using the readfile_chunked function noted here with files larger than 10MB or so I am still having memory errors. It's because the writers have left out the all important flush() after each read. So this is the proper chunked readfile (which isn't really readfile at all, and should probably be crossposted to passthru(), fopen(), and popen() just so browsers can find this information):

<?php
function readfile_chunked($filename,$retbytes=true) {
  
$chunksize = 1*(1024*1024); // how many bytes per chunk
  
$buffer = '';
  
$cnt =0;
  
// $handle = fopen($filename, 'rb');
  
$handle = fopen($filename, 'rb');
   if (
$handle === false) {
       return
false;
   }
   while (!
feof($handle)) {
      
$buffer = fread($handle, $chunksize);
       echo
$buffer;
      
ob_flush();
      
flush();
       if (
$retbytes) {
          
$cnt += strlen($buffer);
       }
   }
      
$status = fclose($handle);
   if (
$retbytes && $status) {
       return
$cnt; // return num. bytes delivered like readfile() does.
  
}
   return
$status;

}
?>

All I've added is a flush(); after the echo line. Be sure to include this!
Hern
Новости
11 июля 2007
Сайт запущен
© 2007 info@grandviewstudio.com
Z058440144362 Z348613067571