views:

199

answers:

6

This is what i want to do............

I am going to let each user upload multiple images into a folder called "pics". If the user upload say "MyImage.jpg" i will rename it "MyImage_UserID.jpg". Where UserID will be the User's unique ID of course. This way when i look for all the images of a user i will just look for the image name that ends with the UserID.

Is this wrong, or is there another way of doing this?

I am thinking about placing ALL the images from all the users in 1 folder.

It will be stupid to create a folder for each User dont you think?

Also, how save will that folder "pics" be? Like i dont want hackers to add or delete pictures out of that folder.

Any input?

+3  A: 

Provided there will be some significant number of users with significant amount of images per user, your File System will start to suffocate (provided it won't crash being unable to handle large number of files).

What I recommend is to create a folder for each user. And no, this is not stupid.

Anton Gogolev
Sjoe, i could create more than 1000 folders though. At the moment i have 230 Users and it should grow and grow.
Etienne
Better 1000 folders than 1000 * multiple images in one folder
ChrisF
+1  A: 

To help with security set permissions on the web site to prevent listing any directories. Thus even if someone manages to correctly guess the name of a folder they won't be able to see the contents.

There are other things you can do - do some research on site security.

I agree with Anton, a directory per user is a good idea. Then you don't even have to rename the image.

ChrisF
A: 

simply have 1 single folder where you upload all pics, and have a seperate table which logs the userid and the imagefilename

the only thing u need to check when uploading images is whether the same image file name exist, if yes rename it and save it accordingly

this is if you choose to save pics on the file system


however note that databases are really good with all this these days. so even if you save your image directly inside sql server scalability should not be a problem at all. this way you completely secure your images, no need for renaming images, managing filesystem, etc etc

a lot of guys here would argue on this. however please note sharepoint 2007 uses sql server to save documents, images, etc etc. also if ever you end up having a lot of users, and u need load balancing and fallback, then its very very difficult to achieve on a file system (you will have to rely on a network share and replicate your network share for fall back)

but the same task to achieve with sql server would be a breeze

Raj
Thanks, at the moment my images are saved in the DB, but most people say i must place them in folders. Another reason why i want to do this: By the articles that i have i can do so much more with images that are saved in a folder compare to DB.
Etienne
If your images are < 2MB you will be fine for quite some time. But storing images in the DB will eventually create problems. First the DB becomes hard to manage and backup, then performance starts to drop as caching becomes less and less successful.
Jacco
+2  A: 

It is not a good option to store all images in one directory. The file system will choke if there are to many nodes in it.

First option is to give each user it's own directory. But if you expect many users, the same problem will eventually arise.

The thing people usually come up with is: split the userId:

+ 1
|- 11
|- 12
|- 1490
+ 2
|- 23
|- 240
...

But then the data is not distributed evenly trough the directory structure, leading to other problems.

The simplest working solution is to split the userId from behind:

+ 1
|- 231
|- 91
|- 1
+ 2
|- 6322
|- 342
...

But there are better solutions out there.
See also: How to store images in your filesystem for a more complex solution

The next thing to worry about is: how do I keep the database and my file-system synchornised

  1. create DB record, marked as 'not-synchronized'
  2. fetch id of newly inserted record
  3. store data in the file-system, tied to the newly inserted recordId
  4. mark record as 'synchronized'

Deleting stuff goes the otherway around.

Jacco
+3  A: 

storing too many files in a single directory can lead to problems. not only performance will suffer at a certain point, but a friend (with way more experience than me) told me that some backup programs have problems with this.

so when i had to store thousands of images i always created 256 subdirectories, and stored the files in the directory files/{id mod 256}/{myfile_id}.jpg

to protect yourself against hackers there are a lot of things to do, and nothing will be safe (because hackers will most likely try to get root access and then your data isn't safe anyway).

1) so ... regular backups. period.
2) audit log files (who what when). that's not security per se, but may help you in discovering security holes and fix bugs
3) set the file permissions accordingly (important on shared servers without chroot-ing)
4) double-check if an action really is done by the right user. it must be impossible to do harm by guessing the url.

there's more if you want to make the filenames and -paths secret. e.g. it's possible to not directly link to the image, but to a script that serves that image. in this case you're able to store the files outside the webroot (additionally, your more independent of filenames) (see code at the end).

one more step would be to avoid auto_increment id values to identify images. better use an unique hash (md5(mt_rand());) without a correlation to the id and store that in the database (afaik youtube and flickr do that).

ugly php-pseudocode for passing through would be something like:

<?php
  if (isset($_REQUEST['img'])) {
    $hash = $_REQUEST['img']);
    if (($res = getImageByHash($hash)) !== false) {
      list($id, $name, $mimetype) = $res;
      $path = '../images/' . ($id % 256) . '/' . $name;

      if (file_exists($path)) {
        header('Content-type: ' . $mimetype); // e.g. image/png
        readfile($path);
     exit();
      }
    }
  }

  // if any error happened, then 404 - it's dirty
  header("HTTP/1.0 404 Not Found");
  echo 'sorry, we couldn\'t find this image';
?>

getImageByHash() would query the db. this solution is slower, because the webserver can't serve images directly anymore.

and: i'd rather not store the images in the database. exports would get huge, backups a pain.

Schnalle
A: 

If you are not sure about security, its better to keep images right in database. One thing you need to be sure is that pictures wount take too muc space there. You need to:

1 ) Store em as JPEGs, and convent other image types to JPEG

2 ) Resample down pictures that are bigger pixel-size then you actually need.

There is special component AccessImagine, that can watch this things automatically + give users freedom of image submitting methods. You can download it here - http://access.bukrek.net