ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Note:
These few lines of code we have given you will allow anyone to upload data to your server. Because of this, we recommend that you do not have such a simple file uploader available to the general public. Otherwise, you might find that your server is filled with junk or that your server's security has been compromised.
In the submission form, you should have a MAX_FILE_SIZE hidden input field, specifying the maximum uploaded file size. (It is for user's benefit only. You still need to check the actual file sizes on the server.)
In the upload script, the uploaded files are saved in a temporary directory (more about that below), and unless you move them elsewhere using move_uploaded_file(), they will be deleted when the PHP script finishes. The copy() in your latter script is useless for this. You do need to use move_uploaded_file() for this. (They might be unlinked files, at least in theory, so normal copy() would not even see them even if you specified explicitly the correct upload directory.)
Finally, your PHP configuration must allow file uploads. There are three variants of the PHP interpreter -- mod_php, cgi, and cli -- and each default to a different php.ini; make sure you modify the correct one. For mod_php, you can set PHPRC environment variable in Apache config to set the configuration file directory, and set individual configuration items in the Apache config itself. cgi and cli versions should have their own subdirectories in /etc/php/ or /etc/php5/. If you do a simple <?PHP phpinfo(); ?> page, you can see which php.ini file(s) that interpreter used.
There are five important configuration settings in the PHP configuration:
file_uploads
This has to be set either true, or better, to the maximum number of bytes uploaded per POST.
upload_tmp_dir
This is the directory where the PHP interpreter saves the uploaded files temporarily. It should be outside your web tree, but on the same filesystem/mount, for security (not published by the web server) and efficiency (moving is simply a hardlink operation, and does not involve copying the file contents).
The user your PHP interpreter runs as must have write access to this directory (to create new files).
post_max_size
The maximum size (in bytes) of POST data payload. (Very close to file_uploads, but affects all POST requests, not only file upload POST requests.)
I recommend setting this too, so your PHP does not try to process oversized POST requests at all.
max_input_time
This is the number of seconds the data transfer from the client browser to the server can take. Note that the data transfer happens before your script starts executing. The proper setting depends on your maximum allowed POST size, and the average/minimum upload transfer rate you expect from your clients.
To avoid security problems and reduce the impact of possible denial-of-service attacks via PHP POST requests, I recommend only allowing file uploads and larger POST requests for specific scripts.
If you use mod_php, you can use a Directory and Files directives to limit the scope, then use php_value to set the php.ini settings in the Apache config.
If you use CGI, SUEXEC CGI, FastCGI, or SUEXEC FastCGI, use a small dash wrapper script for upload scripts, to change the php.ini to a special one that allows larger POSTs and file uploads:
I recommend the use of dash for this, because it is a small, lightweight shell, and will incur smaller PHP interpreter load latencies than using any other shell. (Using a statically compiled C program that does the same is even faster, but usually not worth the effort.)
If you have your own server or virtual server, and are not using a web hosting service, I also recommend using a dedicated user account (thus, SUEXEC + CGI + PHP, or SUEXEC + FastCGI + PHP), so that it is not possible for the upload script to overwrite any script, or write to anywhere in the web tree, unless expressly allowed to (by directory access mode bits). Web hosting services only provide one user account per hosted service, so you cannot do that there.
thank you for your help. It was very helpful. this works
Code:
<?php // RAY_temp_upload_example.php
error_reporting(E_ALL);
echo "<pre>" . PHP_EOL;
// IF A FILE HAS BEEN UPLOADED
if (!empty($_FILES))
{
// SHOW THE UPLOADED FILES
print_r($_FILES);
// TRY TO MOVE THE FILE TWICE - SECOND MOVE RETURNS FALSE
if (!move_uploaded_file($_FILES["userfile"]["tmp_name"], $_FILES["userfile"]["name"])) echo "CANNOT MOVE {$_FILES["userfile"]["name"]}" . PHP_EOL;
if (!move_uploaded_file($_FILES["userfile"]["tmp_name"], $_FILES["userfile"]["name"])) echo "CANNOT MOVE {$_FILES["userfile"]["name"]}" . PHP_EOL;
// SHOW THE UPLOADED FILES AFTER THE MOVE - NO VISIBLE CHANGE
print_r($_FILES);
}
// END OF PHP, PUT UP THE HTML FORM TO GET THE FILE
?>
<!-- The data encoding type, enctype, MUST be specified as below -->
<form enctype="multipart/form-data" method="POST">
<!-- MAX_FILE_SIZE must precede the file input field -->
<input type="hidden" name="MAX_FILE_SIZE" value="300000" />
<!-- Name of input element determines name in $_FILES array -->
Send this file: <input name="userfile" type="file" />
<input type="submit" value="Send File" />
</form>
Now next step, how to upload several files at one, with multi selection using CTRL key?
Now next step, how to upload several files at one, with multi selection using CTRL key?
Use HTML5 (and optionally File API if you need to enhance the functionality with Javascript); it is the only thing that works in multiple browsers AFAIK. So, for PHP, use
You can try limiting the possible file types by specifying one or more MIME types (comma-separated) to the multiple attribute, but in my experience, it doesn't really work; and may sometimes annoy the user (if the OS misdetects the MIME type of the file to be uploaded). So, I think it's best to use */* anyway.
In PHP, $_FILES['name']['name'], $_FILES['name']['type'], $_FILES['name']['size'], $_FILES['name']['tmp_name'], and $_FILES['name']['error'], can be either just strings or numbers (if client does not support multiple file upload, or only one file was uploaded), or arrays. If they're arrays, they all have the same number of elements, which is of course the number of files selected for that control.
So be careful, and test your code with different inputs (and both single and multiple file uploads), preferably with multiple browsers.
I tested the above with PHP-5.3.3 (via SUEXEC FastCGI and Apache 2.2.16) and Firefox 3.6.18. I didn't bother testing other browsers, but I do believe recent browsers should all work.
If you use HTML5 and Javascript, you can extend the HTML to a drag and drop file upload field. On the server side, the POST response should be identical; it's just a better user interface for the fields in the browser.
For older browsers, I recommend creating a fallback: multiple file upload fields, all but the first initially hidden (style="display: none;"). Each input then has an onselect/onclick/foobar Javascript event handler (I cannot remember which works best on most browsers, you need to check), which unhides the next input control. That way users with stale browsers will still be able to upload multiple files, even if they need to select them one by one.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.