LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-06-2011, 06:58 PM   #1
Xeratul
Senior Member
 
Registered: Jun 2006
Location: UNIX
Distribution: FreeBSD
Posts: 2,657

Rep: Reputation: 255Reputation: 255Reputation: 255
A very simple PHP file uploader


Hello,

Coding coding... for coding fans. Another PHP effort for uploading files. Would you know why it does not save anything? Thank you in advance

Code:
<?php
if ($_POST[bsubmit]=="Save")
{
if ($_FILES["file"]["error"] > 0)
  {
  echo "Error: " . $_FILES["file"]["error"] . "<br />";
  }
else
  {
  echo "Upload: " . $_FILES["file"]["name"] . "<br />";
  echo "Type: " . $_FILES["file"]["type"] . "<br />";
  echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb<br />";
  echo "Stored in: " . $_FILES["file"]["tmp_name"];
  }

}

?> 

<html>
<body>

<form action="fileuploader.php" method="post"
enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
<br />
<input type="submit" name="submit" value="Save" />
</form>

</body>
</html>

An alternative would be, but also not working:

Code:
<?php

$ufile = $_GET[ufile];


if ($_POST[bsubmit]=="Save")
{

$path= "upload/".$HTTP_POST_FILES['ufile']['name'];
if($ufile !=none)
{
if(copy($HTTP_POST_FILES['ufile']['tmp_name'], $path))
{
echo "Successful<BR/>";

//$HTTP_POST_FILES['ufile']['name'] = file name
//$HTTP_POST_FILES['ufile']['size'] = file size
//$HTTP_POST_FILES['ufile']['type'] = type of file
echo "File Name :".$HTTP_POST_FILES['ufile']['name']."<BR/>";
echo "File Size :".$HTTP_POST_FILES['ufile']['size']."<BR/>";
echo "File Type :".$HTTP_POST_FILES['ufile']['type']."<BR/>";
echo "<img src=\"$path\" width=\"150\" height=\"150\">";
}
else
{
echo "Error";
}
}

}

?>



<html>
<body>

<form action='<?=$PHP_SELF?>?ufile=<?=$ufile?>' method='post' enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="ufile" id="ufile" />
<br />
<INPUT type="submit" name="bsubmit" value="Save">
</form>

</td></tr></table></center>
</body>
</html>


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.

Last edited by Xeratul; 07-06-2011 at 07:29 PM.
 
Old 07-06-2011, 09:16 PM   #2
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Compare your code to the examples and documentation at www.php.net.

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_max_filesize
    The maximum size (in bytes) for an uploaded file.
  • 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:
Code:
exec /usr/bin/env -i \
        LANG=C \
        PATH=/usr/bin:/bin \
        PHP_CONFIG_FILE_PATH=path-to-specific-php.ini-file \
        PHP_CONFIG_FILE_SCAN_DIR=path-to-php.ini-snippets-dir \
        PHP_INI_SCAN_DIR=path-to-php.ini-snippets-dir \
        PHPRC=path-to-directory-containing-php.ini \
        /usr/bin/php5-cgi
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.
 
Old 07-07-2011, 01:38 PM   #3
Xeratul
Senior Member
 
Registered: Jun 2006
Location: UNIX
Distribution: FreeBSD
Posts: 2,657

Original Poster
Rep: Reputation: 255Reputation: 255Reputation: 255
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?

Last edited by Xeratul; 07-07-2011 at 01:43 PM.
 
Old 07-07-2011, 08:40 PM   #4
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
Quote:
Originally Posted by Xeratul View Post
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
Code:
 <form action="URL-to-upload-PHP" method="post" enctype="multipart/form-data" accept-encoding="utf-8">
  <input type="hidden" name="MAX_FILE_SIZE" value="max-size-in-bytes-per-file">
  <input type="file" name="name" multiple="*/*">
  <input type="submit" value="Upload">
 </form>
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.

Hope you find this useful.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: A Simple New Facebook Photo Uploader for Ubuntu LXer Syndicated Linux News 0 01-15-2011 06:40 PM
LXer: Nautilus Flickr Uploader - Incredibly Useful and Simple Nautilus Extension LXer Syndicated Linux News 0 11-09-2010 08:30 AM
Paranormal Phenomena with PHP and uploader script vargadanis Programming 3 10-10-2007 07:32 AM
php uploader script probleme hua Programming 6 02-01-2007 11:00 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:38 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration