Can't upload 5mb file using AJAX file uploader

2020-07-30 03:07发布

问题:

I am using the file uploader plugin (from: https://github.com/valums/file-uploader) to upload files to my website.

If you are using a moden web browser (like Firefox 6 or Chrome 13), then it uploads by streaming the file in the POST body, and can give you a progress bar. If you're using IE (or an old browser), it falls back on the standard $_FILES (using a hidden iFrame).

Everything was working fine, but suddenly I can't upload 5MB files in Chrome or Firefox. When I upload a 5MB file in Chome or Firefox I get a 500 error and my PHP code is never even ran. If I use Internet Explorer (which uses $_FILES), it works fine.

This has to be a configuration problem, as my PHP code never even runs. So, I checked my settings.

/etc/php.ini

upload_max_filesize = 15M
post_max_size = 16M

I looked for LimitRequestBody, but that's nowhere to be found (and the default is unlimited).

Settings look right. I debugged this for a while, and I can not figure out what is wrong.

Is there a setting I'm missing? The server has suhosin installed, if that matters.

Here is the backend (I'm using CodeIgniter) code I'm using.

// Can we use the fancy file uploader?
if($this->input->get('qqfile') !== FALSE){ // Yes we can :-)
    $name = preg_replace('/[^\-\(\)\d\w\.]/','_', $this->input->get('qqfile'));
    // Upload the file using black magic :-)
    $input = fopen("php://input", 'r');
    $temp = tmpfile();
    $fileSize = stream_copy_to_stream($input, $temp);
    fclose($input);
    if($fileSize > 15728640){
        $ret['error'] = 'File not uploaded: file cannot be larger than 15 MB';
    }               
    elseif(isset($_SERVER['CONTENT_LENGTH']) && $fileSize === (int)$_SERVER['CONTENT_LENGTH']){
        $path = $folder.'/'.$name; // Where to put the file
        // Put the temp uploaded file into the correct spot
        $target = fopen($path, 'w');
        fseek($temp, 0, SEEK_SET);
        stream_copy_to_stream($temp, $target);
        fclose($target);
        fclose($temp);

        $ret['fileSize'] = $fileSize;
        $ret['success'] = true;
    }
    else{
        $ret['error'] = 'File not uploaded: content length error';
    }
}
else{ // IE 6-8 can't use the fancy uploader, so use the standard $_FILES
    $file = $_FILES['qqfile'];
    $file['name'] = preg_replace('/[^\-\(\)\d\w\.]/','_', $file['name']);
    $config['file_name'] = $file['name'];
    // Upload the file using CodeIgniter's upload class (using $_FILES)
    $_FILES['userfile'] = $_FILES['qqfile'];
    unset($_FILES['qqfile']);
    $config['upload_path'] = $folder;
    $config['allowed_types'] = '*';
    $config['max_size'] = 15360; //15 MB
    $this->load->library('upload', $config);
    if($this->upload->do_upload()){ // Upload was successful :-)
        $upload = $this->upload->data();
        $ret['success'] = true;
        $ret['fileSize'] = $upload['fileSize']/1000;
    }
    else{ // Upload was NOT successful
        $ret['error'] = 'File not uploaded: '.$this->upload->display_errors('', '');
        $ret['type'] = $_FILES['userfile']['type'];
    }
    echo json_encode($ret);
}

I know my code works, as files less than 4MB upload fine (on all browsers). I only have a problem with files bigger than 5mb (using Chrome/Firefox). The weird thing is, this works fine on my test server, but not my production server. They probably have different settings (suhosin is on production, but not on test).

回答1:

Please check whether your php.ini settings are correctly loaded by viewing <?php phpinfo(); ?>.



回答2:

I looked in my apache logs, and found

PHP Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 5242881 bytes)

I changed memory_limit to 64M, now it seems to be ok.