Weird PHP file upload issue - php

I am having strange issues regarding file upload on my windows system. I am using windows 7 with iis7 on the server. I am trying on a client comp with local IP 10.47.47.13 and the server is 10.47.47.1.
I have a very simple form which i couldn't make it work in some cases. The page stays on the wwwroot. (http://10.47.47.1/3.php)
3.php
<?php
$source_file=$_FILES["newsimg"]["tmp_name"];
$destination_file="123.jpg";
$ftp_server="localhost";
$ftp_username="admin";
$ftp_password="apple";
if ($source_file!="") {
$mrph_connect = ftp_connect($ftp_server,21);
$mrph_login= ftp_login($mrph_connect, $ftp_username, $ftp_password);
if (($mrph_connect) && ($mrph_login)) {
$upload = ftp_put($mrph_connect, $destination_file, $source_file, FTP_BINARY);
if ($upload) echo "ok"; else echo "nok";
}
}
?>
<body>
<form enctype="multipart/form-data" action="3.php" method="POST">
<input type=file name=newsimg>
<input type=submit name=mrph>
</form>
</body>
The form calls itself to upload the file. When I select a file of size 1 or 2 KB it works but when I select a file of even 10 15KB the page timeouts after some time. I checked the php.ini settings file upload is on, I set temp folder as c:\uploads just to test. AS I SAID IT WORKS FOR FILES SIZE 1 OR 2KB BUT NOT EVEN WHEN I SELECT A FILE OF 10 OR 20KB. I even removed the PHP code (commented everything) to see even when nothing is done it works but it didn't.
Any help would be appreciated.

To me, the problem seems to be where you are uploading your file, the server; there is nothing wrong with uploading because you are able to upload smaller files but when you upload files of 20 kb size, you fail, check to make sure that right upload settings are specified on the server you want to upload the file to. Using ftp and uploading to a different server/location itself is slow process though. Your code also seems to be right.

My guess is that your ftp_put is timing out, try setting your FTP timeout threshold below PHP's default (30 seconds):
$mrph_connect = ftp_connect($ftp_server,21);
ftp_set_option($mrph_connect, FTP_TIMEOUT_SEC, 20);
$mrph_login= ftp_login($mrph_connect, $ftp_username, $ftp_password);
if (($mrph_connect) && ($mrph_login)) {
$upload = ftp_put($mrph_connect, $destination_file, $source_file, FTP_BINARY);
if ($upload) echo "ok"; else echo "nok";
}
If making that adjustment causes your script to return 'nok' then you'll know the put is taking too long.
If the put is your problem you try a non-blocking put with ftp_nb_put to FTP the file asynchronously:
$mrph_connect = ftp_connect($ftp_server,21);
$mrph_login= ftp_login($mrph_connect, $ftp_username, $ftp_password);
if (($mrph_connect) && ($mrph_login)) {
$ret = ftp_nb_put($mrph_connect, $destination_file, $source_file, FTP_BINARY);
while ($ret == FTP_MOREDATA) {
$ret = ftp_nb_continue($mrph_connect);
}
if ($ret == FTP_FINISHED) echo "ok"; else echo "nok";
}

I think Cryo is onto something, can it be that the php.ini file isnĀ“t correctly configured and the maximum filesize is to low?

This might not be it but for the record your form should have a MAX_FILE_SIZE hidden input with the number of bytes corresponding to the max upload size

You might have a low filesize limit. To check this: create a new php file, called info.php or whatever and just write
<?php
phpinfo();
?>
Open that page in your browser, and search for upload_max_filesize. Check the value for that; if it is only a few kilobytes, that's your problem. If this is the case, you will have to modify your php.ini (under Apache you could use a directive in a .htaccess file as well, but I don't think there's anything like that for IIS). The location of this file can be different depending on your installation, but it's probably C:\Windows\php.ini. Find the upload_max_filesize directive and change it to something bigger. The default is 2 megabytes (2M) but you can make it whatever.

Related

PHP filesize() showing old filesize with a file inside a windows shared (network) folder

