Before the project encountered such a problem, that is, in the PHP environment, with a tag href link to a resource, such as MP3 or LRC file, after clicking on the file does not appear to save the prompt, but instead of calling the local program to open the file or directly on the browser to parse. Online said can be all made RAR format file, this one on the other hand inconvenient, in some cases it is not possible to do so, and in fact, did the test will find that in the case of content-type:text/html, the instant is the RAR will sometimes be directly resolved by the browser, Can not implement the download function, then this question is not solved it? The answer is no, a few search + test, finally found a viable solution, that is, after clicking on the link of a tag, not directly request resources, but to the header to do preprocessing, and then go to ReadFile on it. The relevant test code is attached below:
One
In index.php:
<? PHP Echo "<a href= ' Process.php?filename=halo.mp3 ' > Downloads </a>"?>
In process.php:
<? PHP Header ("Content-type:application/octet-stream"); Header basename ($_get[' filename ']). ' "' ); Header filesize ($_get[' filename ']); ReadFile ($_get[' filename ']);? >
This is the simplest method, but there is a problem: if the requested path contains Chinese, then the downloaded file name may be garbled.
Two
Solutions for the above problems,
In index.php:
<? PHP Echo "<a href= ' Process.php?filename=halo halo. mp3 ' > Downloads </a>"?>
In process.php:
<?PHPHeader("Content-type:application/octet-stream"); //working with Chinese file names $ua=$_server["Http_user_agent"]; $encoded _filename=UrlEncode($_get[' filename ']); $encoded _filename=Str_replace("+", "%20",$encoded _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".$_get[' filename ']. ‘"‘); } Else { Header(' Content-disposition:attachment; Filename= '.$_get[' filename ']. ‘"‘); } Header("Content-length:".)filesize($_get[' filename '])); ReadFile($_get[' filename ']);?>
When the output is apache+php, it needs to be sent to the Apache output buffer and sent to the user at the end. For NGINX+FPM, if they are deployed separately, it also brings in additional network IO.
Three
Now seems to be no problem, but ReadFile still have a problem, although PHP ReadFile try to achieve as efficiently as possible, do not occupy the memory of PHP itself, but in fact, it still needs to adopt mmap (if supported), or a fixed buffer to iterate through the file, Direct output.
Can you bypass the PHP layer and send the files directly to the user by webserver? Yes, we can use Apache's module mode_xsendfile to have Apache send this file directly to the user.
The code is implemented as follows: (process.php)
Header("Content-type:application/octet-stream");//working with Chinese file names$ua=$_server["Http_user_agent"];$encoded _filename=UrlEncode($_get[' filename ']);$encoded _filename=Str_replace("+", "%20",$encoded _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".$_get[' filename ']. ‘"‘);} Else {Header(' Content-disposition:attachment; Filename= '.$_get[' filename ']. ‘"‘);}//let xsendfile send files Header("X-sendfile:$_get[' filename '] ");
Finally, if you want to, you can first determine the suffix, because sometimes the image as a file download will also cause some inconvenient:
$type STRRCHR ($_get// if ($type = = "JPG" | | "PNG" | | "GIF") { header("Content-disposition:filename=$_get// Header("content-type:image/$type"); }
Transferred from: http://m.blog.csdn.net/blog/nkliming/8536311
PHP-PHP implementation Click on the href of a tag to make a link, save the file (any type) directly, instead of opening the downloaded file directly through the browser