File Upload

It should be mentioned first, that the http 1.1 protocol comprises the upload function. The web browsers support an upload up to the level, that you can simply add a form input element

<input name="soubor" type="file">

and it will be generated, including the "browse" button to select a file from your computer. The last thing you should to do in the form is to set the "enctype" parameter to set the method how the file will be sent.:

<form action="upload.php" method="post" enctype="multipart/form-data">

That is complete, now we can take over the file.

Using Google, I have found two examples - but for the original course, so both are in the Czech:

Jaromír Skřivan on the Interval server

Tomáš Vinduška on the programujeme.com

Comparing them, we can see, how different could be the solution in the php (different condition form - alternative syntax, generating everything in php, etc.).

Safety. There should be noticed, that if the file is not processed immediately or saved to the server (by our php script), it will be removed from the server after the php script will be processed.
File upload could be a safety risk, because a user can save a php file to your directory (and execute it). A possible solution is to check the extension, because on the most of the servers only files with the ".php" extension can be executed (the rest could only be read from the computer). If you use the "require" or the "include" function, check, if there is always the *.php extension used. The best solution is to insert the original file name into an SQL table and generate a new name for the file to be saved. If anybody will like to have the original file, you can send it back by e-mail, create temporary copy or better, save only zipped files. You cannot disable the file execution using the Apache ".htaccess", because the php files will be executed, even if only the reading will be permitted.
The best solution is in our second example - if we will save only jpeg pictures, we can call the resample function before saving the file.

The next text has been inspired from the example on the second link. On the both links there are used the same file for the upload form generating and for server upload itself. It is useful, if you like to send files one after another. This script should be includet into some html page (somewhere inside the body tag). Note, that on the begining of the file the "is_uploaded_file" function is called - for the first call, there are nothing to deal with, so the script will only generate the html form for the client side. Note, that the name of the php script should be "upload.php" (see the black bold text):

<?php  
if (is_uploaded_file($_FILES["soubor"]["tmp_name"])):
                 // ^if the data sent to server are a file
  $cesta="data/"; //directory for saved files  
  if (move_uploaded_file ($_FILES["soubor"]["tmp_name"],
                   $cesta.$_FILES["soubor"]["name"])):
    //move file to our directory, //announce that it is sucessfull
    echo "File ".$_FILES["soubor"]["name"];
    echo "with a size of ".$_FILES["soubor"]["size"];
    echo "bytes was sucessfully saved to server."; 
  else:  
    echo "Error saving file"; //error response  
  endif;  
else:
  echo "Error transphering file"; //another error response
endif;  
// generate the form for a new upload
?>
<form action="upload.php" method="post" enctype="multipart/form-data">
<input name="soubor" type="file">  
<br>  
<input name="Save" value="Save" type="submit"></form> 

Attention! Register globals!

In the red color is added using of associative (double-dimensional) array $_FILES - it should be used, if you cannot allow the "register global" parameter. If you like to delete it, then instead of $_FILES["soubor"]["name"] you should write $soubor_name (you need to include the underscore sign to denote the name, etc.).

This directive could be switched on, if you add section to your .htaccess file, but it is switched off on most servers now and is not supported in php in version later then 5.4.

php_flag register_globals on
Order allow,deny
Allow from all

The php preprocessor was originaly intended to translate small server side includes on the autors' (Rasmus Lerdorf ) personal home pages (from there this name). It was easy and simple to use. Now, the groups of -in real- professional programmers are trying to convert it to instrument for creating big portals and professional on-line webshops, even including object oriented programming. One of their modifications is to prohibit register globals at all. In this case, you need to use the $_FILES array. If you can use the register globals on, you can use scripts from the czech version of this page. They was fully tested. (the biggest differerence is, that the $soubor_name variable you can simply write to text string (using double quotation), but you cannot do this with text like $_FILES[soubor][name] ).

In the application of a photo archive there is another problem - there is a size limit for a file, often as low as 2 MB. Many pictures with a high resolution are bigger today.

Complete solution is in the next box (the name of the php script should be "upload1.php"):

<html>

 <head>
 <meta http-equiv="Content-Type"
 content="text/html; charset=windows-1250">
 <title>Odezva formuláře</title>

</head>

<body bgcolor="#FFFFFF">

<p><font size="4"><strong>File uploading</strong></font></p>

<?php  
if (is_uploaded_file($_FILES["soubor"]["tmp_name"])): //if the response contain a file
  $cesta="data/"; //our directory (where picture will be saved)  
    if (move_uploaded_file ($_FILES["soubor"]["tmp_name"], $cesta.$_FILES["soubor"]["name"])):
    //move file to our directory, //announce that it is sucessfull
     echo "File ".$_FILES["soubor"]["name"]." with the size of ";
     echo $_FILES["soubor"]["size"]." bytes has been temporary saved to server"; 

     $src = imagecreatefromjpeg($cesta.$_FILES["soubor"]["name"]);   //open new file in the directory
           //there we should check, if it could be opened as a picture - please, add...
     $dst = imagecreatetruecolor(640,480);               //required resolution
           //new image with our preffered size is cfreated
     imagecopyresampled($dst, $src, 0, 0, 0, 0, 640, 480, imagesx($src), imagesy($src));
           //parameters - see php.net/manual, imagesx/y are picture dimensions
     imagejpeg($dst, $cesta."1".$_FILES["soubor"]["name"],60);        //changing name by add the "1"
     imagedestroy($dst);           //destroying temporaly files
     imagedestroy($src);
     //the saved file should be removed from the directory as well (please, add the error report)
     @unlink($cesta.$_FILES["soubor"]["name"]);
  else:  
    echo "Error saving non-resampled file"; //Error message from the corresponding "if"
  endif; 
else:
  echo "Error transfering file"; //another error response
endif;  
//finally - generate form for sending another picture
//(in html, so end of php will follow:)
?>         

<hr>
<form action="upload1.php" method="post" enctype="multipart/form-data">
<input name="soubor" type="file">  
<br>  
<input value="Upload" type="submit"></form>  
<p>&nbsp;</p>
<sub>version from 25.3.2011</sub>
</body>
</html>

This script has been tested on the "webzdarma.cz" server, but has been modified for use on this page, so there could be errors.

Note: From w3schools:

By using the global PHP $_FILES array you can upload files from a client computer to the remote server.

The first parameter is the form's input name and the second index can be either "name", "type", "size", "tmp_name" or "error". Like this:

  • $_FILES["file"]["name"] - the name of the uploaded file
  • $_FILES["file"]["type"] - the type of the uploaded file
  • $_FILES["file"]["size"] - the size in bytes of the uploaded file
  • $_FILES["file"]["tmp_name"] - the name of the temporary copy of the file stored on the server
  • $_FILES["file"]["error"] - the error code resulting from the file upload

This is a very simple way of uploading files. For security reasons, you should add restrictions on what the user is allowed to upload.