duanqiu2064
2015-04-22 16:27 阅读 70

无法在Android浏览器中使用php下载文件

When using computer files are downloaded normally. Problem start on android browsers.

When we download a file from android default browser, the file is downloaded but it is of 0.00 bytes, so not technically present there(corrupt file).

When we download file from any third party application like or opera it gives error that "file could not be downloaded." not the header error. And files could be downloaded via UC Browser and Chrome and Firefox. But still gives the error in default browser.

Here is the code I am using:

<?php
require 'php/db.php';
if(isset($_POST['file_id'])&&!empty($_POST['file_id'])){
    download_file($_POST['file_id']);
}
function download_file($id){
    global $con;
    $id = mysqli_real_escape_string($con,htmlentities($id));
    $file="SELECT file_name,file_title,file_size,down FROM files WHERE file_id= $id";
    $result = mysqli_query($con,$file);
    $row = mysqli_fetch_assoc($result);
    $name = $row['file_name'];
    $title = $row['file_title'];
    $size = $row['file_size'];
    $ext = strtoupper(ext($name));  // Function defined bellow
    $down = $row['down'];
    $newname = $title.'.'.$ext;
    $olddir = "files/".$name;
    $down++;

    if(is_file($olddir)) {
        $update_down = "UPDATE files SET down = $down WHERE file_id = '$id'";
        $update_down_result = mysqli_query($con,$update_down);

        header('Pragma: public');   // required
        header('Expires: 0');       // no cache
        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
        header('Last-Modified: '.gmdate ('D, d M Y H:i:s', filemtime ($olddir)).' GMT');
        header('Cache-Control: private',false);
        header('Content-Type: application/octet-stream');
        header('Content-Disposition: attachment; filename="'.$newname.'"');
        header('Content-Transfer-Encoding: binary');
        header('Content-Length: '.$size);   // provide file size
        header('Connection: close');
        readfile($olddir);

        exit();
    }else header("Location: index.php?msg=Sorry!+File+could+not+be+downloaded");

}

function ext($name){
    $rut = strrev($name);
    $erut = explode('.', $rut);
    return strrev($erut[0]);
}

We give file id to this function and it downloads the file on PC.

Can anyone tell me how to remove the error? So that users can download files from their android phones too.

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

2条回答 默认 最新

  • 已采纳
    duandang9434 duandang9434 2015-05-05 18:03

    I got the solution. Mainly I changed two things:

    1. Used GET method instead of Post Method.
    2. Used Flush and ob_clean functions to clear the buffer.

    New code for downfile.php is like this:

    <?php
        require '../php/db.php';
        ob_start();
        if(isset($_GET['file_id'])&&!empty($_GET['file_id'])){
            download_file($_GET['file_id']);
        }else die("There was an error in downloading file. Please try again later.");
    
        function download_file($id){
            global $con;
            $id = mysqli_real_escape_string($con,htmlentities($id));
    
            $file="SELECT file_name,file_title,file_size,down FROM files WHERE file_id= $id";
            $result = mysqli_query($con,$file);
            $row = mysqli_fetch_assoc($result);
            $name = $row['file_name'];
            $title = $row['file_title'];
            $ext = ext($name);
            $down = $row['down'];
            $newname = $title.'.'.$ext;
            $size = $row['file_size'];
            $down++;
    
            if(is_file($name)) {
                $update_down = "UPDATE files SET down = $down WHERE file_id = '$id'";
                $update_down_result = mysqli_query($con,$update_down);
    
                header('Content-Description: File Transfer');
                header('Content-Type: application/octet-stream');
                header('Content-Disposition: attachment; filename="'.$newname.'"');
                header('Content-Transfer-Encoding: binary');
                header('Expires: 0');
                header('Cache-Control: must-revalidate');
                header('Pragma: public');
                header('Content-Length: '.$size);
                ob_clean();
                flush();
                readfile($name);
                exit;
    
            }else header("Location: index.php?msg=Sorry!+File+could+not+found!");
    
        }
    
        function ext($name){
            $rut = strrev($name);
            $erut = explode('.', $rut);
            return strrev($erut[0]);
        }
    
    ?>
    

    Through this code I am able to download files in android browsers too.

    Hope this may help. :)

    点赞 评论 复制链接分享
  • douyan1882 douyan1882 2015-04-22 21:26

    Probably $size == 0;

    $size = $row['file_size'];
    ...
    $olddir = "files/".$name;
    

    change to

    $olddir = "files/".$name;
    $size = filesize($olddir);
    

    And change

    else header("Location: index.php?msg=Sorry!+File+could+not+be+downloaded");
    

    to

    else header("Location: index.php?msg=Sorry!+File+could+not+be+found+on+server: " . $olddir);
    
    点赞 评论 复制链接分享