save chosen file, when form validation fails - php

I've got a form with some input fiels. One of them is a file upload field.
When the user submits the form, every field will be validated and the page gets reloaded with the error messages, but all other fields still showing the users input. Now I want, that once a user has chosen a file, and the form can't be validated because of other errors, the chosen file still will be uploaded after a resubmission.
I display the entered values with the value property. I know that you can't set the value of an file input, because of security issues.
This is what I've got so far:
<?php
if(isset($fileUpload))
{
echo "<span>selected File: ".$fileUpload["name"]."<span>";
$_FILES["file-upload"]=$fileUpload;
} ?>
<input type="file" class="button" name="file-upload" id="file-upload" accept=".zip"/>
This happens after submission:
if (!isset($_FILES["file-upload"]))
{
$uploadError = "Please choose a file";
$hasError = true;
} else {
$fileUpload=$_FILES["file-upload"];
}
The submitted file is stored in $fileUpload. I tried to set the $_FILES["file-upload"] variable manually, but it doesn't seem to work.
After resubmission, $fileUpload["name"] is empty.
How can I save the selected file, so the user hasn't to reselect it after an unsuccessful submission?

You cant store the file value after loading page like other fields ( the other way is you can upload the file and in return you can pass the uploaded file value in hidden , if user add file again the unlink the previous file otherwise the use the file which uploaded in first step. )

Related

Different browsers show different behaviour with input type file

