PHP file Upload Source: http://www.360weboy.com/php/upload.html? As a special form data, php generates a $ _ FILES global array when the file is submitted to the server through the httppost request, the related file information will be stored in a simple example of file upload in PHP.
Source: http://www.360weboy.com/php/upload.html
?
As a special form data, php generates a $ _ FILES global array when the file is submitted to the server through an http post request, the related file information is stored in this global array. In this article, I will use some sample code to describe the file upload in php, and take a deeper look at the internal implementation mechanism of file upload, finally, let's briefly explain how to enhance security in this aspect!
File Upload
To allow client users to upload files, we must provide a form on the user interface to submit the file upload request. Because the uploaded file is a special type of data, unlike other post data, we must set a special encoding for the form:
?
You may not be familiar with the above enctype attribute, because it is often ignored. However, if the http post request contains both regular data and file-type data, this attribute should be displayed and added to improve compatibility with various browsers.
Next, we need to add a field to the form for uploading files:
The preceding file fields may vary in different browsers. For most browsers, the above fields are rendered into a text box and added with a browser button. In this way, you can enter the path of the file to the text box, or select the file to be uploaded from the local hard disk by clicking the Browse button. However, in Apple's Safari, it seems that you can only browse this method. Of course, you can also customize the style of the upload box to make it look more elegant than the default style.
Next, we will give a complete example to better illustrate how to process file uploads. For example, you can use the following form to allow users to upload attachments to my local server:
1 2 3 4 5 |
Upload your attachment:
|
Tip: you can use upload_max_filesize in php. ini to set the maximum value allowed to upload files. In addition, there is also a post_max_size parameter that can be used to set the maximum form data that can be uploaded, specifically the sum of various data in the form, therefore, you can set this field to control the maximum value of the uploaded file. However, note that the value of the latter must be greater than that of the former, because the former is part of the form data of the latter.
. Upload form displayed in firefox
When this form is submitted, the http request is sent to upload. php. To show which information can be used in upload. php, I printed it in upload. php:
1 2 3 4 5 6 |
Header ('content-Type: text/plain '); Print_r ($ _ FILES );
?> |
Let's do a test. if I upload a blog logo to my local server www.360weboy. me/upload. php through the above form, let's see what information will be output in upload. php:
1 2 3 4 5 6 7 8 9 10 11 12 |
Array ( ? ? [Attachment] => Array ? ? ? ? ( ? ? ? ? ? ? [Name] => boy.jpg ? ? ? ? ? ? [Type] => image/jpeg ? ? ? ? ? ? [Tmp_name] => D: \ xampp \ tmp \ php1168.tmp ? ? ? ? ? ? [Error] => 0 ? ? ? ? ? ? [Size] = & gt; 11490 ? ? ? ? )
) |
The above is all information about the currently uploaded file in the global array after the file is uploaded. However, can we ensure that the information is secure? if the name or other information has been tampered? We always need to be cautious with the information from the client!
Specific http request parts
To better understand file upload, we must check the specific information contained in the http request sent by the client. The Attachment I uploaded previously is the logo of this blog. because it is an image, it is not suitable for us to do the above experiments. Therefore, I re-upload a text file test. text, which contains the following content:
1 2 3 4 5 |
360 weboy
360 days
Life Of A Web Boy |
Okay. Now I upload this text file, which will be output in upload. php:
1 2 3 4 5 6 7 8 9 10 11 12 |
Array ( ? ? [Attachment] => Array ? ? ? ? ( ? ? ? ? ? ? [Name] => test.txt ? ? ? ? ? ? [Type] => text/plain ? ? ? ? ? ? [Tmp_name] => D: \ xampp \ tmp \ php51C0. tmp ? ? ? ? ? ? [Error] => 0 ? ? ? ? ? ? [Size] => 40 ? ? ? ? )
) |
Let's take a look at the http post request sent by the relevant browser (I omitted some optional headers ):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
POST/upload. php HTTP/1.1 Host: www.360weboy. me Referer: http://www.360weboy.me/ Multipart/form-data; boundary = --------------------------- 24464570528145 Content-Length: 234 ? ----------------------------- 24464570528145 Content-Disposition: form-data; name = "attachment"; filename = "test.txt" Content-Type: text/plain
360 weboy
360 days
Life Of A Web Boy --------------------------- 24464570528145 -- |
In the preceding request format, we need to pay attention to the following fields: name, filename, and Content-Type. they indicate the field name-attachment in the form of the Upload file box, the file name-test.txt uploaded from the local hard disk, and the uploaded file format-text/plain (representing the text file ). Then, we can see the specific content of the uploaded file under a blank line.
Enhanced security
To enhance the security of file uploads, we need to check the tmp_name and size in the global array of $ _ FILES. To ensure that the object pointed to by tmp_name is indeed a file just uploaded by the user on the client, rather than a file similar to/etc/passwd, you can use the is_uploaded_file () function in php to perform the following judgment:
1 2 3 4 5 6 7 8 9 |
? $ Filename = $ _ FILES ['attachment'] ['tmp _ name']; ? If (is_uploaded_file ($ filename )){ ? ? /* Is an uploaded file .*/ } ? ?> |
In some cases, after a user uploads a file, the content of the uploaded file may be displayed to the user. Therefore, the above code check is particularly important.
Another thing to check is the mime-type of the uploaded file, that is, the type field of the output array in upload. php. In the first example, I uploaded an image, so the value of $ _ FILES ['attachment '] ['type'] is 'image/jpeg '. If you want to accept only image/png, image/jpeg, image/gif, image/x-png, and image/p-jpeg mime-type images on the server side, the following code can be used for check (for example, the specific code, such as error reporting, should follow the system in your system ):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ Allow_mimes = array ( ? ? 'Image/png ', ? ? 'Image/x-png ', ? ? 'Image/GIF ', ? ? 'Image/jpeg ', ? ? 'Image/pjpeg' );
$ Image = $ _ FILES ['attachment'];
If (! In_array ($ image ['type'], $ allow_mimes )){ ? ? Die ('sorry, the format of the file you uploaded is not accurate; we only accept image files .'); }
// Continue processing uploaded image files |
As you can see, we have ensured that the mime-type of the file meets the server requirements. However, it is not enough to prevent malicious users from uploading other harmful files, because the mime-type malicious users can disguise it. For example, you have made a jpg image, written Malicious php code in the metadata of the image, and saved the file with the suffix php. When this malicious file is uploaded, it will pass the server's mime-type check and is considered as an image, and the dangerous php code in it will be executed. The metadata of a specific image is similar to the following:
1 2 3 4 5 |
File name? ? : Image.jpg File size? ? : 182007 bytes File date? ? : 7:45:10 Resolution? : 1197x478 Comment? ? ? : |
We can see that php code is added to the Comment field of the image metadata. Therefore, it is clear that a necessary check must be performed on the file extension to prevent similar dangerous situations. The following code enhances the Mime-type check code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$ Allow_mimes = array ( ? ? 'Image/png '=> '.png ', ? ? 'Image/x-png '=> '.png ', ? ? 'Image/GIF' => '.gif ', ? ? 'Image/jpeg '=> '.jpg ', ? ? 'Image/pjpeg '=> '.jpg' );
$ Image = $ _ FILES ['attachment'];
If (! Array_key_exists ($ image ['type'], $ allow_mimes )){ ? ? Die ('sorry, the format of the file you uploaded is not accurate; we only accept image files .'); }
// Get the name of the file with the suffix omitted: $ Filename = substr ($ image ['name'], 0, strrpos ($ image ['name'], '.');
// Add a suffix $ Filename. = $ allow_mimes [$ image ['type'];
// Continue processing uploaded files |
Through the above code, we ensure that even if the uploaded image meta file contains php code, the image file will be renamed with a suffix named image format, so the php code will not be executed. The above code does not have any negative impact on normal uploaded images.
After performing the preceding steps to improve security, if you only want to save the uploaded file to a specified directory, you can use the default function move_uploaded_file of php to implement it:
1 2 3 4 5 6 7 8 9 10 |
? $ Tmp_filename = $ _ FILES ['attachment'] ['tmp _ name']; $ Filename = '/path/to/attachment.txt '; ? If (move_uploaded_file (tmp_filename, $ filename )){ ? ? /* $ Temp_filename: Save the file to the temporary directory and save it to the attachment.txt file in the corresponding directory .*/ } ? ?> |
You may also need to limit the size of the uploaded file, so you can use the filesize function to obtain the size of the uploaded file, determine the size, and perform further processing. this is not the case here, let's do it on your own.
?