As for an assignment I created a filter that modifies a Config that's connected to an API which prints out Order files. The web application has the option to save the modified Orderlist with a date and number added to it.
I've been asked to add a feature that allows my task giver to remove the order files he wishes to delete. I've asked a question before how I could remove a file through a file input, but this doesn't seem to be efficient considering it'll be eventually thrown in a private server. Now the best idea was to include the directory and print it out in a list, allowing the user to select the file they wish to remove.
With a lot of looking around I tried to find something that suited my resolve to this as best as I could and stumbled on this. It does print out an array and show checkboxes, but the file names(example Order file 26-1-2021 version 1.xml) are not displayed right next to the checkboxes. - My second question: How do I delete the order file you specifically checked through the submit button?
my code
<?php
$dir = '..\api-ivolved\s_orderlist';
$files1 = scandir($dir, 1);
foreach ($files1 as $filename => $n) {
echo "<input type=\"checkbox\" name=\"files[]\" value=".$filename."/>";
}
if (isset($_POST['delete'])){
unlink( /* Value here */ );
}
?>
<form class="deleteFile" method="get" enctype="multipart/form-data">
<input type="submit" id="delete" value="Delete file"/>
</form>
It appears you are checking $_POST for the delete flag rather than $_GET. Because your form submits using "get", this will cause it to never detect the delete checkbox. I've added a corresponding "delete" field/checkbox within your form to reference the field you are checking for.
For displaying the filenames besides the textbox, you will need to output this separately. I've added this after the checkbox itself, followed by a line break.
I've also "buffered" your input fields so that they get outputted inside of the form tags (rather than before).
Try something like this:
<?php
$dir = '..\api-ivolved\s_orderlist';
$files1 = scandir($dir, 1);
// We need to output the fields AFTER the opening form field. We "buffer" them for now and output them later.
$fields = "":
foreach ($files1 as $filename => $n) {
// Output the filename beside the textbox.
$fields .= "<input type=\"checkbox\" name=\"files[]\" value=".$filename."/>" . htmlspecialchars($filename) . "<br />";
}
if (isset($_GET['delete'])){
// Make sure files are checked/marked for deletion.
if (!empty($_GET['files'])) {
// Loop through each file and delete
foreach ($_GET['files'] as $file) {
unlink($file);
}
}
}
?>
<form class="deleteFile" method="get" enctype="multipart/form-data">
<?php echo $fields; ?>
<br />
<strong> Delete checked files? </strong> <input type="checkbox" name="delete" value="1"/><br />
<input type="submit" id="delete" value="Delete file"/>
</form>
It's worth noting to make sure that you have robust permissions checking in your application, since a simple link will cause a file to be deleted. This can technically cause a CSRF vulnerability (a special type of vulnerability that would allow someone to create a image/link on another website with a full link to do unwanted business). To prevent this, look into adding CSRF tokens to check links in your script (various robust guides exist online for this sort of thing) :)
The question posed is a little different to the original so I hope the following helps you resolve your confusion.
<?php
$dir=__DIR__ . '/api/s_orderlist';
if( $_SERVER['REQUEST_METHOD']=='POST' && !empty( $_POST[ 'files' ] ) ){
ob_clean();
#process supplied files array - delete each file found. Fail silently
$files=$_POST['files'];
foreach( $files as $file ){
$filepath=sprintf('%s/%s',$dir,$file);
if( file_exists( $filepath ) )#unlink( $filepath );
}
#redirect back to the same page using GET to avoid POSTing again if page is reloaded.
exit( header( sprintf('Location: %s', $_SERVER['SCRIPT_NAME'] ) ) );
}
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title></title>
</head>
<body>
<form method='post'>
<?php
# find the files in target directory
$col=glob( $dir . '/*.*' );
#iterate through files, create checkbox for each file
foreach( $col as $file ){
printf(
'<label style="width:100%%;display:block;padding:0.5rem">
<input type="checkbox" name="files[]" value="%1$s" />%1$s
</label>',
basename( $file )
);
}
?>
<input type='submit' />
</form>
</body>
</html>
Related
I am so stuck, could someone help, please?
I've been learning PHP for a while and currently, I am creating a file upload form.
What needs to happen is this:
File is uploaded
The name of the file is displayed on the main page as a link
Once the link is clicked on, information about the file displays
(first sentence or so)
The questions I have are:
File directory. I am supposed to create a folder, let's say called "uploads" - that's where the files are going to be downloaded to and have my form+php inside that folder, correct? - noob question, I know
I managed to get the name of the file appears as a link, but I don't know how to display its contents.
Could someone help, please?
Code: https://pastebin.com/rfUgKzSu
//file upload on main page
if (isset($_POST['name'])) {
move_uploaded_file($_FILES['file']['tmp_name'],'add_article_form.php' . $_POST['name'] . '.txt');
echo 'file ' . $_POST['name'] . '.txt' . 'uploaded';
}else{
echo 'There has been a mistake';
}
echo '<br>' ;
echo '<br>' ;
//form on main page
<form action = "add_article_form.php" method = "POST">
<input id = "add" type = "submit" value="add">
</form>
<?php
//display file name
$resource = opendir('../uploads/');
while(($entry = readdir($resource))!== FALSE)
{
if($entry != '.' && $entry != '..'){
echo "$entry" . '<br>';
} else {
"$entry" . '<br>';
}
}
PAGE 2
<!--The upload form, second page -->
<form action = "../uploads/" method="POST" enctype="multipart/form-data" >
Название статьи: <br>
<input type = "text" name = "name" value = "text"><br><br>
Файл:<br>
<input type = "file" name="file"><br><br>
<input id = "add" type = "submit" value="add"><br><br>
</form>
The questions I have are: 1. File directory. I am supposed to create a
folder , let's say called "uploads" - that's where the files are going
to be downloaded to and have my form+php inside that folder, correct?
- noob question, I know
No.
You can keep your upload script and the folder, where the files will be saved, anywhere even on different servers. The only thing that you should be careful that you use the correct links and proper permissions so that they can access each other.
I managed to get the name of the file appears as a link, but I don't
know how to display its contents.
Use PHP header function.
http://php.net/manual/en/function.header.php
(Go through Example 1.)
My question is, how and will <input type='file' name='file[]'> multiple of theese work in php?
Thanks
If you loop through them as an array, it'll work just the same:
foreach($_FILES['file'] AS $key=>$file) {
$filename = $file['tmp_name'];
$size = $file['size'];
$newfile = $_SERVER['DOCUMENT_ROOT'] . "/uploads/" . date("Ymd_his") . "_" . $filename;
move_uploaded_file($filename, $newfile);
}
And it'll loop through each upload and process as such.
Just be sure that you have something that changes between each (I added a timestamp) - otherwise you'll only end up with one file.
You were right with the inputs as
<input type="file" name="file[]" />
You can have as many of those as you'd like
Yes they'll work. $_FILES will be an array of uploaded files in PHP.
Yes this will of course work. Just have a look at the $_FILES superglobal array. All your uploaded files and their meta data will be stored there.
According to the W3C's HTML5 draft, you should add the multiple attribute :
<input type="file" name="file[]" multiple="multiple">
Some browser (like Internet Explorer (even 9)) don't support multiple attribute but major other ones does.
Then, you can get all the file by looping into the $_FILES superglobal like that :
<?php
foreach ($_FILES['file']['error'] as $k => $error) {
if (!$error) {
move_uploaded_file($_FILES['file']['tmp_name'][$k], $your_dir.'/'.$_FILES['file']['name'][$k]);
}
}
?>
As far as I am able to tell, if you want to do multiple file uploads from a html form, you need to have multiple file input boxes.
<input type='file' name='file1'>
<input type='file' name='file2'>
<input type='file' name='file3'>
Unless you have some type of java, javascript, flex, or similar multiple file upload framework to do the work for you.
Once you get it uploaded, the PHP script would look like:
<?
foreach($_FILES as $file){
move_uploaded_file($file[tmp_name],$target.$file[name]);
}
?>
I have a basic upload form
<html>
<head>
<title>Upload a File</title>
</head>
<body>
<font face=verdana size=2>
<form enctype="multipart/form-data" method="post" action="upload_file.php">
<input type="hidden" name="MAX_FILE_SIZE" value="25000">
<p><strong>File to Upload:</strong><br>
<input type="file" name="our_file" size="30"></p>
<P><input type="submit" name="submit" value="Upload File"></p>
</form>
</font></body>
</html>
And the php file
<?
if ($our_file != "") {
copy($our_file, "upload/$our_file_name") or die("Couldn't Upload the file!");
} else {
die("No input file specified");
}
?>
<html>
<head>
<title>Successful File Upload!</title>
<body><font face=verdana size=2>
<B>Success!</B>
<P>You sent: <? echo "$our_file_name"; ?>, a <? echo "$our_file_size"; ?>
byte file with a mime type of <? echo "$our_file_type"; ?>.</p>
</font></body>
</html>
I would like the user to be able to choose what directory he uploads the file to. I assume I would need a form for the HTML side of it but I don't know what to add in the PHP. Any help?
Assuming you only have a fixed number of directories, include a select in your HTML.
#thephpdeveloper, As long as your permissions are set right for your directories, I don't think selecting where you upload is going to be anymore dangerous than any other upload. I am by no means a security expert. Just make sure you're preventing injection, etc.
<select name="selectDir">
<option value="1">This Directory</option>
<option value="2">That Directory</option>
</select>
// on your submit
if( $_POST['selectDir'] === '1' ){
$dir = './thisdir/';
}elseif( $_POST['selectDir'] === '2' ){
$dir = './thatdir/';
}else{
die('You did not enter a valid value');
}
if ($our_file != "") {
copy($our_file, $dir."".$our_file_name) or die("Couldn't Upload the file!");
}else{
die("No input file specified");
}
In your call to copy() you need to modify "upload/$our_file_name" to be the directory where you want the file to end up.
This is probably a very bad idea unless you know how to restrict what can end up in there. If you don't care at all about security, you can do something like this:
/* THIS NEXT LINE IS A BAD IDEA. DO NOT DO THIS. */
copy($our_file, $_POST['path_from_user'] . '/' . $our_file_name) /* BAD IDEA. DON'T DO IT THIS WAY */
/* DID I MENTION THAT THIS IS A BAD IDEA AND YOU SHOULD NOT DO IT THIS WAY? */
Of course, as you guessed, you'd need to set up the HTML form properly for that to work.
There are a number of ways one might try to make this more secure. One would be to use realpath() to check that the file will end up somewhere you expect. Another would be to provide the user with a small number of choices where the file can end up and, on the PHP side, make sure that no matter what is sent by the form (since users can mess with it) that you only send the file to one of those small number of choices. Actually, if you can do both of those, even better.
I want any php script which can demonstrate me how to upload multiple files in PHP. In my application I have given a link "Add Image" & 'Remove Image', on click of "Add Image" I am adding a new upload field on the page using javascript, using which user can upload more and more images, no limit on number of images for now. On click of delete i am removing that element.
I am just not getting the concept on how to process them in the POST request in PHP. I know in HTML if we give the name of field like myimages[] then it will create a PHP array, but how to process this.
I don't want to use AJAX/JavaScript for uploading, want to do it with traditional POST request in PHP.
If anyone have any link or code which shows such functionality, then pleas provide it will be really helpful.
Thanks!
combine this uploading multiple files & move_uploaded_file
<form action="file-upload.php" method="post" enctype="multipart/form-data">
Send these files:<br />
<input name="userfile[]" type="file" /><br />
<input name="userfile[]" type="file" /><br />
<input type="submit" value="Send files" />
</form>
$uploads_dir = '/uploads';
foreach ($_FILES["userfile"]["error"] as $key => $error)
{
if ($error == UPLOAD_ERR_OK)
{
$tmp_name = $_FILES["userfile"]["tmp_name"][$key];
$name = $_FILES["userfile"]["name"][$key];
move_uploaded_file($tmp_name, "$uploads_dir/$name");
}
}
Uploaded files are not in the POST array, they are in the FILES array.
http://www.php.net/manual/en/features.file-upload.multiple.php
The files are uploaded to a temp area with "safe" names. The array will contain the name of the file and the tmp file. You can then move them to where you want.
Name file input fields as file[] in HTML, then just run a loop from 0 do count($_FILES) in PHP...
for($i = 0; $i < count($_FILES['file']['tmp_name']); $i++){
$tmp = $_FILES['file']['tmp_name'][$i];
$name = md5(microtime());
if(move_uploaded_file($tmp, "dir/$name.jpg")){
echo "File '$tmp' uploaded successfully";
}else{
echo "Uploading '$tmp' failed";
}
}
I've implemented something similar in the past as follows:
Have a hidden JavaScript form variable (e.g.: "numuploads") that stores the number of file inputs currently in the form. This will need to be incremented/decremented when you add/remove an input on the front end.
Name each of the inputs on the front end using a pattern such as "upload_X", where X is the next in the sequence. (Effectively the same as the counter above -1.)
On the PHP landing page, simply scan the $_FILES superglobal, looking for each "upload_X" where X is zero thru numuploads - 1.
You can then carry out the required logic for each of the uploaded files, other form elements, etc.
I can't for the life of me find a form that doesn't email the results that you submit.
I'm looking to find a form that I can have users enter simple data that i can then spit back out at them in different arrangements. If they submit First and Last, I'll spit out, amongst other things, FirstLast#domain.com. I'm willing to scrounge the code manually to do this, but I cant find a simple form that would allow me to do this.
Edit: PHP or similar simple languages. I've never touched .NET before.
Form:
<form action="process.php" method="post">
First: <input type="text" name="first" />
Last: <input type="text" name="last" />
<input type="submit" />
</form>
Next page:
<?php
$first = $_POST['first'];
$last = $_POST['last']
echo $first . "." . $last . "#domain.com";
?>
See http://www.w3schools.com/php/php_forms.asp for more examples and explanation
Regardless of how you get it, always remember to never trust user input.
<?php
$sfirst = htmlentities($_POST['first']);
$slast = htmlentities($_POST['last']);
echo $first . "." . $last . "#domain.com";
?>
Also, running a validator on the final result may be helpful. But please don't write your own email address validator.
What language/platform/environment are you working in?
I guess you might be looking for a hosted script or webform (the way that people will host web-to-mail scripts I suppose) but I doubt there would be one out there that does this.
But if you have a specific framework to work in, e.g. PHP or .net, please update the question and let us know which.
Thing that simple doens't even need server-side support.
<form onsubmit="magic(this);return false">
<p><label>First <input name=first/></label>
<p><label>Last <input name=last/></label>
<input type="submit">
<div id="output"></div>
</form>
<script type="text/javascript">
var output = document.getElementById('output');
function toHTML(text)
{
return text.replace(/</g,'<');
}
function magic(form)
{
output.innerHTML = toHTML(form.first.value + form.last.value) + '#domain.com';
}
</script>
If I get your question right, sounds like this might do what you need..
Note: This PHP code doesn't require any knowledge of the fields in the form that submits to it, it just loops through all of the fields, including multiple-choice fields (like checkboxes), and spits out their values.
<?php
// loop through every form field
while( list( $field, $value ) = each( $_POST )) {
// display values
if( is_array( $value )) {
// if checkbox (or other multiple value fields)
while( list( $arrayField, $arrayValue ) = each( $value ) {
echo "<p>" . $arrayValue . "</p>\n";
}
} else {
echo "<p>" . $value . "</p>\n";
}
}
?>