I have 2 file upload fields in my form. Both look like this:
<input type="file" id="file1" name="file1" accept="application/pdf,application/msword">
<span id="file1_status">Currently uploaded: <?php echo $file1_fileName; ?></span>
<input type="file" id="file2" name="file2" accept="application/pdf,application/msword">
<span id="file2_status">Currently uploaded: <?php echo $file2_fileName; ?></span>
where $file1/2_fileName; is either "none" when the page is first loaded or equal to $_FILES["file1/2"]["name"] after a post event.
Toward the end of the page, I do
$(document).ready(function () {
jQuery("input#file1").change(function () {
var val = $(this).val();
_('file1_status').innerHTML = "Currently uploaded: " + val.substr(12); // removes C:/fakedir/
});
Same for file2. So, basically if someone uploads "file.pdf", there is a text under the file input that reads: "Currently uploaded: file.pdf". I do this so the user sees that the file is still there if form validation fails after form submission.
OK so far so good.
Rather than using "required" in the input file field, upon form submission, I do the following:
if (is_uploaded_file($_FILES["file1"]["tmp_name"])) {
// check mime_type, file size, etc.
} else {
// display an error below the input field that a file is missing.
}
Same for file2. Now to the actual question/problem.
Imagine the following situation. A user only uploads file1 but forgets file2 and clicks submit. This is what happens:
Firefox (latest version): Below the file1 field the status still shows "Currently uploaded: file1.pdf" and below the file2 input field an error message is displayed to remind the user to upload this file also. If the user complies and uploads file2, then clicks on submit again, the form is submitted and all is fine, i.e., both files have been attached to the form submission. This is the expected behaviour.
Chome/Edge: For the same user behavouir everything is the same except for when the user clicks on submit a second time. For some reason, both these browsers now show an error below the file1 input field (although it still shows "Currently uploaded: file.pdf" which the user uploaded in the very beginning). So for some reason, and although $_FILES["file1"]["tmp_name"] is not empty, the test
is_uploaded_file($_FILES["file1"]["tmp_name"]) fails upon the second form submission in both Chrome and Edge but not in FF.
This is very confusing. Why is this and how can this be avoided/fixed?
It seems that the Edge/Chrome behaviour is indeed to expected/normal behaviour. To my great embarrassment I have not been able to reproduce the above behaviour in FF anymore so I am not exactly sure what happened because I really did see a different behaviour while testing it for about an hour or so.
Anyway, for all practical purposes, I was able to work around the issue by moving the files that met all my criteria (re mime types, file size, etc) into a temporary upload directory on my server, store the file name in a session variable, and modify this code:
if (is_uploaded_file($_FILES["file1"]["tmp_name"])) {
// check mime_type, file size, etc.
} else {
// display an error below the input field that a file is missing.
}
to this
if (is_uploaded_file($_FILES["file1"]["tmp_name"])) {
// check mime_type, file size, and if OK move to upload directory on server and store the name of the successfully uploaded file in $_SESSION["file1"]
} elseif (!empty($_SESSION["file1"])) { //basically this gets invoked the second time round, i.e., when the user uploads the 2nd file they forgot when submitting the form for the first time
$file1_fileName = $_SESSION["file1"]; // used to display under the input file element (see above)
} else {
// display an error below the input field that a file is missing.
}
Same for file2. So while the first "if" condition fails upon the 2nd form submission, the "elseif" condition is true and no error is issued.

Making file input a not required field - bootstrap file input

I want to make file input field not required , I have 2 fields for file input one is for profile picture and another for uploading documents.
If I do not select any image it says "You did not select file to upload" for both documents and profile picture
If I select a file it works perfectly fine.
The file field should not be mandatory.
I am using this plugin : http://plugins.krajee.com/file-input/demo for front end design
Following is the code I tried on form submit
if(!array_filter($_FILES['docs']['name'])) {
//upload file
}
if($_FILES['profile_pic']['name']!='') {
//upload file
}
What is wrong in the above code. Can anyone please tell why it is not working...

Data in text file gets erased on form submit click

For a website, the user should be able to type a title and post in a form and press a submit button to enter them. Upon pressing the submit button, the data in the forms are written to their assigned text files which are in the same folder as the webpage. The writing works fine, but as you can see below, I have attempted to make it so that if the user clicks the submit button without one of the two fields (or neither of the fields) being filled in the site will prompt them to enter text and no file writing takes place.
My issue is that when they click submit and a field isn't filled, this will actually affect the .txt files and they will also end up blank. I want the files to retain their 'old' text unless both textareas in the form contain data to be overwritten. For example, if both .txt files have text in them and I click submit on the form with no text in the form, the two .txt files will keep their text instead of being overwritten to have no text (which is what currently happens).
Here's the html and php:
<form action="AdminBlog.php" method="post">
Blog Title:<textarea type="text" name="titleInput"></textarea><br><br>
Blog Post:<textarea type="text" name="postInput"></textarea><br><br><br>
<input type="submit" value="Submit"/>
</form>
<?php
$titleFile = fopen("Title.txt","w");
$blogTitle = null;
$postFile = fopen("Post.txt","w");
$blogPost = null;
if(!empty($_POST['titleInput']) && !empty($_POST['postInput'])) {
$blogTitle = $_POST['titleInput'];
fwrite($titleFile,$blogTitle);
fclose($titleFile);
$blogPost = $_POST['postInput'];
fwrite($postFile,$blogPost);
fclose($postFile);
}
if (empty($_POST['postInput']) || empty($_POST['titleInput'])) {
echo "Please enter a title and post.";
}
?>
Changing that final if statement to elseif or else didn't seem to make a difference. The echo is outputted when it should be, but the .txt files are still overwritten with no data (when a textarea is blank and user clicks submit).
EDIT: Just wanted to add something. I'm not sure if this is relevant, but whether there is text in the files or not, I cannot read the text from another .php file. I can from this same one, but when trying to get the .txt file contents in another .php page, I cannot do so. This is also causing me a separate problem, just wanted to mention in case it was anything useful.
I think you need to try
file_put_contents($file, $person, FILE_APPEND);
for write file.
1st argument will be name & path of the file.
2nd argument will be data in string format.
3rd argument will be FILE_APPEND if you want to add content in existing file.
if you will not use 3nd argument then it will replace content of the file all time.
Source
There is a > missing in your html after <textarea type="text" name="postInput".
Try to put that on.

file validation, preserving the file location

I'm trying to create a full validation page for an input (sql insert) form.
What I've typically been doing are the following to preserve the values already input on the page in case one piece of validation fails (in which case the user is returned to the form to correct it with an error shown).
echo 'value=" ';
if(isset($_POST['NewGameName'])){
echo $_POST['NewGameName'];
} // for text-fields
echo '<option value="'.$i.'" ';
if(isset($_POST['Score'])){
if($i == $_POST['Score']){
echo'selected="selected"';
}
}
echo '>'.$i.'</option>'; // for dropdowns
But I can't seem to find a way to preserve the file location if the page is refreshed. Is there a way to do this? I've read that it's always cleared for security reasons which would be annoying but if it's the standard I guess people are used to it.
you could create a hidden field to store the file name and change the name through javascript by using onchange event on the actual file field.
as soon as file name changes you could update the hidden field value.
you get the hidden field value in the post variable and use this variable to refresh the value of the file field
I think you have 2 options.
is to use Ajax for validation. This way you don't leave the form with the filepath.
Use javascript after the validation to go back in history history.go(-1) to the previous screen. I think when using history, the form entries are preserved.

Can I submit a form and add record to DB by only php in the same file without using Get/Post methods?

Say I have create a registration form. Now to add records into a DB, we send the data to another php file by POST method, where we do some validations and add a record. Is it possible to do it in the same file without sending and getting the data by POST/GET? If no, then why?
EDIT: Even sending to the same php file is SENDING and losing resource. I ask this question because I want to avoid the lost of time on sending by GET/POST and getting by the same Get/POST. And if it is not posible, I want to understand why PHP does not allow.
No. You always have to send data from the client to the server, there is no way around that.
If you dont want to reload the entire page the user is on, you could submit the data via AJAX to the php file responsible for processing it and adding the data. That way the user never leaves the page.
yes ofcourse.
just in your form "action" put
$_SERVER['PHP_SELF']
then in the beginning of your PHP page check if the $_POST is set or not
if(isset($_POST))
{
// actions to be taken after form submission
}
ofcourse you can add a hidden input tag for refining checks for the $_POST. eg in your form
<input type="hidden" name="formSubmit" value="yes" />
then your check should be like
if(isset($_POST['formSubmit']))
{
// actions to be taken after form submission
}
It's possible. For example:
<?php
if(true === isset($_POST['submit']) // check if submit-button was clicked
{
// do some validation here...
// If validation successes add record into db here...
}
else // no post data sent so output the form
{
// output the form here...
}
Yes it is possible set
action="same page"
in form tag.
you can access your all form attributes on same page.
Yes it is easy. The form can post back to its self. This is most easily done by not even specifying the value of action in the form tag.
<form method='POST'>
Then at the top of the page before any content is put on the page, include an if statement to check if the form was submitted.
if (isset ($_POST['post'])) { // 'post' is the name of the submit button
$error = false;
// Do validation
From there do validation and act according to the result.
If you have lots of validation to do, perhaps put that in another file and include it.
include "formValidation.php";
If all is well and all tests are passed use
if ($error === false) {
Header ("Location: confirmation.php");
exit;
}
}
If tests fail, stay on the page keeping all the post data, and display an error.
if (isset ($error) && !empty ($error)) {
echo "<div class='error'>$error</div>";
}

Categories