Jump to content

What's the best practice for storing pictures?


Recommended Posts

Hello. I'm working on a website with an editor that allows image uploading. Ideally I want to be able to develop a framework for this and use it in later projects. What I have in mind is this:

  • Database has an images table
  • Entries contain these fields: id, filename, and a short description
  • Images are referred to by their ids in other parts of the application.

That part seems simple to me, but now there are two details I need to determine: the file name, and storing the images.
Big sites like Facebook - as far as I know - parse uploads and store them all in the same format. I can see the huge security benefit there. What are the best ways of doing that? As for the file name, I know PHP has a function to generate a file with a unique name. Is there any benefit to doing that over using the id? (i.e. 1.jpg, 2.png, 3.jpg, etc)

Link to post
Share on other sites

Numbering the images is only acceptable if all images are public. Otherwise, the ID sequence leaks private information about which picture has been uploaded when (and potentially by whom).


So if the images belong to particular accounts and not the general public, you need randomized filenames. However, it's not recommended to use the built-in PHP functions like mt_rand() or uniqid(). Those produce very poor results derived from trivial input like the server time and the process ID. For proper random numbers, you need to use the generator of your operator system. There are several interfaces for this:

Link to post
Share on other sites
  • 1 month later...

Store images in the file system and store the directory in the database,


or create a directory in your file system for each user (which is what i would do)







If your looking after protecting the images, get the binary data from the image then store it in the database as a BLOB.



I've been programming websites for a long time now and these are the 2 main options.

Link to post
Share on other sites





Storing an upload with the user-provided filename in some personal directory is the worst possible option:

  • You need to be very, very careful that you don't end up with people uploading malicious scripts. If they can freely choose the filename, nothing prevents them from using a “.php” or “.html” extension.
  • You have to go through complicated uniqueness checks, or you may uncontrolledly overwrite existing files.
  • You force the user to give the files unique names, which is completely unnecessary. 

Storing the images in BLOBs means that you massively bloat the database and keep it busy with swapping image data back and forth.


So as much as I appreciate alternative solutions, I fear those are not good. 

Link to post
Share on other sites

I am using something like this for storing files

  preg_match('/\.([a-zA-Z]+?)$/', $_FILES['userfile']['name'], $matches);
  if(in_array(strtolower($matches[1]), $accepted)) {
    $newname = md5_file($_FILES['userfile']['tmp_name']).'.'.$matches[1];
    move_uploaded_file($_FILES['userfile']['tmp_name'], $filedir.'/'.$newname);

Where '$accepted' is array of allowed file extensions and '$filedir' is subdirectory to store images. I am using 'md5_file' for unique names for images. Then you can simply pass '$newname' to database what is containing other data such as uploader and description like you stated in OP.

Link to post
Share on other sites

Using md5_file() as the filename means that the user cannot have two files with the same content. What's the point if that? There are no such restriction in a “real” filesystem. If you want to prevent accidental duplicates, there are much smarter solutions.


Also, what happens if the user does upload the same content with a different name? Do you just overwrite the file and change the name? Does the script crash? Do you ask for permission?


Last but not least, use pathinfo() to get the extension. No need for any regex magic.

Link to post
Share on other sites


This topic is now archived and is closed to further replies.

  • Create New...

Important Information
