robertmylne's avatar

Image Storing Folder Structure

I have made a post form, that STOREs a new post. After the post is made the user can then SHOW the post and add images.

The way I setup the images folders is like so {post_id}/{timestamp}_{random_str(4)}. This worked just fine to stop any clashes that may happen as I didn't want to ever delete an image that was uploaded, just remove it from the database.

The problem I now face is that I have been instructed to now add the images in the same form as creating the post. Therefore I can no longer use ~~{post_id}~~. As the post has not been saved yet and the images are auto uploaded via ajax, using dropzone.js.

So I kind of have two ideas in my head of how to do it, but am unsure if either is the best option and was hoping the community could give me some feedback on the best way to do this.

Option 1: {user_id}/{timestamp}_{random_str(4)}

Option 2: {timestamp}_{random_str(4)}

I would prefer something like option 2, but I am worried that clashes may occur? Is this possible?

0 likes
8 replies
DarkRoast's avatar

random_str() generates a random string, but this does not mean it won't spit the same thing out twice. It's unlikely to collide but if you want to be more sure consider phps uniqid() function instead: {timestamp}_uniqid()

carenburg's avatar
Level 5

I might personally look at giving each image a UUID for the name when storing, and store the images in one folder. The likely hood of a UUID clashing is very very slim. Ben Ramsey's UUID package makes it dead simple to ( ramsey/uuid).

Structure wise I might have the folders laid out as such.

storage/public/posts/images --- with all post images going in that one folder. You can easily append the post ID to a uuid ( you would need to use an underscore or another separator).

Just my two cents

robertmylne's avatar

@carenburg So I am just reading this now. How does this no it will never create another duplicate in the database?

carenburg's avatar

@robertmylne You can not guarantee that two UUID's well ever clash, but you can safely assume you'll never see a clash of UUID's in a production environment.

"In other words, only after generating 1 billion UUIDs every second for the next 100 years, the probability of creating just one duplicate would be about 50%."

For more information you can check out this Source page on UUID's.

1 like
robertmylne's avatar

@carenberg thank you very much for your time today. You have saved me a massive headache trying to work out the best way to solve this problem :)

UhOh's avatar

UUIDs plus user folder structure...?

/storage/app/public/user_uuid/uuid.jpeg

And then use symlinks to obfuscate the uri, or obfuscate in code.

Some advantages: you can peak into user folders for tickets, apply limits, do directory checks for abuse, never have uuid collision even if extremely unlikely, monitor folder sizes from the shell, can use timestamp+random instead, etc.

UhOh's avatar

@robertmylne hi, sorry, by uri I mean the storage path uri. You don't want to show this...

/storage/app/public/user_uuid/uuid.jpeg since it reveals your directory structure... just out of an abundance of caution, you would create a symlink from your public folder to the public folder in storage or wherever. For example, anyone who inspects the html sees src=/photos/uuid.jpeg, but the symlink links internally to /storage/user/photos/uuid.jpeg.

You wouldn't do user_id/uuid. If you want the user_id as a parameter, it would be a user_uuid also. But since the item uuid is unique, you can skip the user if you like and just select for the uuid internally to do whatever you want to do.

That's at least one way to do it. If anyone has others, would love to know.

Please or to participate in this conversation.