Download, process, store and deliver user-submitted files and images

Later or earlier in the life of web developers, you will have to deal with files and images uploaded by users.

General issues:

How to download?

modern web browsers and methods allow several ways to upload files provided by the user to my server. What are the best practices and what should I consider?

How do i handle it?

Once the download is finished, what I need to know about security and further file processing

How to save and deliver?

Are there any recommendations for storing downloaded files?

Disclaimer: I put almost 30 minutes to the next answer, the original question was deleted, so I decided to ask general questions that the user may encounter when working with files provided by the user. See My answer, you can contribute and add your ideas and experience.

+4
source share
1 answer

There is no β€œbest” way for each of these steps, but there are a whole bunch of installed methods and best practices among the many methods and libraries that can help you achieve user-friendly downloads, security, and speed.

For another question, which unfortunately was deleted, I wrote this little guide.

A custom file or image goes through several stages of its life:

  • load yourself
  • validaton
  • processing for storage (e.g. type conversion, resizing, thumbnail creation, ...)
  • storage
  • entry side delivery

In this case, all steps will be indicated and, if possible, examples are given.

1. Download

Modern web browsers offer several ways to download a file.

The easiest way is to create a form with a simple <input type="file" name="userFile" /> . After submitting the form, the file will be sent using POST, and it can be accessed using $ _ FILES superglobal in PHP

1.1. Simple HTML form

 <form action="upload.php" method="post" enctype="multipart/form-data"> <input type="file" name="userFile1" /> <input type="file" name="userFile2" /> <input type="submit" value="upload files" /> </form> 

When the form is submitted, the POST request is sent to upload.php. Such a download is not very convenient for the user. Your user will not see any progress in downloading, and downloading multiple files will be a pain.

1.2. Download javascript ajax

In this solution, POST runs asynchronously with javascript

http://www.saaraan.com/2012/05/ajax-image-upload-with-progressbar-with-jquery-and-php

1.3. HTML 5 loading

modern browsers support HTML5, which allows you to load masks with a progress bar and preview very nicely and conveniently - the border is your own creativity

For example, I really like this demo: http://html5demos.com/dnd-upload

Server side

No matter which of these download technologies you decide to use, the download will be completed in the HTTP POST sent to your script. All further processing will be performed on the server.

PHP copies the file to a temporary path ( upload_tmp_dir )

There are several other download related settings that you can configure in your php.ini or on the fly with ini_set : http://php.net/manual/en/ini.core.php#ini.sect.file-uploads

upload.php

 <pre> <?php print_r( $_FILES ); 

This is what $_FILES looks like after a successful download.

  • name: original name
  • type: browser supported mime type
  • size: size in bytes
  • tmp_name: temporary file name on your server
  • error: error codes as described here , 0 when everything went through the file

Each file has its own index.

 Array ( [userFile1] => Array ( [name] => i_love_ponies.png [type] => image/png [size] => 42233 [tmp_name] => /tmp/_x123tfsdayx134 [error] => 0 ) [userFile2] => Array ( [name] => ponies_run_my_server.png [type] => image/png [size] => 12325 [tmp_name] => /tmp/_x3123asdad3ssy [error] => 0 ) ) 

Some more tips

If you expect large files, consider web server and php execution timeouts. If the download takes 10 minutes, you do not want your users to be in error.

In PHP you can increase max_execution_time

2. Verification

Questions you can ask

I want to allow only certain files - which file do I get?

the type found in the $_FILES array is set by the browser. If you want to be sure which type has been loaded, you can use the fileinfo extension in PHP.

In this example, the success of the download itself will be checked and the files of allowed types will be written to a new array for further processing

 $allowedTypes = array( 'image/png' 'image/gif' 'image/jpeg' ); $useFiles = array(); $finfo = new finfo(FILEINFO_MIME_TYPE); foreach ( $_FILES as $index => $file ) { if ( $file['error'] === UPLOAD_ERR_OK ) { $type = $finfo->file( $file['tmp_name'] ); if ( in_array( $type, $allowedTypes ) ) { $useFiles[$index] = $file; } } } 

I want to set the maximum file size - what size?

In this case, you can safely rely on the value of $_FILES['key']['size'] , whose size is equal to bytes. You should not just rely on client-side file size limits

if we talk about images, do I want to scale or create thumbnails - what are the sizes of the image?

See getimagesize to determine image sizes.

3. Processing

Before you save the file to the final location, you may need to process it. This is the time when you can

Common libraries used for image processing are gd lib and imagick . I personally prefer gd lib. This is a little more manual work, but it is faster and comes with most default settings or is easy to install additionally. Imagemagick initially has a very large pool of image processing functions

4. Storage of your data

Now it's time to talk about storage. First save the way to copy the temporary file to a temporary or final location.

You must use move_uploaded_file

 move_uploaded_file( $useFiles['tmp_name'], $destination ); 

Again, there is no β€œbest way” to store, it depends on your environment, files and usage. I will talk about a few

4.1. server file system

This is probably the most used and easiest way to store your files. You can simply put files statically with an already running web server. This is usually the location at the root of your document.

To make your life easier, you can save the file name to a database - it is preferable to link to or link to related data, such as a user or location.

You do not have to save all files in one folder for various reasons.

You need to create a unique name for each file, otherwise you will replace the existing file with a new one. Also, conventional file systems become slower to search with an increase in the number of files in a node. This will result in slow response times when a file is requested for delivery.

You can save it to a folder for each user.

 /uploaded/user-id/file.jpg 

If you expect a large number of files per user, you can split the checksum of the file name to get a deeper folder structure.

eg.

 $path = $_SERVER['DOCUMENT_ROOT'] . '/uploaded/' . $userId . '/' . chunk_split( md5( $useFiles['index']['name'] ), 12, '/' ); 

will result in

 /var/www/htdocs/uploaded/1/97e262286853/d52aa8c58eb7/f0431f03/ 

4.2. Database

You can store your files in a MySQL database using the blob type. I do not recommend it at all

4.3. Content Delivery Network

If you expect a lot of traffic around the world, you might want to save your files on a CDN, like Amazon S3 with CloudFront.

S3 is a cheap reliable storage for files up to 5 TB in size (as far as I know)

http://www.9lessons.info/2012/08/upload-files-to-amazon-s3-php.html

You do not have to worry about file backups, available hard disk size, delivery speed, etc. etc. Cloudfront adds CDN layer on top of S3 with edges around the world

+21
source

All Articles