Php – How should I handle uploads centrally and sanely in the web app

ArchitecturecodeigniterPHPweb-applications

I am creating a web application, which is basically a very specialised CMS. It's written in PHP with Codeigniter (though the specifics are not important) and is structure according to the MVC pattern.

Many entities in this webapp require the ability to have uploads, e.g pages, articles etc.

I have an upload controller which works fine on its own. How it functions is that we have a media table which records meta data about an upload, and then a number of other tables which map a specific media item to an article/page etc so articles_media, pages_media etc. These tables just contain a media_id and an article/page/etc_id

I clearly don't want to copy and paste the upload code throughout the app so when you are on an article_create view, for example, there is a link to the upload controller which opens in a pop up allowing you to upload an image.

The problem with this is that at the point at which you want to upload an image you haven't actually created the article/page etc. so there is no ID that can be passed to the upload controller to map the uploaded media to the specific article/page etc.

My "solution" which feels completely insane, is to add an is_published field to the models that require uploads and when you get to the create page to instantly create it with all blank values except is_published = 0 and then I have an ID I can pass to the uploader.

This does work but it feels sub-optimal, for starters I'm going to [potentially] end up with many blank rows in the database.

How do sensible people normally do handle this? I don't require any specific implementation help, I'll figure out the required PHP myself but my brain cannot seem to come up with a logical solution to the overall problem.

I thought my mapping between media, articles_media and articles was neat but maybe this is also part of the problem…?

In theory I'd like a user to be able to upload an arbitrary number of media files, though in practice this is actually meant to be quite limited, as in you can only have one upload with one article etc.

I would appreciate informed opinions – I'm assuming there is a [relatively] straightforward "best practice" to this problem that I just can't seem to come up with myself.

Best Answer

There are a lot of ideas about the best way to do that, the one I use and which never let me down is to create a stripped down version of my file table where I store uploads until either 1 - the user finish the request and I can move the file to the final table with all info, 2 - the user cancels and I drop it, 3 - the user does neither and a cron cleans it up after, say, a week.

This handles multiple files upload for the same media (even when not all on the same request, so you can provide an "add more media" form), "final" files are not mixed with temporary ones, the user closing the browser without finishing what he's doing does not mean you get a bloated file table (the cron will clean it up), ect ...

And whatever choice you make, I can advise you with experience: do NOT go the "is_published" way. You do not want that. Seriously, you're gonna hate yourself if you try.

Related Topic