1

I'm creating a survey in which users can upload about 6 pictures. What would be the best way for me to store these in the file system? Users can do multiple surveys (thus tracking their improvement over time)...so that means I can't just name them sequentially...

This is a CI/PHP app. :)

Or for knowledge's sake, how would you do it?

Kevin Brown
  • 12,602
  • 34
  • 95
  • 155
  • 2
    Why not sequentially? `survey1_image6.jpg`? – Pekka Jan 14 '11 at 19:50
  • So you need to track, user, survey and image(s)? – Phill Pafford Jan 14 '11 at 19:52
  • @Phill, I just need a simple way to track images and users, but I can't just name them something like `user12_image3`... – Kevin Brown Jan 14 '11 at 19:56
  • @Pekka, I'd give you the green check if you answered. Your answer is the simplest for my purposes... – Kevin Brown Jan 14 '11 at 20:22
  • @Kevin fair enough :) done. I extended it a bit because you would need the user's ID in there as well – Pekka Jan 14 '11 at 20:24
  • 2
    `/images/{survet_id}/{timestamp}_{id}.{ext}` where id would be 1/2/3 etc, then you do `glob("/images/$survey_id/*_(1,2,3,4,5,6).(gif,png)")` and be ablle to get the files neatly. – RobertPitt Jan 14 '11 at 20:26
  • Yea you may also want t add the user id in there: `/images/{survet_id}/{user_id}/{timestamp}_{id}.{ext}`, it doesn't really matter what way you place `survey_id` and `user_id` as its a one to one relation. – RobertPitt Jan 14 '11 at 20:41

5 Answers5

1

Wow, this is kinda open-ended... I think I'd probably structure a directory for each user, then name the images based upon the datetime they were uploaded. So it would look something like this:

/+
 |
 +--+ Kyle
    |
    +-- 20110113114903.png
    |
    +-- 20110113115122.png
    |
    +-- 20110114010304.png
 +--+ Kevin
    |
    +-- 20101114123456.png
    |
    +-- 20110102023648.png
    |
    +-- ...

However, this may not be as scalable as you like. You might want to make the directories deeper, so each person gets a directory per date, with images inside.

Kyle Humfeld
  • 1,887
  • 4
  • 23
  • 28
1

Mapping all this in a database to where you have them stored on the file system would be the best result in searchable surveys and users.

// Pseudo Database
// user table
user_id (pk)
user_name
user_filesystem_dir
...

// survey table
survey_id (pk)
survey_name
survey_filesystem_dir
...

// Image table
image_id (pk)
image_name
image_filesystem_dir
user_id_fk (this is the user_id from the user table)
survey_id_fk (this is the survey_id from the survey table)
...

// Find all the images for user id 123 and survey 456
SELECT * FROM image_table AS it, user_table AS ut, survey_table AS st
JOIN (it.user_id_fk = ut.user_id AND it.survey_id_fk = st.survey_id)
WHERE user_id_fk = 123
AND survey_id_fk = 456

// Pseudo Code
$user_id     = 123;
$survey_id   = 456;
$survey_name = 'Stack Survey #1';

$image_array = array(
    'image1.png',
    'image2.png',
    'image3.png',
    'image4.png',
    'image5.png',
    'image6.png'
);

// Folder Structure where User is most searched 
+-+123 <user_id>
  |
  +-467 <survey_id>
  | |
  | +-images
  |   |
  |   +-image1.jpg
  |   +-image2.jpg
  |   +-image3.jpg
  +-456 <survey_id>
    |
    +-images
      |
      +-image1.png
      +-image2.png
      +-image3.png
      +-image4.png
      +-image5.png
      +-image6.png

// Folder Structure where Survey is most searched 
+-+467 <survey_id>
| |
| +-123 <user_id>
|   |
|   +-images
|     |
|     +-image1.jpg
|     +-image2.jpg
|     +-image3.jpg
+-456 <survey_id>
    |
    +-123 <user_id>
      |
      +-images
        |
        +-image1.png
        +-image2.png
        +-image3.png
        +-image4.png
        +-image5.png
        +-image6.png
Phill Pafford
  • 83,471
  • 91
  • 263
  • 383
0

If you track the individual users as is suggested by "thus tracking their improvement over time" I would start with that being the top level directory. However, even that can lead to a directory bloat as the number of users increases.

In one application I wrote where I had to create a file for every user in a system, I wrote a routine (was actually database side) that broke down their unique id into a structured set of folders.

For example: user 12345 upload #5 could be stored in UPLOAD_DIR/1/2/3/4/5/upload_5.png

If you wanted something a little less "guessable" you could still use something like the above but instead of just using their id, you could hash it but follow a similar pattern.

jsuggs
  • 2,632
  • 3
  • 19
  • 17
0

Consider sequential numbering:

user123_survey1_image6.jpg

The ID of the user being 123, and this being the user's sixth image, or even more easily:

user123_survey56_image899.jpg

where user 123's sixth image happens to have the ID 899.

Pekka
  • 442,112
  • 142
  • 972
  • 1,088
0

One alternative would be to name your files randomly with uniqid(). You would have to check to make sure that that uniqid does not already exist of course. Something like this.

do {
    $filename = uniqid().'.jpg';
} while (file_exists('images/'.$filename));
dqhendricks
  • 19,030
  • 11
  • 50
  • 83
  • this assumes you are keeping the filenames in a database. – dqhendricks Jan 14 '11 at 20:36
  • This is also bad code... the loop is endless unless you add the file creation in the `do` part... otherwise you're iterating forever... should be `while (file_exists('images/'.$filename))` – jscul May 09 '18 at 06:14
  • 1
    @JohnCullen you are right. I have edited the answer to reflect that. – dqhendricks May 16 '18 at 18:01