On the microblog to see an introduction to PHP faster download file method, in fact, the use of Web server xsendfile features, bird Brother's blog only said the Apache implementation, I found the introduction of nginx implementation of the article, tidy up!
Let ' s go!
In general, we can direct the user to download a file by directly directing the URL to a file located under document root.
However, to do so, there is no way to do some statistics, permission checks, and so on. So, many times, we use to let PHP to do the forwarding, to provide users with file download.
<? PHP $file = "/tmp/dummy.tar.gz"; Header ("Content-type:application/octet-stream"); Header basename ($file). "'); Header filesize ($file)); ReadFile ($file);
But this has a problem, that is, if the file is a Chinese name, some users may download the file name is garbled.
So, let's make a change (see:
<?PHP$file= "/tmp/Chinese name. tar.gz"; $filename=basename($file); Header("Content-type:application/octet-stream"); //working with Chinese file names $ua=$_server["Http_user_agent"]; $encoded _filename=Rawurlencode($filename); if(Preg_match("/msie/",$ua)) { Header(' Content-disposition:attachment; Filename= '.$encoded _filename. ‘"‘); } Else if(Preg_match("/firefox/",$ua)) { Header("Content-disposition:attachment; Filename*=\ "UTF8".$filename. ‘"‘); } Else { Header(' Content-disposition:attachment; Filename= '.$filename. ‘"‘); } Header("Content-length:".)filesize($file)); ReadFile($file);
Well, it looks much better now, but there's another problem, that is, ReadFile, although PHP's ReadFile try to be as efficient as possible, without taking up PHP's own memory, but in fact it still needs to adopt mmap (if supported), Or a fixed buffer to iterate through the file and output it directly.
Output, if it is Apache + PHP mod, then also need to send to Apache output buffer. Finally sent to the user. and for Nginx + FPM If they are deployed separately, that will also bring additional network IO.
So, can not go through this layer of PHP, directly let webserver directly send the file to the user?
Today, I saw an interesting article: how I php:x-sendfile.
We can use Apache's module mod_xsendfile to have Apache send this file directly to the user:
<?PHP$file= "/tmp/Chinese name. tar.gz"; $filename=basename($file); Header("Content-type:application/octet-stream"); //working with Chinese file names $ua=$_server["Http_user_agent"]; $encoded _filename=Rawurlencode($filename); if(Preg_match("/msie/",$ua)) { Header(' Content-disposition:attachment; Filename= '.$encoded _filename. ‘"‘); } Else if(Preg_match("/firefox/",$ua)) { Header("Content-disposition:attachment; Filename*=\ "UTF8".$filename. ‘"‘); } Else { Header(' Content-disposition:attachment; Filename= '.$filename. ‘"‘); } //let xsendfile send files Header("X-sendfile:$file");
The X-sendfile header is processed by Apache and the response file is sent directly to the client.
Nginx also has the corresponding Xsendfile module, the default already contains the Senfile module, if you install the nginx you will be in the nginx.conf file will see "Sendfile on;"
Configuration section:
Server {Listen80; SERVER_NAME Demo. Markdream.com; Root/var/vhost/demo; Index index.PHP; #This is the URL that defines the directory where your files are read and the direct access is not possible only byLocation/protected{internal; Alias/var/vhost/demo/Uploadfiles; } Location~ \.php$ {fastcgi_pass127.0.0.1:9000; Fastcgi_index Index.PHP; Fastcgi_param Script_filename$document _root/$fastcgi _script_name; includeFastcgi_params; }}downloads.php
<?PHP//eg:http://demo.markdream.com/xsendfile/downloads.php?filename=hello.docx//Get file name$filename=$_get["FileName"];//You can write down your query database and other functions you want ...Header("Content-type:application/octet-stream" );//working with Chinese file names$ua=$_server["Http_user_agent"];if(Preg_match("/msie/",$ua )) { $encoded _filename=Rawurlencode($filename ); Header(' Content-disposition:attachment; Filename= '.$encoded _filename. ‘"‘ );} Else if(Preg_match("/firefox/",$ua )) { Header("Content-disposition:attachment; Filename*=\ "UTF8".$filename. ‘"‘ );} Else { Header(' Content-disposition:attachment; Filename= '.$filename. ‘"‘ );}//that's a simple sentence. Note that "protected" is consistent with Nginx configuration file protectedHeader("X-accel-redirect:/protected/".$filename);?>
Here is the use of the alias, you can also use direct access to the way, specific to the Nginx official website about the xsendfile of the instructions, a look will understand!
References and excerpts:
1. Brother Bird: http://www.laruence.com/2012/05/02/2613.html
2.nginx implementation: Https://www.markdream.com/technologies/programs/nginx-x-accel-redirect-php-practise.shtml?utm_source =tuicool&utm_medium=referral
3.nginx Xsendfile Official website Description: Http://wiki.nginx.org/XSendfile
PHP provides faster file downloads