Jump to content
Larry Ullman's Book Forums

A Site With Subdirectories For Each User!


Recommended Posts

Hi Larry!

 

This is "phaseblue" (the Flash guy) from your last forum. I know you don`t cover mkdir() in "PHP5 Advanced: Visual QuickPro Guide",

but given that my situation is a bit "advanced" I thought that this was the best forum to post this.

 

As you know, I run a fan website for the group Underworld in Japan. Many of the fans are quite tech savvy and quite a few are into

visual/musical arts. Recently I have been playing with the idea of creating an art gallery on the site where fans can create a profile

and post their work. What I think should happen is this:

 

1) A fan/artist registers and clicks on the email link sent to him to confirm his registration.

2) He/she then logs in for the first time and creates a profile.

3) A sub-directory (which he names) is automatically created for the artist (i.e. www.darktrain.jp/galleries/JohnSmith) and a php

index file is dropped in it.

4) He can then start uploading images to display in his/her gallery.

5) Whenever a visitor goes to a particular artist`s url, the index.php page will pull the artist`s data from the database and display it.

 

My question(s) is/are:

- What are some best practices/good security measures for implementing something like this?

- Should the images be stored in the artist`s folder, or should they be stored outside the web directory?

- Would you create a modular structure for the index.php page (so that the user never leaves the artist`s folder), or would you have

it redirect to other scripts on the top level of the site?

- When a visitor visits the artist`s index page (within the folder), how would you link the index.php file to the particular artist`s data,

by the folder name in which it resides or by a variable stored within the index file?

- And finally, when should the folder be created, before or after the artist creates his profile? I don`t want to run into a situation

where the directory was created, but the database wasn`t updated for some reason, or vise versa!

 

I`m using Larry`s complete user registration system from "PHP 6 and MySQL5: Visual QuickPro Guide" as a starting point.

I found a good mkdir() script which uses regular expressions on the name and checks for the existence of the directory before creating it.

 

Sorry for all the questions, but this type of layout is quite new for me.

 

Thanks a lot for any help Larry or anyone else can offer!

 

Matt

Link to comment
Share on other sites

- What are some best practices/good security measures for implementing something like this?

 

Um, be extra careful about validating the uploaded files to make sure they're of acceptable types. A proxy script, and blocking direct access to the subdirectories (using .htaccess or the like) would be even more secure.

 

- Should the images be stored in the artist`s folder, or should they be stored outside the web directory?

 

I normally try to put all writable folders outside of the Web directory.

 

- Would you create a modular structure for the index.php page (so that the user never leaves the artist`s folder), or would you have

it redirect to other scripts on the top level of the site?

 

The problem is if you ever need to change that index.php page. If so, you'd need to do so for all X users. It'd be better to use top level scripts.

 

- When a visitor visits the artist`s index page (within the folder), how would you link the index.php file to the particular artist`s data,

by the folder name in which it resides or by a variable stored within the index file?

 

I would think by the folder name, which the index file passes to the root level scripts that do the actual action. You want to avoid as much work up front as possible, and as many later edits as possible.

 

- And finally, when should the folder be created, before or after the artist creates his profile? I don`t want to run into a situation

where the directory was created, but the database wasn`t updated for some reason, or vise versa!

 

I'm not sure how to answer this one. I suspect it does't matter so long as you have checks that would delete the directory should the database insertion fail and vice versa.

 

Sorry for all the questions, but this type of layout is quite new for me.

 

No problem. That's what the forum is for!

Link to comment
Share on other sites

Larry, if you don't mind me asking, what do you mean by a proxy script? I get the .htaccess thing, but I'm not sure what you mean by a proxy script.

 

Also, you make a good point about having to edit all the index.php files if there is a change. That being the case, would you recommend having an index.php file in each folder that simply includes (in the programming sense) a top-level script? And then maybe, you would have a function in that top-level script that each index.php file calls and supplies the necessary information as an argument to get the correct data from the database? I mean, I suppose that's what you already said, but just want to clarify.

 

On another note, I have been wondering about this for a while, but if you have an .htaccess file controlling access to a Web folder, why do you recommend placing the files outside of the public Web directory? Does it really add extra security? If, for example, all the images for a particular gallery where in a Web folder, and that folder also included an index.php script and an .htaccess folder, wouldn't that be plenty secure? Also, when you use the mkdir function in PHP, the default permissions are chmod 755, which would prevent the writing/deleting of files by non-admins, right?

Link to comment
Share on other sites

A proxy script is a script that's used in place of something else. If you have something outside the web root for some reason that you don't want the user to have direct access to you use a proxy in its place to call the file from the file/folder that is outside the root. (I As I understand it)

  • Upvote 1
Link to comment
Share on other sites

Larry,

 

Thank you so much for your reply!

 

Um, be extra careful about validating the uploaded files to make sure they're of acceptable types. A proxy script, and blocking direct access

to the subdirectories (using .htaccess or the like) would be even more secure.

Good points!

 

I normally try to put all writable folders outside of the Web directory.

As * Hartleysan said, I`m not sure why this is necessary. It just seems more logical to have all the artists media kept within the folder for his

gallery. If done outside the artists`s folder, then you get into the added complexity of linking a specific artist with his/her image files

(adding a new table to the database, writing more code, putting more demand on the server, etc...). What do you think about Hartleysan`s

suggestions?

 

The problem is if you ever need to change that index.php page. If so, you'd need to do so for all X users. It'd be better to use top level scripts.

I didn`t even think about this one! Thank you so much Larry!

Hartleysan thought that including a simple function call in the index.php file to a "createPage()" function in an upper-level script would be a

good way to do this and I agree! All links shown in the index page would call upper-level scripts to create the new content (i.e. gallery pages)

without the user ever leaving the folder/index.php page. Does that sound like a good idea?

 

I would think by the folder name, which the index file passes to the root level scripts that do the actual action. You want to avoid as much work

up front as possible, and as many later edits as possible.

Hartleysan suggested the same thing about using the folder name, and it would certainly work fine, but I just feel that using the artist`s ID would

be a more direct and less error-prone way to make a database query. Querying the user table by "folder_name" just seems like a half ass

workaround to the way it ought to be queried (i.e. by user_ID). I look at it like this: Imagine that we all live in a small town. Everybody in the

town has one car, and they are all different makes and colors. Would it be more logical to ask "Who owns the red Porch 911?" , or "Who owns the

car with license plate # 1967825?" The last question is far more accurate/efficient from a database point of view. The problem is how to get

access to this user_ID unless it is embedded in a variable within the index.php file. With that scenario I now have to open, write to, and then close

the index.php file before writing it to the artist`s folder every time a new account is created, which does create more work!

 

 

I'm not sure how to answer this one. I suspect it does't matter so long as you have checks that would delete the directory should the database

insertion fail and vice versa.

It sounds easy in theory, but I might need a little help with this one :(

 

Matt

 

* Hartleysan and I both live in Japan and are good friends. We often talk about various web projects and code problems.

Link to comment
Share on other sites

Also, you make a good point about having to edit all the index.php files if there is a change. That being the case, would you recommend having an index.php file in each folder that simply includes (in the programming sense) a top-level script? And then maybe, you would have a function in that top-level script that each index.php file calls and supplies the necessary information as an argument to get the correct data from the database? I mean, I suppose that's what you already said, but just want to clarify.

 

Yes, exactly.

 

On another note, I have been wondering about this for a while, but if you have an .htaccess file controlling access to a Web folder, why do you recommend placing the files outside of the public Web directory? Does it really add extra security?

 

No, it's an either/or. If the folder isn't in the Web directory, then there's no need to use an .htaccess file on that directory (because it's not Web accessible).

 

If, for example, all the images for a particular gallery where in a Web folder, and that folder also included an index.php script and an .htaccess folder, wouldn't that be plenty secure? Also, when you use the mkdir function in PHP, the default permissions are chmod 755, which would prevent the writing/deleting of files by non-admins, right?

 

"Plenty secure" depends upon the site in question. 755 means that only the owner can write to the directory.

 

That makes sense, in the same way that a proxy server might be used to hide the actual IP address, etc., but...well, okay. I suppose if you really need that level of security, sure. Thanks, Jonathon.

 

That's the fundamental thing about security: if you need that level. There's no right answer, there's only more secure and less secure.

 

A proxy script can do more than what you think, though. You could use a proxy script to limit access to only registered users or to count how many times a resource has been requested.

 

As * Hartleysan said, I`m not sure why this is necessary. It just seems more logical to have all the artists media kept within the folder for his

gallery. If done outside the artists`s folder, then you get into the added complexity of linking a specific artist with his/her image files

(adding a new table to the database, writing more code, putting more demand on the server, etc...). What do you think about Hartleysan`s

suggestions?

 

It's not a matter of "necessary", it's a matter of "warranted" or "appropriate".

 

I didn`t even think about this one! Thank you so much Larry!

Hartleysan thought that including a simple function call in the index.php file to a "createPage()" function in an upper-level script would be a

good way to do this and I agree! All links shown in the index page would call upper-level scripts to create the new content (i.e. gallery pages)

without the user ever leaving the folder/index.php page. Does that sound like a good idea?

 

Yes.

 

Hartleysan suggested the same thing about using the folder name, and it would certainly work fine, but I just feel that using the artist`s ID would

be a more direct and less error-prone way to make a database query. Querying the user table by "folder_name" just seems like a half ass

workaround to the way it ought to be queried (i.e. by user_ID). I look at it like this: Imagine that we all live in a small town. Everybody in the

town has one car, and they are all different makes and colors. Would it be more logical to ask "Who owns the red Porch 911?" , or "Who owns the

car with license plate # 1967825?" The last question is far more accurate/efficient from a database point of view. The problem is how to get

access to this user_ID unless it is embedded in a variable within the index.php file. With that scenario I now have to open, write to, and then close

the index.php file before writing it to the artist`s folder every time a new account is created, which does create more work!

 

You should never make the primary key value (from a database table) publicly available. Definitely not secure. To improve upon your metaphor (and I like a good metaphor), the real suggestion is that everyone knows everyone else's social security number, which would be bad.

 

* Hartleysan and I both live in Japan and are good friends. We often talk about various web projects and code problems.

 

Excellent. Nice to "meet" you.

Link to comment
Share on other sites

Larry,

 

Thank you very much for your responses! I think I have enough to go with to get started.

Actually, I already started setting this up. I decided to use the "Knowledge is Power" example from "Effortless E-Commerce"

as a starting point. The code is much more up-to-date and secure compared with the "PHP6 and MYSQL 5: Visual Quickpro

Guide" user registration code from ch16. I do need to take out the whole PayPal payment code and a few other things, but

everything else is almost ready to go!

 

I just had one last (I hope) question for now:

As you know, I need have a profile setup page for each user that will get certain information from the them which it used to

create his/her gallery (i.e. display name, country, hobbies, gallery description, and most importantly, the name for the gallery

folder). Currently, I have a table for users, but I don`t think it would be appropriate to store all this extraneous information

there. From a database design point-of-view, the "users" table is merely the table for storing information about the user`s

account. I think that there should be another table called "profiles" which has a one-to-one relationship with "users" by "user_id".

What do you think of this Larry?

 

Finally, what I`m thinking is that when a user logs in for the first time after registering, he/she will be sent to a page for

setting up their profile. As mentioned above, this profile page will collect various pieces of info. about the user, as well as

the name he/she would like to use for their gallery directory (i.e. the folder name). Obviously, I need to check the database

every time a user logs in to see if they have an entry in the "profiles" table. If they do, then they sign in as usual. If they

don`t, then they are redirected to the create_profile.php page.

 

What I wanted to know is what would be the most efficient way to check for this? Wouldn`t it be faster to just have a flag

field in the "users" table that contains "1" if the "profile/gallery was created, or "0" if it wasn`t?

 

Thanks again Larry,

 

Matt

 

btw - Larry, you might laugh at me for this, but I was actually an IT major and I took a few database classes!!! I can usually

visualize the setup for most schemas quite easily, and indeed many are quite simple, but there are always the outliers. It

can start getting pretty philosophical sometimes and I guess it just comes down to feeling and how you want to separate

the data. In this case, I`ve got a gut feeling that there should be a "profiles" table, but I want to hear your advice first.

Link to comment
Share on other sites

Matt, we have already discussed the various issues with your site outside this forum, but I will respond to your questions here as well, in an effort to create a more open discussion and atmosphere.

 

First off, I think the idea for two tables in the database is a good one. However, I think my idea for how to implement the site slightly differs from yours.

 

As we discussed before, I think there should be a login DIV at the top of every page, which will be within the header file. If a user is not registered, they can click the appropriate link for a registration form, which I think should require the following information:

 

User name

First name

Last name

Email address

Desired folder name

 

Along with this data, the users table would also contain a field for the record ID (the primary key) and a registration date. I also strongly feel that the folder name should be chosen when a user registers their account, and the folder name must be tested for uniqueness. I understand your car description/license plate analogy, but in the end, if you test to make sure that the specified folder name is a valid server folder name and unique, there shouldn't be any issues.

 

Anyway, after the user has registered and verified their registration via email, I would not automatically jump them to the gallery setup page. I would instead include a link in the registration confirmation email that provides an explanation on how to setup a gallery, if/when they choose to do so. That's the imperative phrase: "if/when they choose". Also, I would place both that link and a link to their actually gallery page in their login DIV when the user is logged in.

 

Next, when the user decides to set up their gallery, they should be able to simply go to their gallery page, and if the creator of that page matches the person visiting the page (according to the database), then the user should be given the necessary options to edit the page. If the are not logged in/are a different user, then they should only be able to view the gallery.

 

It's also worth noting that when a user registers and confirms an account, I would take that opportunity to create a new entry in the gallery table that contains an auto-incrementing ID value, and a foreign key to the folder name in the users table. Again, if the folder name is truly unique, this should pose no problem!

 

And like you mentioned before, if you decide to place all the images for a gallery within the created folder for that user, you don't even need any image info in the database. You can simply scan that folder for images everytime someone goes to that page. So, in the end, I think all you need in the gallery table is the following:

 

id

folder_name (the foreign key to the users table)

gallery_name

gallery_description

country

hobbies

last_updated

 

I think that's more than enough. Maybe I missed something, but I digress. Also, if you wanted, you could set default values for the gallery database to signify that a user has been registered with a gallery, but the gallery has not yet been set up. You could set default values like the following:

 

gallery_name='Your gallery name goes here.'

gallery_description='Your gallery description goes here.'

 

Sorry, I'm just spitballing ideas, but I think you get the point. I suppose, in the end, it wouldn't hurt to have a gallery_active flag, but since the gallery is essentially active as soon as a user is registered, then I don't think that would be a problem.

 

Or what I mean to say is that any customization beyond that is up to you, but I think the essentials are already there.

 

Any thoughts?

  • Upvote 1
Link to comment
Share on other sites

 Share

×
×
  • Create New...