I have the following script that runs to read new content from a file:
<?php
clearstatcache();
$fileURL = "\\\\saturn\extern\seq_ws.csv";
$fileAvailable = file_exists($fileURL);
$bytesRead = file_get_contents("bytes.txt");
if($fileAvailable){
$fileSize = filesize($fileURL);
//Statusses 1 = Partial read, 2 = Complete read, 0 = No read, -1 File not found. followed by !!
if($bytesRead < $fileSize){
//$bytesRead till $fileSize bytes read from file.
$content = file_get_contents($fileURL, NULL, NULL, $bytesRead);
file_put_contents("bytes.txt", ((int)$bytesRead + strlen($content)));
echo "1!!$content";
}else if($bytesRead > $fileSize){
//File edit or delete detected, whole file read again.
$content = file_get_contents($fileURL);
file_put_contents("bytes.txt", strlen($content));
echo "2!!$content";
}else if($bytesRead == $fileSize){
//No new data found, no action taken.
echo "0!!";
}
}else{
//File delete detected, reading whole file when available
echo "-1!!";
file_put_contents("bytes.txt", "0");
}
?>
It works perfect when I run it and does what is expected.
When I edit the file from the same PC and my server it works instantly and returns the correct values.
However when I edit the file from another PC, my script takes about 4-6 seconds to read the correct filesize of the file.
I added clearstatcache(); on top of my script, because I think its a caching issue. But the strange thing is that when I change the file from the server PC it responds instantly, but from another it doesn't.
On top of that as soon as the other PC changes the file, I see the file change in Windows with the filesize and content but for some reason, it takes Apache about 4-6 seconds to detect the change. In those 4-6 seconds it receives the old filesize from before the change.
So I have the following questions:
Is the filesize information cached anywhere maybe either on the Apache server or inside Windows?
If question 1 applies, is there anyway to remove or disable this caching?
Is it possible this isnt a caching problem?
I think that in Your local PC php has development settings.
So I suggest to check php.ini for this param: realpath_cache_ttl
Which is:
realpath_cache_ttl integer
Duration of time (in seconds) for which to cache realpath
information for a given file or directory.
For systems with rarely changing files,
consider increasing the value.
to test it, php info both locally and on server to check that value:
<?php phpinfo();

PHP FTP code fails, even though file is downloaded successfully

