Got a script I've used several times, using move_uploaded_file. But what I can't figure out is why it do not respond in any way, no error reports, nothing.
<form> using method="post", target="upload" that is an <iframe>
action="file.php" responds to $_FILES
Correct enctype
Filerights is set to 777
Upload folder "uploads" exists
print_r($_FILES['file']) gives me:
Array
(
[name] => 1392930853.png
[type] => image/png
[tmp_name] => /tmp/php0rZdBf
[error] => 0
[size] => 611
)
The code below illustrates my script, and what I've figured out is that the last line with move_uploaded_file is the cause of my problem as it do not respond at all. As I wrote above, no error, no nothing.
Pastebin to script: http://pastebin.com/49m9Siqi
Got a clue what could be the cause of this?
$destination_path = getcwd().'/uploads/';
//echo $destination_path;
// File handling
$counted = count($_FILES['file']['name']);
$counted = $counted-1;
for ($i=0; $i<=$counted; $i++) {
if ($_FILES['file']['error'][$i] == UPLOAD_ERR_OK) {
$md5file = rand() . rand() . md5($_FILES['file']['name'][$i]) . rand() . rand();
if(move_uploaded_file($_FILES['file']['tmp_name'][$i], $destination_path . $md5file . "." . basename($_FILES['file']['type'][$i]))) { echo 'THIS WILL NOT BE ECHOED OUT ON THE PAGE'; }}}
There was a simple error in my form, as I handle my uploaded files like an array I need to create the array first.... Which I forgot to do in my form.
Wrong
<input type="file" name="file">
Correct
<input type="file" name="file[]">
Related
I'm trying to download a file from my website to my server but can't find why or where I'm doing that wrong.
Here my php code :
$fn = $_FILES['file']['name'];
if (is_writable('.')) {
echo "Writable<BR>";
} else {
echo "Not writable<BR>";
}
$upfile = './'.basename($fn);
echo $upfile.'<BR>';
shell_exec("echo 'baaaaah' > test.baaaah");
$f = $_FILES['file']['tmp_name'];
echo $f.'<BR>';
if (is_uploaded_file($f)) { echo "uploaded<BR>"; } else { echo "not uploaded<BR>";}
$com = "test - f ".$f." && echo 'F' || echo 'N'";
echo $com.'<BR>';
echo shell_exec($com).'<BR>';
if (move_uploaded_file($f,$uploadfile)) {
echo "File transfer OK<BR>";
} else {
echo "File transfer NOK<BR>";
}
print_r($_FILES);
And here the website output :
Writable
./flag.jpg
/tmp/phpyKvhEz
uploaded
test - f /tmp/phpyKvhEz && echo 'F' || echo 'N'
N
File transfer NOK
Array ( [file] => Array ( [name] => flag.jpg [type] => image/jpeg [tmp_name] => /tmp/phpyKvhEz [error] => 0 [size] => 1660 ) )
So first thing I check if my folder is writable (it's not intended to be '.' but I moved to here because the folder I want wasn't working either (same behavior as '.' through...)) => check
Then I try to shell_exec a file here juste to be sure => check, file is on server
Then I check if the temp file is created on the server :
- check, anyway is_uploaded thinks the file is here
- not check, but a test on the temp file doesn't work (and since the file is not supposed to be removed before the end of the script it should see the file here imho ?)
Then I try to make the move_uploaded_file => not check
And I print the $_FILES who shows nothing suspicious (error = 0, file names matches what I see before).
I can't figure what goes wrong nor where a mistake can come from ><
$uploadfile is undefined in your code. Change it or set it to '.' and it should work.
With PHP 5 I would like to upload an XML file via a web form and parse it using SimpleXML.
I've tried few SimpleXML examples and they work fine at my CentOS 6 Linux server.
However, I don't have any experience with handling uploaded files in PHP yet.
Should I use the $_FILES and do I always have to use a temporary file or can it be done completely in memory?
From PHP Cookbook I've copied this example:
<html>
<body>
<?php if ($_SERVER['REQUEST_METHOD'] == 'GET') { ?>
<form method="post" action="<?php echo $_SERVER['SCRIPT_NAME'] ?>"
enctype="multipart/form-data">
<input type="file" name="doc"/>
<input type="submit" value="Send File"/>
</form>
<?php } else {
if (isset($_FILES['doc']) &&
($_FILES['doc']['error'] == UPLOAD_ERR_OK)) {
$oldPath = $_FILES['doc']['tmp_name'];
$newPath = '/tmp/' . basename($_FILES['doc']['name']);
if (move_uploaded_file($oldPath, $newPath)) {
print "File moved from $oldPath to $newPath";
} else {
print "Couldn't move $oldPath to $newPath";
}
} else {
print "No valid file uploaded.";
}
}
?>
</body>
</html>
It works fine and for the print_r statement added by me the following output is printed:
Array
(
[document] => Array
(
[name] => my_file.xml
[type] => text/xml
[tmp_name] => /tmp/phpRD9cYI
[error] => 0
[size] => 1610252
)
)
And I can see the /tmp/my_file.xml file.
My question is though if I can skip the creation of temporary files?
I don't like them because:
They are sometimes security issue
They have to be cleaned up (by a cronjob?)
Their names might collide (probably seldom case unless it's 1)
UPDATE: Also, I don't understand, why can't I read the file at $oldPath? It is not found there and I have to call the move_uploaded_file() and then read the $newPath...
You don't need to save/move the file in a new folder,
if (isset($_FILES['doc']) && ($_FILES['doc']['error'] == UPLOAD_ERR_OK)) {
$xml = simplexml_load_file($_FILES['doc']['tmp_name']);
}
The tempfile generated will be automatically removed when the PHP script finishes. Hope this helps.
Here is the form
form action="index.php" method="POST" enctype="multipart/form-data" >
<input type="file" name="image[]" multiple="multiple">
<input type="submit" value="upload">
</form>
I am trying to only run my code when only when if(!empty($_FILES['image'])){ but for some reason the array is not empty upon submitting no files and only clicking submit.
Here is the rest of the code if that will help, thanks.
<html>
Image Upload
<form action="index.php" method="POST" enctype="multipart/form-data" >
<input type="file" name="image[]" multiple="multiple">
<input type="submit" value="upload">
</form>
<?php
include 'connect.php';
if(!empty($_FILES['image'])){
echo $_FILES['image']['error'];
$allowed = array('jpg', 'gif', 'png', 'jpeg');
$count = 0;
foreach($_FILES['image']['name'] as $key => $name){
$image_name = $name;
$tmp = explode('.', $image_name);
$image_extn = strtolower(end($tmp)); //can only reference file
$image_temp = $_FILES['image']['tmp_name'][$count];
$filesize = filesize($_FILES['image']['tmp_name'][$count]);
$count = $count +1;
if(count($_FILES['image']['tmp_name']) > 5){
echo "You can upload a maximum of five files.";
break;
}
else if(in_array($image_extn, $allowed) === false){
echo $name." is not an allowed file type<p></p>";
}
else if($filesize > 1024*1024*0.3){
echo $name." is too big, can be a maximum of 3MB";
}
else{
$image_path = 'images/' . substr(md5($name), 0, 10) . '.' . $image_extn;
move_uploaded_file($image_temp, $image_path);
mysql_query("INSERT INTO store VALUES ('', '$image_name', '$image_path')") or die(mysql_error());
$lastid = mysql_insert_id();
$image_link = mysql_query("SELECT * FROM store WHERE id = $lastid");
$image_link = mysql_fetch_assoc($image_link);
$image_link = $image_link['image'];
echo "Image uploaded.<p></p> Your image: <p></p><a href = $image_link>$image_path</a>";
}
}
}
else{
echo "Please select an image.";
}
?>
This is how $_FILES array looks like when nothing uploaded
Array ( [image] => Array ( [name] => [type] => [tmp_name] => [error] => 4 [size] => 0 ) )
So it's never empty.
The error code 4 [error] => 4 indicates no file was uploaded and error code 0 indicates no error and file was uploaded so you can check
if($_FILES['image']['error']==0) {
// file uploaded, process code here
}
Here is another answer on SO.
Use the is_uploaded_file PHP function instead:
if(is_uploaded_file($_FILES['image']['tmp_name'])) {
//code here
}
http://php.net/manual/en/function.is-uploaded-file.php
You should first of all take a look into the PHP manual because - you're not the first one with that problem - the solution has been written in there:
If no file is selected for upload in your form, PHP will return $_FILES['userfile']['size'] as 0, and $_FILES['userfile']['tmp_name'] as none.
So if you actually want to find out if any file for the image element has has been submitted, check for it:
$noFile = $_FILES['image']['size'][0] === 0
&& $_FILES['image']['tmp_name'][0] === '';
Yes, that simple it is.
The test you used:
empty($_FILE);
will only tell you if the whole form has been submitted or not. So an example in full:
$submitted = empty($_FILE);
if ($submitted) {
$noFile = $_FILES['image']['size'][0] === 0
&& $_FILES['image']['tmp_name'][0] === '';
if ($noFile) {
...
}
}
Check value is not null:
in_array(!null,$_FILES['field_name']['name'])
if($_FILES['image']['error'] === UPLOAD_ERR_OK) {
// Success code Goes here ..
}
UPLOAD_ERR_OK returns value 0 if there is no error, the file was uploaded successfully.
http://php.net/manual/en/features.file-upload.post-method.php
If no file is selected for upload in your form, PHP will return
$_FILES['userfile']['size'] as 0, and $_FILES['userfile']['tmp_name']
as none.
You get an array entry per "file" upload field, even if the user didn't select a file to upload.
I have confronted this issue with a multiple file input.
What I found to be working for checking if any file has been selected is:
<?php
$size_sum = array_sum($_FILES['img']['size']);
if ($size_sum > 0) {
// at least one file has been uploaded
} else {
// no file has been uploaded
}
?>
if(!empty($_FILES['image']['name'][0]) || !empty($_FILES['image']['name'][1]) ||
!empty($_FILES['image']['name'][2]))
or
for($1=0;$i<count($_FILES['image']);$i++){
if(!empty($_FILES['image']['name'][$i])){
// do something
}
}
if(isset($_FILES['file'])){//do some thing here}
As a bit of a follow up to Javascript form won't submit (to view the code I am using visit that link) I am now encountering a problem that I cannot find the file that has been uploaded.
I have added $files = apc_fetch('files_'.$_POST['APC_UPLOAD_PROGRESS']); to the top of my page and this is the output of print_r($files);
Array
(
[theFile] => Array
(
[name] => tt1.mp4
[type] => video/mp4
[tmp_name] => /tmp/php2BEvy7
[error] => 0
[size] => 1050290
)
)
However when I try to run the following code:
if (file_exists($files['theFile']['tmp_name'])) {
$webinarType = strcmp($files['theFile']['type'], 'video/mp4');
if($webinarType == 0) {
$webinarFile = $fileTitle;
$webinarTempName = $files['theFile']['tmp_name'];
} else {
echo 'Webinar must be .mp4';
}
} else {
echo "No File";
}
I get the No File output.
I have ssh'd into the server and the file is not in /tmp/, /path/to/public_html/tmp/ or path/to/file/tmp/ all of which exist.
I have tried to use move_uploaded_file() but as this is executed on all file inputs I can't get the tmp_name dynamically due to my limited knowledge of javascript.
tl;dr version; Where is my file gone and how can I find it?
NOTE; This form did work before the APC intevention and I am running wordpress in case that affects anything.
Fixed this one on my own as well.
In the progress.php file (found on the other question) I modified the elseif statement with this:
elseif(($s_progressId = $_POST['APC_UPLOAD_PROGRESS']) || ($s_progressId = $_GET['APC_UPLOAD_PROGRESS']))
{
// If the file has finished uploading add content to APC cache
$realpath = realpath($PHP_SELF);
$uploaddir = $realpath . '/tmp/';
foreach ($_FILES as $file) {
if(!empty($file['name'])) {
$uploaded_file = $file['name'];
$moveme = $uploaddir.$uploaded_file;
move_uploaded_file($file['tmp_name'], $moveme);
}
}
apc_store('files_'.$s_progressId, $_FILES);
die();
}
That way I could iterate through the $_FILES array without knowing the name of the input. I noticed that it loops through a couple of times hence the if(!empty()) however in hindsight it's probably best practice anyway.
I have a website up and running which makes use of file uploads. Everything is working fine, except for one of the users. They are using IE8 to upload files from their SharePoint server to the website. When I look at the $_FILES variable in PHP the 'name' key looks like this:
somefilename[1]
Instead of
somefilename.pdf
The uploads are then blocked, because the extension is not allowed. Has anyone ever dealt/seen this before? It looks like a temporary name, or a hidden file extension.
Edit:
Some of you requested the $_FILES variable:
[Filedata] => Array
(
[name] => Algemene%20Voorwaarden%20Corporate%20Services%202011[2]
[type] => application/octet-stream
[tmp_name] => /tmp/phps19zye
[error] => 0
[size] => 148021
)
This should be a PDF file. I need the extension, not only for security reasons, the [type] would be better suited for that, but also for presentation and functionality. I need to display the correct icon for a file type, and separate images for processing.
The HTML form is just a basic test form:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<form action="uploadtest3.php" method="post" enctype="multipart/form-data">
<input type="file" name="file_upload" id="file_upload" />
<br /><input type="submit" value="Uploaden" />
</form>
</body>
</html>
The PHP file is the following:
$targetFolder = '/uploadtests/uploads3';
if (!empty($_FILES)) {
$tempFile = $_FILES['file_upload']['tmp_name'];
$targetPath = $_SERVER['DOCUMENT_ROOT'] . $targetFolder;
$targetFile = $targetPath . $_FILES['file_upload']['name'];
move_uploaded_file($tempFile,$targetFile);
echo "OK";
}
Introduction
Have seen this issue before but am not sure what caused it. I would not even like to call it an error because some files extension can be intentionally removed or altered for malicious purpose.
The most important thing is validating file properly and worry less if a file has extension or not
Reasons :
File Extension Can easily be faked and it would be bad if your application relies on file extension only for validation
$_FILES ['file_upload']['type'] would return application/octet-stream for all files with not extension so it not not also a option for validation
Since its a browser issue then its a Client Related Problem so you don't have any control. If you are able to manage this you would definitely increase user experience
Simple Patch
The solution is very simple. All you need to validate your file with FILEINFO and fix any extension issue to your uploaded file.
You also need to validated all uploaded file based on their Mime Type ... and remove any invalid file.
Prove of Concept
$allowedTypes = array (
"pdf" => "application/pdf"
);
$pathFinal = "final";
$pathTemp = "temp";
try {
if (! empty ( $_FILES )) {
$tempFile = $_FILES ['file_upload'] ['tmp_name'];
$fileName = $_FILES ['file_upload'] ['name'];
$destinationTemp = $pathTemp . DIRECTORY_SEPARATOR . $fileName;
$destinationFinal = $pathFinal . DIRECTORY_SEPARATOR . $fileName;
/**
* Move To tempary File
*/
move_uploaded_file ( $tempFile, $destinationTemp );
$fileMime = mimeInfo ( $destinationTemp );
$key = array_search ( $fileMime, $allowedTypes );
/**
* Validate Mime Type
*/
if (empty ( $key )) {
unlink ( $destinationTemp );
throw new Exception ( "File Type not Supported" );
}
/**
* Fix Extention Issues
*/
$ext = pathinfo ( $destinationTemp, PATHINFO_EXTENSION );
if (empty ( $ext )) {
$destinationFinal .= "." . $key;
}
/**
* Transfer File to Original Location
*/
copy ( $destinationTemp, $destinationFinal );
unlink ( $destinationTemp );
echo "OK";
}
} catch ( Exception $e ) {
echo "ERROR :", $e->getMessage ();
}
Function Used
function mimeInfo($file) {
return finfo_file ( finfo_open ( FILEINFO_MIME_TYPE ), $file );
}
somefilename appears to be an array. Are your users selecting more than one file to upload?? You need to limit the number of files allowed to upload, or catch the array and handle it properly. You might also ensure that Sharepoint is set to allow multiple file uploads.
Also, I found information regarding the way that IE8 passes the file upload to the server. The source article states:
Additionally, the “Include local directory path when uploading files” URLAction has been set to "Disable" for the Internet Zone. This change prevents leakage of potentially sensitive local file-system information to the Internet. For instance, rather than submitting the full path C:\users\ericlaw\documents\secret\image.png, Internet Explorer 8 will now submit only the filename image.png.
This means, if your code (or Sharepoint) is looking to delimit the folder structure from filename by PATH_SEP, then with IE8 it will obviously fail.
You should check the file type not by extension but by Mime type. Use the variable $_FILES["uploaded_file"]["type"] to get the Mime type.
This way users cannot tamper with the extension with weird ASCII characters, and you know what file is what reliably.