Forum Moderators: coopster

Message Too Old, No Replies

Files and folder structure

         

ernest1b

11:57 pm on Apr 28, 2010 (gmt 0)

10+ Year Member



Please could you advise me about file structure.

My structure is currently the following:
Inside main root folder:
index.php
profile.php
inbox.php
users.php
...

Each main php file has two parts. On top only php which gets all data, handles $_POSTs etc., below I display html without and with php.

Each file has sections. For example profile.php has aboutme, friends, comments, ...
I do this by the following way:
//top
if ($_GET[section]=="aboutme"){
include_once('includes/profile/aboutme_php.php');
}elseif($_GET[section]=="comments"){
include_once('includes/profile/comments_php.php');
}
//...

//below
?>
<html>
<?
if ($_GET[section]=="aboutme"){
include_once('/profile/aboutme_html_php.php');
}elseif($_GET[section]=="comments"){
include_once('includes/profile/comments_html_php.php');
}
//...
?>
</html>


So each bigger page has own folder inside includes folder where are files for each section. Similar is with header and footer, but because they are common to all pages, I have it in includes without subfolder.

Each file have included also settings.php. Settings.php is located outside root for security reasons. And inside settings.php are included functions.php and language.php.

Is ok to have include in parent include (functions.php>settings.php>profile.php)?

Is ok to have in this case for example comment in includes/profile/comments_html_php.php?

Is this common and ok to use this way?

Tnx!

CyBerAliEn

3:28 am on Apr 29, 2010 (gmt 0)

10+ Year Member



Is your structure perfect? Probably not. But it is a good start! Frankly, the idea of looking at your pages and determining that there is a common structure with unique pieces... and then module-izing these pieces into different files you can include with PHP is generally a good idea. It makes updating incredibly easy.

Once easy mistake using this include-method is that often people have URLs like "profile.php?page=comments" and to display 'comments', they use an include like:
include("{$page}.php");


Problem with above is that it opens the user to try and inject things into your script without your control. (bad)

Your approach (using IF's and ELSE's to look for what you EXPECT to find) is a good initial approach. But you'll eventually find this to be cumbersome with updates. What I tend to do a lot now is along the lines of (roughly):
if (file_exists($page)) { include("{$page}.php"); }
else { echo "<p>Error: Requested page does not exist.</p>"; }


Though in most of my own sites/projects, I'll usually append the full server/file path to the request and include the file by the full path, ie: /home/mysite/public_html/pageparts/profile_aboutme.php (instead of just 'profile_aboutme.php'; etc)

But specifically, your idea of having a top level page like "profile.php" and then having a folder (/profile/) with specific "parts" of profile in their own files, is a good approach. My only thoughts are, why is the file named "comments_html_php.php"? Why not just "comments.php"?

It seems weird to me to append 'html' and 'php' into the filename. If it is because you have different "comments" files for different things, then I would suggest further differentiating, ie:
/profile/
/profile/html/ (contains HTML/content files for comments?)
/profile/php/ (contains PHP files for comments? like functions, classes, etc?)


Bottom line
As you continue to develop, you'll always learn and discover newer/better ways of organizing your content and backend. Frankly, there is no "right" way. Some ways are just "better" than others. In my opinion, anything that resembles organization is A+++. I've worked on too many sites that someone else has developed that are an organizational nightmare on the backend. :(




My Structural Choice (FYI)
On my own projects where I have content mainly in files (not in a database, because I have to for some reason or another), I tend to have a ~general~ structure like:

/index.php = master file
/core/ = powerhouse of site backend
-- /core/java/ = all javascript files
-- /core/php/ = main and primary PHP files/modules/classes
-- /core/css/ = all css files
-- /core/proc/ = processors (forms)
-- /core/x/ = components (3rd party stuff, large groups of stuff, etc)
/images/ = all images of sites, with subfolders to organize
/pages/ = PHP files of content to pages
/shells/ = master templates (shells)
/templates/ = page templates
/files/ = download-able files (PDFs, etc)

Where Apache URL rewriting sends all requests to '/index.php'. This file includes all necessary PHP parts and determines "what" the user wants (routes the request internally). Based off what the user "wants", it will determine what 'shell' to load, what 'template', and what 'page'... ultimately to deliver the right HTML to the user.

On these sites, "shell" is a master template: it defines things like headers, footers, etc and all main structures that are constant across the site, and specifies a place where "content" loads; which is usually either a template or a page file. 'Template' files are similar, they get loaded into the content area of the shell (if a template is needed); templates might define a banner area, a sidebar, a sub-level navigation, and a place for their "content". Finally, the 'page' file is loaded into the "content" area of the template file (or the shell content area if a template is not specified); and page file is basically what you'd expect a web page to be, it has links, paragraphs, images, etc... but just the content, no headers, no footers, no major structural components, etc. It seems confusing, but essentially: shell -> template -> page file.

I like the approach so far because it allows me to rapidly change major site structures with ease while not having to modify real content. I use this same approach in file and DB driven systems. In a file based setup, everything is in files that are loaded; where as in a DB based setup, all of these things are stored in a database. To ease handling this, I have functions/classes that handle all of this manipulation/setup.

On these types of sites, all URLs are in the form "/aboutus/", "/profiles/", "/members/", "/library/presentations/", etc. In the 'pages' folder I'll have pages arranged as: "/pages/aboutus.php", "/pages/library_presentations.php", etc. Essentially, the filename will dictate the URL. On file based setups, I'll usually have metadata in a text file that is parsed (ie: "library_presentations.dat", which defines things like page title, template, etc); where as in a DB system, such info would simply be in the DB. Because I have the centralized system built, adding pages in such a file based setup is as simple as creating a new "/pages/newstuff/mypage.php" file with content and adding a new metadata file. Voila. However... it took me a bit of work to build up the system to make this easily do-able. I initially did it for a file-based system because I wanted to develop a framework that would allow me to rapidly build functional sites without need of a database. I eventually expanded it to be database-based as well. Of course, most sites/projects I work on are 'small' in terms of pages and content. Looking back on it, I could easily have used something like a CMS... but I find most/all CMS's bloated beyond what I need or want. But everyone as their own style/interests.

ernest1b

9:21 am on Apr 29, 2010 (gmt 0)

10+ Year Member



Thanks for very usefull info. I also agree with your idea to make also /profile/html/.I have just one more question. Is there any limit how deep in parent structure can go include file? For example
connection.php>functions.php>settings.php>comments.php>profile.php
Would be this too deep, can be any problem from the server prospective?

omoutop

9:47 am on Apr 29, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member Top Contributors Of The Month



for filename/path i think the limit is 254 characters (to be valid in both *nix and win platforms)

for url this limit goes up to 2048 characters (to maintain compability with earlier IE versions)

But I am not 100% sure for these nunmbers

CyBerAliEn

3:59 pm on Apr 29, 2010 (gmt 0)

10+ Year Member



To be outright, there is no direct on limit the structure such as:

/profiles/admins/images/status-symbols/blue/round/medium/
(etc)

You can essentially place as many sub-directories as you want within a directory; there is no direct limit on how far your structure can go (depth). Though as omoutop points out, there can be limits when it comes to "communicating" the length (ie: file paths, URLs, etc).

So realistically, no need to worry about it! But you should be sure the structure you choose is logical and concise. For example, this is probably a bad idea:

/profiles/admins/images/status-symbols/blue/round/medium/

Why? It is too convoluted! It may seem "descriptive", but you're better off using a simpler scheme like:
/profiles/images/symbols/
(etc)

All in all though, you should be fine going through with what you intend to do. :)

