I've been banging my head against this for 20+ hours now I would really appreciate some help!
I have simplified the problem here so the code is very simple. Basically this upload script works perfectly until I try to upload a file bigger than 25MB then it fails. PHP gives no errors.
index.htm
<form enctype="multipart/form-data" action="upload.php" method="POST">
Choose a file to upload: <input name="uploadedfile" type="file" /><br />
<input type="submit" value="Upload File" />
</form>
upload.php
<?php
$target_path = "uploaded/";
$target_path = $target_path.basename( $_FILES['uploadedfile']['name']);
/***/highlight_string(print_r($_FILES, true)); //check array
if (move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "The file ". basename($_FILES['uploadedfile']['name'])." has been uploaded";
} else {
echo "There was an error uploading the file, please try again!";
}
?>
php.ini
[PHP]
post_max_size = 32M
upload_max_filesize = 32M
My host informed me that the upload limit on the server is 32MB. Ran phpinfo() & the variables in the ini are being changed. It is not a timeout issue (ran a 16mb upload when downloading a file - it took several minutes longer than the 25MB upload but still worked).
I have been spittin out the $_Files array as a string for error checking, heres what I get when it fails:
Array
(
[uploadedfile] => Array
(
[name] => 30.tif
[type] =>
[tmp_name] =>
[error] => 7
[size] => 0
)
)
There was an error uploading the file, please try again!
Any ideas? Tried it on different servers with the same problem.
According to this, it failed to write files to disk. Can you check quota/disk space/etc.?
memory_limit might also restrict the size of uploadable files.
Your error don't is for the size, the error code 7 is because the file "can't be save in the disk."
to more errors read: Upload code errors
Try change the directive "upload_tmp_dir" in php.ini file and check if is allow the upload of file: 'file_uploads = On'.
Thanks everybody, I'm sure now that it is a host problem, not a problem on my end - even though I've tried it on several hosts - I think it's pretty common for http post to be limited to around 25MB.
I have now set my uploader to take a maximum file size of 20MB, that should make it pretty safe on most hosts.
Related
please ignore "Original" information since I already know this is nothing to do with CI.
In order to simplify problems, I create another vhost and put only one HTML and one PHP files, just to try pure file upload without CI.
<html><body>
<form method="post" enctype="multipart/form-data" action="upload.php">
<input type="file" name="my_file">
<input type="submit" value="Upload">
</form>
</body></html>
And pure file upload like this:
# Check if file uploaded
if ($_FILES['my_file']['error'] === UPLOAD_ERR_OK){
echo 'file name: ' . $_FILES['my_file']['name'] . '<br/>';
echo 'file type: ' . $_FILES['my_file']['type'] . '<br/>';
echo 'file size: ' . ($_FILES['my_file']['size'] / 1024) . ' KB<br/>';
echo 'tmp file: ' . $_FILES['my_file']['tmp_name'] . '<br/>';
# check if file exits
if (file_exists('/tmp/' . $_FILES['my_file']['name'])){
echo 'file already exists。<br/>';
} else {
$file = $_FILES['my_file']['tmp_name'];
$dest = '/tmp/after-' . $_FILES['my_file']['name'];
# try moving file and rename
move_uploaded_file($file, $dest);
}
} else {
echo 'Error:' . $_FILES['my_file']['error'] . '<br/>';
}
Upload file less than 10MB is fine, will receive echo message. But upload file larger than 10MB will receive no echo message. Check my /tmp folder can see upload is success. There is a "after-firewall.pdf.zip" file which is 21MB, so upload and move is done.
-rw-r--r-- 1 apache apache 21M 2月 9 07:25 after-firewall.pdf.zip
-rw-r--r-- 1 apache apache 420K 2月 9 07:31 after-LINE_ALBUM_230117_6.jpg
-rw-r--r-- 1 apache apache 8.1M 2月 9 07:24 after-test_upload.zip
-rw-r--r-- 1 apache apache 141 2月 9 06:50 upload_log.txt
But why browser and POSTMAN cannot get response? Is there any setting block or delay php-fpm or Apache2 response?
------------- Original Question ---------
You can ignore below complex statement....
We already know this is nothing to do with CodeIgniter.
We have an up and running services which using CodeIgniter 3.1.11. I am trying to add an upload file function and it works. But somehow if file is larger than 10MB, browser cannot get response (it will wait until time out). I am sure file upload is success and can upload up to 100MB file. (PHP max upload and post size is set to 100MB, max execution time is set to 300 seconds.)
Amazon Linux 2
Apache version: 2.4.54
PHP version: 7.2.34
CodeIgniter version: 3.1.11
Upload related code like this. After upload completed, it will bring file information to next page.
if($this->upload->do_upload('uploadfile')){
$file1 = $this->upload->data();
$arr_info['file']['file_size'] = $file1['file_size'];
$arr_info['file']['ori_file_name'] = $file1['orig_name'];
$arr_info['file']['file_extension'] = $file1['file_ext'];
$arr_info['file']['fullpath'] = $file1['full_path'];
}
else {
echo "Upload failed! Please try again!";
exit;
}
$pagedata['data'] = $arr_info;
$this->template->load('layout', '/build/end_upload', $pagedata);
When upload a 5.5MB filename schedule.json, it will success.
Select a 5.5 MB file to upload
It will go to next page and show file information (array) like this.
Browser can get response, file upload success.
But if I upload file larger than 10MB, although file can successfully upload to server, my browser will not get response and wait until timeout. Here is my /tmp folder where upload file placed. You can see a 61MB file name "2023TaipeiNewYear.mp4" successfully uploaded.
enter image description here
CodeIgniter logs are like this:
CI says it was finished
Since last few lines says it has loaded view file, and "Final output sent to browser". I think it means CodeIgniter had done his job. But browser still hang and wait until timeout.
I tested in Chrome(109.0.5414.119), FireFox (109.0.1), Edge(109.0.1518.78 ) but got the same result.
I wonder if php-fpm have some issue so open DEBUG mode to trace, when upload started it showed
[08-Feb-2023 05:37:39.040845] DEBUG: pid 8604, fpm_pctl_perform_idle_server_maintenance(), line 378: [pool www] currently 1 active children, 5 spare children, 6 running children. Spawning rate 1
and after few seconds, active children turn to 0, and file did uploaded to /tmp folder. But, browser still get nothing.
[08-Feb-2023 05:37:40.042082] DEBUG: pid 8604, fpm_pctl_perform_idle_server_maintenance(), line 378: [pool www] currently 0 active children, 6 spare children, 6 running children. Spawning rate 1
I think it means php-fpm had done his part.
some php.ini settings may be related:
max_input_time= 300
output_buffering= off
max_execution_time = 300
memory_limit = 512M
post_max_size = 100M
file_uploads = On
upload_max_filesize = 100M
I wonder if anything happened or hanged in upload process, or can load CodeIgniter view for some reason. so I try to write a log in server after upload, then echo result to browser.
if($this->upload->do_upload('uploadfile')){
$file1 = $this->upload->data();
$arr_info['success'] = 1;
$arr_info['file']['file_size'] = $file1['file_size'];
$arr_info['file']['file_name'] = $file_name;
$arr_info['file']['ori_file_name'] = $file1['orig_name'];
$arr_info['file']['file_md5'] = md5_file($file1['full_path']);
$arr_info['file']['file_extension'] = $file1['file_ext'];
$arr_info['file']['file_md5_type'] = 'md5';
}
else {
echo "Upload failed! Please try again!";
exit;
}
$log = json_encode($arr_info);
exec('echo "'. $log . '" >> /tmp/upload_log.txt &');
header('Content-Type: application/json; charset=utf-8');
echo $log;
flush();
exit;
After try to upload two files which are 8.2MB and 10.2MB, I get this log.
{success:1,file:{file_size:8217.24,file_name:s-test_upload.zip,ori_file_name:test_upload.zip,file_md5:34d8753e37df705fc3358c4b4e5e2754,file_extension:.zip,file_md5_type:md5}}
{success:1,file:{file_size:10250.2,file_name:s-AINTD.png,ori_file_name:AINTD.png,file_md5:0eb1b12a08ee913102cfb5db29a9589d,file_extension:.png,file_md5_type:md5}}
So two uploads are success, but only the first one can get JSON output on browser, the second one which larger than 10MB still hangs and get nothing response.
I can't see any error messages in php-fpm and apache logs.
Not sure what happens. If anyone needs any more information please let me know. Thanks!
try calling upload library with config:
$config['upload_path'] = './tmp/';
$config['allowed_types'] = 'json|mp4|jpg|png';
$config['max_size'] = 100000; //100MB
$config['max_width'] = 1024;
$config['max_height'] = 768;
$this->load->library('upload', $config);
https://codeigniter.com/userguide3/libraries/file_uploading.html#the-controller
put display_error in else block:
$this->upload->display_errors('<pre>', '</pre>');
if you have some time, please try it out to see what the result will be if you use move_upload_file() function https://www.php.net/manual/en/function.move-uploaded-file.php
check phpinfo() that the settings are real in php-side
((we also use codeigniter 3.1, we can easily upload a 500mb file))
After create a few other AWS instances to test, we finally find out that this is a HTTP protocol issue.
We were running services inside our internal network when coding on development environment, so we just use internal IP and HTTP for connection on dev servers.
After I register a real domain and give it SSL certification, running through HTTPS protocol to upload file more than 10MB would be okay.
But I don't think HTTP POST have any limitation before..... we had coding on HTTP only dev environment for years..... not sure if major browsers have a new limitations on HTTP protocol.
Upload bigger file( > 10KB) will get error code 3(UPLOAD_ERR_PARTIAL) in $_FILES['file']['error'] and small file( < 10KB) will upload successfully.
If the file exceed the limit php post_max_size or upload_max_filesize, it should get error code 1 UPLOAD_ERR_INI_SIZE. However, getting error code 3 UPLOAD_ERR_PARTIAL which is incorrect.
I guess it has something wrong with apache setting, and have no idea how to solve this problem.
Using below software and its versions
php 5.6.17
apache 2.4.18
Following is the php.ini:
post_max_size = 8M
file_uploads = On
upload_tmp_dir = "/tmp"
upload_max_filesize = 2M
and when upload larger file(hi.png) the error log in /var/log/httpd-error.log
PHP Notice: Missing mime boundary at the end of the data for file hi.png in Unknown on line 0
here are index.php
<!DOCTYPE html>
<html>
<body>
<form action='upload.php' method='post' enctype='multipart/form-data'>
Select image to upload:
<input type='file' name='fileToUpload' id='fileToUpload'>
<input type='submit' value='Upload Image' name='submit'>
</form>
</body>
</html>
and the upload.php
<?php
if($_FILES['fileToUpload']['error'] > 0){
echo "error code".$_FILES['fileToUpload']['error']."<br>";
}
else{
echo "file name:".$_FILES['fileToUpload']['name']."<br>";
echo "file type:".$_FILES['fileToUpload']['type']."<br>";
echo "file size:".$_FILES['fileToUpload']['size']."<br>";
echo "file path:".$_FILES['fileToUpload']['tmp_name']."<br>";
move_uploaded_file($_FILES['fileToUpload']['tmp_name'],"uploads/".$_FILES['fileToUpload']['name']);
}
?>
I had the same problem in a FreeBSD 10.1 jail with php 5.6.18 and apache 2.4.18: Files above 7950 bytes would constantly and consistently fail with error 3, no matter which limits were set.
After ages I finally isolated the issue: The PHP module (mod_php56) was compiled with apache2filter SAPI but enabled as a handler via AddHandler. The solution was to review the port options and rebuild mod_php56 with standard options (without AP2FILTER).
Long story: Check if you have port option OPTIONS_FILE_SET+=AP2FILTER (Apache 2 Filter SAPI) on, but PHP configured the usual way as a handler ( AddType application/x-httpd-php .php ). Removing the option (as the default build/port does), and rebuilding the mod_php56 package solved the problem for me.
To verify if this is your case too, you can echo the php_sapi_name(). if it is apache2filter but php is enabled via AddHandler directive, you have the same problem. After rebuild, your php_sapi_name() should be apache2handler. Both options are also checkable in phpinfo(), as "Apache 2.0 Filter" and "Apache 2.0 Handler" respectively.
Note that this does not explain why it actually broke uploads (or why the module worked with the Handler configuration in the first place).
You might also succeed by enabling mod_php as a filter instead as a handler, but I did not check that here.
I want to upload the file to my local server, but only small size files worked, if the file size exceeds certain value, then it can not find the uploaded file.
if (isset($_FILES["fileToUpload"]["tmp_name"])) {
$fileUploaded = move_uploaded_file($_FILES["fileToUpload"]["tmp_name"], "./uploads/".$_FILES["fileToUpload"]["name"]);
} else {
die("Error uploading file. Please contact an administrator");
}
Then I changed the upload_max_filesize and post_max_size in php.ini, restart apache, but the problem still exists, couls you help me on that? thanks so much.
update:
1. only one file will be uploaded.
2. Small-size file like less than 2 MB could be uploaded successfully. I tested an 10 MB file, it failed.
3. I changed the two parameters upload_max_filesize and post_max_size from 2 MB to 100 MB.
So you can see what actual error is being generated try this code
if ( isset($_FILES["fileToUpload"]) ) {
print_r($_FILES);
}
Then look at the [error] array and see what error is actually being reported.
Then check this page in the manual to see what the numbers mean.
We have a form where we can upload file. We are not able to upload big size files for e.g. > 30 MB.
We have already changed the settings memory_limit, post_max_size and upload_max_filesize to some large number.
But still we get "This web page is not available" error with "Error code: ERR_CONNECTION_RESET" in Chrome . In Chrome we see message like "Uploading %" and after certain %of uploading it throws the error. In short it seems data is itself not posting to action page.
It looks like your upload is being timed out. Try increasing max_input_time in php.ini, ie:
max_input_time = 600
and your php's max_execution_time = ?
http://php.net/manual/en/function.set-time-limit.php
perhaps better to show the code you're using.
For larger file upload use chunk upload.
https://github.com/blueimp/jQuery-File-Upload/wiki/Chunked-file-uploads
Hopefully this will help you.
I have the PHP script (testupload.php):
<?php
error_reporting(E_ALL);
ini_set('log_errors',1);
ini_set('error_log','/root/work/inputs/log_file');
$target_path = "/work/inputs";
$target_path = $target_path . basename( $_FILES['frag3']['name']);
echo "Received File: " . $_FILES['frag3']['name'] . " and moving it to " . $target_path . "<br>";
if(move_uploaded_file($_FILES['frag3']['name'], $target_path)) {
echo "The file ". basename( $_FILES['frag3']['name']) . " has been uploaded";
} else{
echo "There was an error uploading the file, please try again!";
}
?>
And the HTML file to call it:
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<form action = "http://localhost:8081/testupload.php" method="post" enctype="multipart/form-data">
<span>Value : </span><input type="text" name="Value" value="Hello world"/><br />
<span>Fragment File : </span><input type="file" name="frag3" /><br />
<input type="submit" value="Send"/>
</form>
</body>
</html>
However, I continually recieve the response:
There was an error uploading the file, please try again!
So it's clear that move_uploaded_file() is not correctly functioning. Plus, it doesn't actually move the file. However, I can't seem to diagnose the issue.
My first thought was that the directory was not writable. But my permissions for the folder are drwxrwxrwx (as determined by ls -l)
Also, the line:
ini_set('error_log','/root/work/inputs/log_file');
doesn't seem to write a log file to that location.
Has anyone had any experience with this? How can I diagnose whats going on here?
I am almost at a loss here, so any help would be greatly appreciated.
I am using OpenSUSE 11.2, Apache 2.2, and PHP 5.3.
Many thanks,
Brett
You should do move_uploaded_file($_FILES['frag3']['tmp_name'], $target_path)
Here are some things to check:
Ensure that your file upload and post limits are not reached by editing upload_max_filesize and post_max_size in your .htaccess or php.ini file. If you have error reporting on, you should see an error when they're reached. See this: http://drupal.org/node/97193
Check for file upload error codes. See the documentation for these: http://www.php.net/manual/en/features.file-upload.errors.php
Ensure that your memory_limit has not been reached. Again, with error logging enabled, you should receive an error message about this. http://drupal.org/node/207036
Check PHP's common pitfalls documentation and make sure there's nothing there that helps: http://www.php.net/manual/en/features.file-upload.common-pitfalls.php
If none of this helps, enable error reporting and post what you receive so we can tailor our answers better to your situation.
the php stores the file in server with temporary name
which you can get by
$_FILES['frag3']['tmp_name'] and not by $_FILES['frag3']['name']
I believe it's move_uploaded_file($_FILES['frag3']['tmp_name'], $target_path), as the files aren't actually stored by the name they're uploaded with (though you can, of course, rename them by setting their target path to such).