I'm using the following code to download a file via FTP in PHP:
$fp = fopen($local_file, 'w+');
$conn_id = ftp_connect($host);
$login_result = ftp_login($conn_id, $user, $pass);
$ret = ftp_nb_fget($conn_id, $fp, $remote_file, FTP_BINARY);
while ($ret == FTP_MOREDATA) {
$ret = ftp_nb_continue($conn_id);
}
if ($ret != FTP_FINISHED) {
echo "<span style='color:red;'><b>There was an error downloading the file!</b></span><br>";
logThis("log.txt", date('h:i:sa'), "ERROR DOWNLOADING FILE!");
exit();
}
fclose($fp);
<<php code continues below this....>>
This code seems to be working fine. The file is downloaded, and the MD5 hash of the file matches the hash of the file on the other server before it was downloaded. So the download does complete.
In any event, using that code above, even with the file successfully downloading, it's hitting the code inside of the if ($ret != FTP_FINISHED) condition.
If the file downloads fine, why is FTP_FINISHED not true?
EDIT
When I check the value of $ret after the WHILE loop, the times the script completes fine $ret=1 and the times the script fails $ret=0
However, there are times when the script fails because $ret=0 when the file is actually downloaded properly, which can be confirmed with a MD5 comparison.
Also, 0 or 1 are not values that should be returned from these commands. The official PHP documentation give three possible return values, they are FTP_FAILED or FTP_FINISHED or FTP_MOREDATA
I have thought of one solution. Since the file does get downloaded correctly, as determined by an MD5 check from the original source (which we do have), I could modify the code this way:
if ($ret != FTP_FINISHED) {
$localMD5 = md5_file($local_file);
if($localMD5 != $remoteMD5){
echo "<span style='color:red;'><b>There was an error downloading the file!</b></span><br>";
logThis("log.txt", date('h:i:sa'), "ERROR DOWNLOADING FILE!");
exit();
}
}
In most cases the script completes as expected, so this block of code never gets run. However, in cases where the error above occurs and this code is run, it could verify the MD5 hash of the file, and only run the error code if it doesn't match the MD5 of the original source file. If the MD5's match then the download was successful anyways, so the error code shouldn't run
Edited:
My first solution wasn't correct. After checking your comments below, I must say your code is correct, and that the problem probably is on "upload_max_size" and "post_max_size" values.
See here "Upload large files to FTP with PHP" and mainly here: "Changing upload_max_filesize on PHP"
So, the proposed solution is to add this to the .htaccess file:
php_value upload_max_filesize 2G
php_value post_max_size 2G
or, if the server is yours (dedicated), set them in php.ini (you'll need to restart the server so the changes take effect).
You may also find useful the post_max_size info in php.net. I've found interesting particularly this:
If the size of post data is greater than post_max_size, the $_POST and
$_FILES superglobals are empty. This can be tracked in various ways,
e.g. by passing the $_GET variable to the script processing the data,
i.e. , and then checking if
$_GET['processed'] is set.

Error during uploading a file with php

Ok, I used google over the last 2 days and didn't got what is wrong with my code. First it seemed that I used the wrong path but the official "Hilfe Center" (like helping center or so) from 1&1 said that this must be the right path "e:\Kunden\Homepages\11\d12345678\www\UploadTest" (obviously you have to adapt it to your path, which i got throught phpinfo() )
so I'm using the following code:
<form action=\"upload.php\" method=\"post\" enctype=\"multipart/form-data\">
<input type=\"file\" name=\"datei\"><br>
<input style=\"position:absolute;left:5px\" type=\"submit\" value=\"Hochladen\">
</form>
on the site where you upload the file and
$max_filesize = 524288; // Maximum filesize in BYTES (currently 0.5MB).
$upload_path = "e:\\Kunden\\Homepages\\11\\d12345678\\www\\UploadTest";
$filename = $_FILES['userfile']['name']; // Get the name of the file (including file extension).
if(filesize($_FILES['userfile']['tmp_name']) > $max_filesize)
die('The file you attempted to upload is too large.'); // if we upload large file then we get error.
if(!is_writable($upload_path))
die('You cannot upload to the specified directory, please CHMOD it to 777.'); // if we have no enough permission then got error.
if(move_uploaded_file($_FILES['userfile']['tmp_name'],$upload_path . $filename)){
// if everything is fine then we upload file and go to somewhere else
header ('location: whereeveryouwantogo.php');
} else {
echo 'There was an error during the file upload. Please try again.';
}
on the site where the php script is running (upload.php). I got the code on another thread here and wanted to use it for troubleshooting. Later I'm going back to my own code.
I am now at the last error:
'There was an error during the file upload. Please try again.';
I just want to upload .txt files that are later used on a news based site. Thx for any helps in advance!
I think the problem is name of the input or name of the files variable.
$files=$_FILES['datei']['tmp_name'];

PHP File Copy() Not working on IIS 6

I have the following code that attempts to take a users form input of a file, and upload it to the webserver.
This code does work on a Apache server, however I'm now trying to get the same code working on my Windows IIS 6 web server, which has PHP (Version 5.2.3) installed and working. I have set the PHP.INI file so that
file_uploads = On
upload_tmp_dir = "C:\Temp"
My form is
<form method="POST" action="do_upload.php" enctype="multipart/form-data">
<input type="file" name="img1" size="30">
<input type="submit" name="BtnUpload" value="Click To Upload Now">
</form>
My PHP code to do the upload is
$abpath = "C:\MyWebs\Website1\httdocs\images";
#copy($img1, "$abpath/$img1_name") or $log .= "Couldn't copy image 1 to server";
if (file_exists("$abpath/$img1_name"))
{
$log .= "File 1 was uploaded";
}
else
{
$log .= "File 1 is not an image";
}
For some reason when I check the value of $img1 e.g echo $img1; it is empty. Therefore I tried to get the file using $_FILES['img1']['name']. This worked fine, but still I couldn't upload any files
Any ideas why this is happening.
Your code should be:
move_uploaded_file($_FILES['img1']['tmp_name'], "$abpath/$img1_name");
Don't copy() uploaded files. There are a few edge cases where an uploaded file can be tampered with, which is why move_uploaded_file() exists - it checks for those particular types of tampering.
As well, be VERY careful with how you create your filenames when processing the upload. If you directly use ANYTHING provided in $_FILES as part of the destination path/name for the file, you are opening bad security holes on your server, and a malicious user can exploit that to scribble a file anywhere they want on your server.

$_FILES field 'tmp_name' has no value on .JPG file extension

i was making an upload script when i tested an image file wit this extension .JPG, i don't know whats the difference between jpg or jpeg, but it seems that $_FILES don't recognize this file type.
I've read several threads that $_FILES ins't that reliable when it comes to mime type, so i decided to used the php's mime type function mime_content_type(), php's getimagesize(), pathinfo(), though pathinfo returns a file name, and type, but i need the path of the file which is NOT present, all of the functions are being passed with $_FILES['file']['tmp_name'] as parameters.
So this problem came up when i decided to upload an image file e.g sample.JPG, i think most of this files are raw from the camera <-- that's what i think though but nevertheless what is more important is that i can upload them .JPG, .jpg, jpeg, .png. all of them works fine except for .JPG.
Main problem is that field ['tmp_name'] in $_FILES has no values when .JPG is to be uploaded.
Any of you guys who have encountered this problem please do share your workaround or "how did you do it" kind of thing.
If $_FILES[$field]['tmp_name'] is empty then the file hasn't been uploaded. You should look at $_FILES[$field]['error'] to see why.
FWIW, and as far as I understand it, the mime-type in $_FILES[] is provided by the browser.
Update: here is a bit of potted code to handle all file upload errors:
$message = 'Error uploading file';
switch( $_FILES['newfile']['error'] ) {
case UPLOAD_ERR_OK:
$message = false;;
break;
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
$message .= ' - file too large (limit of '.get_max_upload().' bytes).';
break;
case UPLOAD_ERR_PARTIAL:
$message .= ' - file upload was not completed.';
break;
case UPLOAD_ERR_NO_FILE:
$message .= ' - zero-length file uploaded.';
break;
default:
$message .= ' - internal error #'.$_FILES['newfile']['error'];
break;
}
if( !$message ) {
if( !is_uploaded_file($_FILES['newfile']['tmp_name']) ) {
$message = 'Error uploading file - unknown error.';
} else {
// Let's see if we can move the file...
$dest .= '/'.$this_file;
if( !move_uploaded_file($_FILES['newfile']['tmp_name'], $dest) ) { // No error supporession so we can see the underlying error.
$message = 'Error uploading file - could not save upload (this will probably be a permissions problem in '.$dest.')';
} else {
$message = 'File uploaded okay.';
}
}
}
Check your php.ini and in particular this setting
; Maximum allowed size for uploaded files.
; http://www.php.net/manual/en/ini.core.php#ini.upload-max-filesize
upload_max_filesize = 6M
Or do this in your Apache Config:
<Directory "/var/www/vhosts/path/to/your/directory/import/">
php_value post_max_size 6M
php_value upload_max_filesize 6M
</Directory>
I would also say that it is poor that PHP doesn't report an error in the error logs if you upload a file that is larger than your php.ini upload_max_filesize setting. For example, if you upload a 6MB file when you have it set at 2M (which I think is the default).
Posting an answer because my rating is too low.
Remember to restart your server after setting the max file size cap in your php.ini. I spent hours on this issue thinking that it wasn't a file size problem meanwhile I forgot to restart. After restart everything worked.
I hope this can help someone.
I was having the same problem and being familiar with mostly .NET platform makes you forget about stuff that happens in the client side html.
My problem was my form is having a MAX_FILE_SIZE hidden input which has some value lesser than file's equavalent bytes.
Your form should have this;
Other than that, your form tag must include enctype="multipart/form-data"
I was thining that max file size was in kb, but it's in bytes, thanks to some other page in stackoverflow.
The other reason that might cause this problem your php.ini settings that people have mentioned in previous comments. You should can post_max_size = 200M to php.ini file too.
If you are developing on Windows like me, you can see a dump file that showing errors at C:\Windows\Temp called as "php**VERSION**_errors.log". It helps.
Seems as though it's a random problem because while I was making a script to upload CSV files, some CSV files would have no problem uploading but in other cases, $_FILES['file'][tmp_name] would be empty.
I faced the issue with $_FILES field 'tmp_name' having no value for .JPG file extension and successfully fixed it in few steps. These measures may help someone in the future.
First of all, I implemented the Switch Case solution offered by the
user 'staticsan'. Link here -
https://stackoverflow.com/a/14472801/3681985. This solution helped me
trace the potential issues such as parameters in php.ini file and
folder permissions.
The php.ini file was named php.ini.default. Changing the parameters upload_max_filesize and post_max_size didn't yield any result, until I renamed the file to php.ini. Remember to experiment with parameter values.
After fixing the file name issue, I encountered a challenge with the permissions to the folder in which the uploaded temp image has to be moved. I have changed the permissions and was able to see the image uploaded in to the folder.
Just try this and see what happens,
if (($_FILES['file']['type']) == "image/jpg" || ($_FILES['file']['type']) == "image/jpeg") {
//do uploading stuff here
}else{
echo 'File is not a valid JPG,JPEG';
}

Categories