ernest1b

5:55 pm on Apr 29, 2010 (gmt 0)

10+ Year Member



than it is probably the best that I also use index.php to include all subpages depend on $_GET url. So I need to include header and footer and common funcations only 1 time instead for each larger page (profile.php, home.php, ...) each time.

Am I right?

Matthew1980

6:17 pm on Apr 29, 2010 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Hi there ernest1b,

Yes, that sounds about right, In theory you could have an index.php file that contains no html at all, and just rely on if/else switches and such to gather the include(); files dependant on how the $_GET was structured. Sounds like a plan to me anyway :)

When you do things like this though it is often best to use absolute paths to files rather than relative ones. One valuable way to do this would be to define the 'path' once, then you can just reference it whenever you need to:-

define('ROOT_DIR', dirname(__FILE__). "/");//Current directory

Your would need to re-type the path out again, and again, and again then :)

Hope that makes sense to you anyway.

Cheers,
MRb

CyBerAliEn

6:22 pm on Apr 29, 2010 (gmt 0)

10+ Year Member



That's what I would do. A good approach: module-ize everything (where feasible)!

So if your site looks like...
#index.php#
(header)
(nav)
(news)(sidebar)
(footer)

#profiles.php#
(header)
(nav)
(member profile)
(member friends)
(footer)

#etc#


If you look at the "pages" in this generalized-full-form... you'll see that they share the SAME elements (header, footer, nav; etc). Your best approach would be to remove these items, making your page modular. Many people accomplish this via:

#index.php#
<?php
include('phpstuff.php');
include('header.php');
include('nav.php');
?>
(homepage stuff)
<?php include('footer.php'); ?>


Where each page follows this form. Anywhere a "module" is used, it is simply "included" via PHP. Obviously, separate (single) files exist elsewhere for the header and footer (etc). This way, if you need to edit the footer, you edit ONE FILE and the whole site changes. Same for header, same for nav, etc.

This is the easier method to accomplish module-izing your site. Note however that I noted a "phpstuff.php" include at the top. My recommendation is to put an "include" to a single PHP file at the top of every page. This file should do all of the PHP handling you want to do. If you have classes to include, do it there. If you want to establish a DB connection, do it there. Etc. Having this single script included into EVERY page allows you the ability to easily "expand" the site without having to go into each individual page and regularly added new includes/etc. (some people might do this type of stuff in "header" since it is included anyway; I don't like this; in my opinion, header should be JUST header)


But consider: What if your site is generally in this form:
(header)
(nav)
(content stuff)
(footer)

And you want to change it to:
(header)
(nav)
(content stuff)(sidebar)
(banners)
(ads)
(footer)

You could get around this update by including the "new" items in the 'footer' script (specifically banners, ads; cause they're basically 'like the footer'). But what if you decided to change the layout/structure further, by adding a cool sidebar to the side of the content (or something else that is more complex)? This MIGHT mean you have to open EVERY page you have (which could be a lot of pages), and modify the "includes" to account for these changes. I don't like this.

My approach would be to use a template/shell file, a la:
(header)
(nav)
(sidebar)(CONTENT)
(footer)


Where the main structure is defined in one file, and the "content" is in another file. This allows quick editing of the structure and key components while separating pure content to a separate file. The only problem with this approach is that it requires more work to setup the "system" (how does it include the shell/template; how does it include the content; etc).