I want to upload files from a list box in php.
I am able to do it by using <input type="file"> which I found on http://www.tizag.com/phpT/fileupload.php
But when I change this <input type="file"> by <select>
i am trying this way
<form enctype="multipart/form-data" action="upload.php" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="100000" />
Choose a file to upload: <input name="uploadedfile" type="file" />
<select name="uploadedfile" id = "fileName" size="3" style="width: 100%">
<option id = "uploadedfile" value="c:\text.txt">c:\text.txt</option>
</select>
<input type="submit" value="Upload File" />
</form>
and PHP code remains the same for both cases
<?php
$target_path = "uploads/";
$target_path = $target_path . basename( $_FILES['uploadedfile']['value']);
if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
echo "The file ". basename( $_FILES['uploadedfile']['value']).
" has been uploaded";
} else{
echo "There was an error uploading the file, please try again!";
}
?>
it does not work........
Regards
Hemant
You can only use an <input type="file" /> to upload files for security reasons. These input types display a file select box and allow a user to select a file in a secure way. Allowing a server to select arbitrary files to upload like you are trying to do would be a gross breach of security.
For instance, say I implemented your <select> based option (and it worked). I could select your Windows password file to upload. I could select all sorts of nasty files that are in predefined locations.
As a total aside, your HTML has two elements with the same name. Which one is actually sent to the server will be somewhat dependant on your browser and server. You really only want one form element with the same name.
I'm not sure how this is supposed to work, since you are using a drop down box to ask a user to upload a file.
Drop down menus (select > option) are not, in my experience, used as inputs other than for specific choices, like "blue" vs "red".
however, you are going to run into issues with your setup because a) you the first file option outside of the select element and b) you gave both of them the same name, which means that when php gets the POST variable, it's going to create an array with two items with the same key (if it is even getting to that point).
Update
After reading Matthew's answer, I now notice the c:/text.txt you have set as the value. As he said, that's a big time no. You could in theory have it copy the entire hard drive (very slowly of course) or have some AJAX that doesn't even ask the user if they are okay with the upload and get anything on the computer.
I thought somehow you were offering the user the option to "upload" some generic file already on the server because they had nothing they could use on their end.
Related
I am trying to debug my front-end of a HTML/PHP web face and have run into an issue. Currently, the user is able to upload a file, which is then sent to a separate upload function (to process and upload their file to an AWS instance), and then redirects the user to another page.
On the page, I have two options for the user to click- the first of which unhides an option for the user to select and upload their file. This option uploads to the AWS instance and functions normally. The second option unhides some text about download/upload instructions, along with an option for the user to select and upload their file.
Both options do functionally the same thing, with only difference being the second option unhides some text in addition to revealing exactly the same button. Only the first option posts and uploads like normal; the second doesn't upload to the bucket and just returns 'zero' in plain text to the screen. Has anyone experienced anything like this and/or has any advice on how to fix it? Thanks!
Below are the two code snippets for the upload forms:
<form id="Site" method="POST" enctype="multipart/form-data">
<div id="file_input"><input id="files" type="file" name="file"/></div>
<label for="files">SELECT ZIP FILE TO UPLOAD</label>
<br>
<input type="submit" value="submit" name="submitSite">
</form>
and the one that doesn't work (exactly the same?)
<p> Download Instructions Go Here</p><br>
<form id="Site" method="POST" enctype="multipart/form-data">
<div id="file_input"><input id="files" type="file" name="file"/></div>
<label for="files">SELECT ZIP FILE TO UPLOAD</label>
<br>
<input type="submit" value="submit" name="submitSite">
</form>
And the POST function itself is:
<?php
session_start();
$_SESSION['Username'] = '';
$userID = $userID; // change this to be set in database
//set progress
$_SESSION['progress'] = 'upload_section';
'/survey_interface_shared_libraries/progress_emails/store_progress.php';
if (isset($_POST['submitSite'])) { // upload file
Please let me know if you need any further context!
I have a file input element that is used to upload a profile image to a user profile page. By default browsers only allow this element to upload one file unless you add the multiple attribute.
I'd like to set a back up in the PHP though just in case someone decides to add the 'multiple' attribute in the HTML.
I thought assigning the $_POST superglobal to a variable and having an if statement saying if this value is greater than 1 would be prevent this, but it doesn't?
What is the best way to approach this? I've tried various things such as the count() array method but can't seem to find a solution to what seems like a very simple problem?
if(isset($_POST['submit-profile-image'])) {
$profileImage = $_POST['submit-profile-image'];
if (isset($profileImage)) {
if ($profileImage > 1) {
$error[] = "You cannot upload more than one profile image";
}
}
// ALL OTHER CODE
}
I've also tried using the $_FILES superglobal and counting the instances of the $_FILES['profile-image']. This encounters a different problem in that it blocks more than one file upload BUT also blocks single file uploads (and I don't understand why)?
if(isset($_FILES['profile-image'])){
if(count($_FILES['profile-image']) > 1){
$error[] = "You cannot upload more than one profile image";
}
}
You can't prevent a user sending multiple files. All you can do is defend against the possibility, and fail gracefully.
Let's assume that your HTML includes this <form>
<form method='post' enctype="multipart/form_data">
<input type='file' name='uploadFile'>
<input type='submit' name='submit'>
</form>
When the user selects a file and clicks submit the browser packs up the file and sends it, PHP unpacks the file to the server disk, and then presents the file details to your program in the $_FILES['uploadFile'] array.
If we assume that the user edits your HTML and adds multiple then the browser will pack up the files and send them. PHP will unpack the first file and add its detail to $_FILES['uploadFile'] as before. It will then unpack the second file and place its details in $_FILES['uploadFile'], overwriting the first file. Your program sees only one file, knows nothing of any other file, and carries on.
To get two files your user will have to change the name of the file input to use array syntax, so lets suppose he changes the line to
<input type='file' name='uploadFile[]' multiple>
Now PHP unpacks the file details into a set of arrays. Instead of having $_FILES['uploadFile']['name'] containing a string with one filename, it becomes an array of strings.
It is likely that your code, expecting a string, will choke on an array and fail in some unexpected way. You can check for this condition with
if (is_array($_FILES['uploadFile']['name'])) {throw new Exception("Too many files");}
So, our user, determined to force this extra file on you now adds a second <input> to the form:
<form method='post' enctype="multipart/form_data">
<input type='file' name='uploadFile'>
<input type='file' name='uploadFile'>
<input type='submit' name='submit'>
</form>
The second file overwrites the first as it has the same name. Your program is none the wiser and carries on with just one file. So the user changes the name on the second input:
<form method='post' enctype="multipart/form_data">
<input type='file' name='uploadFile'>
<input type='file' name='uploadFileB'>
<input type='submit' name='submit'>
</form>
You could check for this by looking at count($_FILES), but your program isn't looking for a second input, so it will ignore it anyway and carry on handling just the first file. If the user also changes the first name your program won't see any files, and if he reverses the names, your program will see just the second file and ignore the first.
Alternatively, set the PHP configuration value in PHP.INI:
max_file_uploads = 1;
If you do this, PHP will ignore the second and subsequent files. Your code will still have to deal with the naming issues. Setting this with ini_set() doesn't seem to have any effect.
I'm currently working on a photoalbum thing on my website and was wondering is there is a way to upload files separately even though I selected multiple files for upload, let me explain:
<form method="post" action="upload.php" enctype="multipart/form-data">
<input name='uploads[]' type="file" accept="image/*" multiple>
<input type="submit" value="Send">
</form>
<?php
$y=count($_FILES['uploads']);
for($x=0;$x<$y;$x++) {
echo $_FILES['uploads']['name'][$x];
echo "<br>";
}
?>
So I've got these simple lines of code. And basically (As you can see) you can upload multiple files. But let's say that that my 'upload_max_filesize' is at 8M. I can only select 4 images of 2MB each to upload successfully, otherwise I overwrite the max upload size. My question is, is there a PHP way to keep the form structure the same but let the script handle one file at the time so I can upload 5.000 files from 5MB's each for example?
I've got a page where users can upload a HTML file for use as a theme. The HTML file has some checks performed on it before some options are displayed to the user. The user fills out the form in relation to the HTML file, and submits the form. However, due to the file in the temp folder being destroyed after the script has ended, I do not know how to get the HTML file once the form has been filled out and re-submitted short of making the user re-upload the file, which relies on them uploading the same file, and also makes them upload something twice, which is counter-intuitive and could be an issue with large files.
Here is the code (cut down to make it easier to read/understand). The form submits to itself, so the same PHP file is used for both "steps".
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Form has been submitted
$files = $_FILES['file'];
<form method="POST">
/* Options about the uploaded HTML file are generated using PHP and displayed here */
<input type="submit">
</form>
} else {
?>
<form method="POST" enctype="multipart/form-data">
<label for="file">Theme File(s)</label>
<input type="file" name="file[]" multiple="multiple">
<input type="submit">
</form>
<?php
}
I tried using <input type="file" name="file[]" multiple="multiple" value="<?php echo $files; ?> >, but this did not work, and would also require the user to re-upload the files, which could be any issue if the files get too big.
I was thinking there might be a way to pass the file internally, and have a check whether a file has been uploaded or passed to the script instead of <input type="file" name="file[]" multiple="multiple">, but I could not find a way to do that.
You need to create your own temporary file, and pass the name between your two scripts.
So for example, in your "first script" (i.e. when the file has first been uploaded) you would:
$uniqName = uniqid('upload_', TRUE);
$tmpFile = "/tmp/$uniqName.html";
move_uploaded_file($_FILES['file']['tmp_name'][0], $tmpFile);
And then when you generate the form from the result of this upload, you would add
<input type="hidden" name="uniqName" value="<?php echo $uniqName; ?>" />
...so that when you get to your "second script" (after the questionnaire form is submitted) you can access the file through:
$tmpFile = "/tmp/".basename($_REQUEST['uniqName']).".html";
Of course, this is subject to the possibility of people failing to submit to second form so you end up with "orphaned files" littering your temporary directory, so you will need to implement some form of check that deletes files after thet have been inactive for a certain amount of time - you can base this on the last modified time of the files.
EDIT
Here is an example of how you can randomly run a job to keep the /tmp dir tidy without a cron job:
$probabilityDivisor = 10; // 1/10 chance of running
$uploadTTLSecs = 1800; // 30 minutes
if (mt_rand(1, $probabilityDivisor) / $probabilityDivisor == 1) {
foreach (glob('/tmp/upload_*') as $file) {
// Iterate files matching the uniqids you generate
if (time() - filemtime($file) >= $uploadTTLSecs) {
// If file is older than $uploadTTLSecs, delete it
unlink($file);
}
}
}
This operates in a similar way to the PHP session garbage collectors. Because of the simplicity of the operations, this should not adversely affect the user experience in any meaningful way.
You could try the following:
Use move_uploaded_file() and move the file from the temp location to a permanent location on the server. Be sure to give the file your moving a unique name like 'file-' . time() . '.jpg' or something.
Soon after uploading, register a Session variable and put the file name in it.
After everything is over you could delete the file using unset()
Now the file is located safely on your server and you also have access to it via the session.
Hope this helps :)
My PHP book gives a template HTML form for uploading a file:
<form action="upload.php" method="post" enctype="multipart/form-data"/>
<div>
<input type="hidden" name="MAX_FILE_SIZE" value="10000000"/>
<label for="userfile">Upload a file:</label>
<input type="file" name="userfile" id="userfile"/>
<input type="submit" value="Send File"/>
</div>
</form>
The book displays it as "Upload a file:" [textbox] [Browse...] [Send File]
I copied it verbatim, and the result I'm getting is "Upload a file:" [Choose File] "no file chosen" [Send File]
I'm wondering why the discrepancy exists. Is there a way around it? I'm using XHTML Transitional. No doctype is given in the book. But I doubt that's the issue.
The script I'm writing aims to take the file the user chooses, process it, and write the result into another file that doesn't exist yet. I'm asking this question because it would be useful to let the user more easily copy the initial file path/name, paste it into the other field, and just change a part of it.
(Also: why the difference between "Browse..." and "Choose File"? I tried manually setting the value of the "userfile" field to "Browse..." but nothing happened. This is less important but I'm curious nonetheless.)
It is probably showing a different browser and/or version.
It sounds like you are looking at it under Safari and the book has screenshots of IE, for example.
There are a few ways to get complete control of file uploading and the <input type="file" /> element. You can use Flash, or you can set the input to opacity: 0 and then position what you want beneath it.
Some time ago the browser engines took almost complete control over the input type="file" - fields, since it nowadays is regarded as a security issue. For example the days before that you could easily prefill the file input filed with some path and filename (e.g. something like /etc/passwd) and hide the field, so sending the form you would not remark that you're also sending the file...
That's why for example you could not preset the filename of such a field and that's also why browsers now all do their own thing with these special input fields.
As Alex said above, you could get around this, but it will be some hassle, because it would mean to "fake" the file input field.