A Guide To Website Structure/Organization

Today I want to talk to you about how I go about setting up my websites to ensure an organized structure and accessible code. This blog post covers these sections:

  1. Folder Structure/Organization
  2. The Critical Boot File
  3. Accessible Classes

Now without any more frivolous details, let’s dig in.

Folder Structure/Organization

The folder structure/organization (herein referred to as folder structure) is two fold:

  1. For small websites all page files are included in the root directory.
  2. For big websites the page files are categorized in to separate folders.

I’ll first be addressing small websites and then I’ll go in to details on larger websites as the folder structure gets more complex at that point. Now then, my website folders are setup as follows:

An outline of the website’s folder and file structure
  • css: Contains Cascading Style Sheet files
  • fonts: Contains font files
  • img: Contains media files
  • js: Contains script files
  • resource: Contains files related to site functionality
  • >external: Contains 3rd party files (e.g. “Login through [Facebook/Steam/Twitter]” implementations)
  • >internal: Contains 1st party files/critical site files
  • >>include: Files to be included for functionality
  • >>>exampleclass: Lowercase folder contain a main classes
  • >>>>exampleclass.php: The actual class file
  • >>>function: Contains files that add functions
  • >>>>somefunctionality.php: Example function file
  • >>>autoload.php: Implements auto loading for classes
  • >>>boot.php: Entry point for all pages.
  • index.php: Example webpage file.

To address larger projects I’ll be using my Clockwork Collections project as an example. The key difference is that most of the root folders containing things such as CSS/JS/etc. have been moved under “/resource/internal/”. Here’s a picture of that now:

An outline of the website’s folder and file structure for a large website

You can also see how many of the categories for the website have been split in to different folders. Each page name is its own folder name. This is achieved by including only one file in each folder named “index.php” so that when a user accesses a folder without specifying a page they will automatically open the index.php file. Sometimes this requires editing your web service settings (e.g. apache2) in order to automatically open the index file.

Here’s one more picture on how the folders are split up in to categories:

Notice how there’s two components to the folder structure:

  1. Functionality from the “action” folder
  2. What the user views from all the other folders

When a user, let’s say clicks a button to download a plugin then this file will be called from the user: /plugin/list/hl2rp/12345/example-plugin/download/index.php

That file will redirect the user’s request to the action file found here (while also sending the plugin ID): /plugin/action/download/index.php

This allows all functionality to be redirected to a centralized means of processing a user’s request. That way you only have to edit a single file to affect the functionality across all other files.

The Critical Boot File

This is probably thee most important file being used by my websites. This allows me to consistently load needed files while also taking care of important things such as escaping text from $_GET or $_POST for security purposes. I’ll first be taking a look at what the boot file looks like and then how it’s implemented. Here’s how the boot file looks in my Clockwork Constructors website:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?php
// IMPORTANT NOTICE: This file should be included at the start of every file.
 
$DEBUG_MODE = false;
 
if ($DEBUG_MODE == true) {
ini_set('display_errors', 'On');
error_reporting(E_ALL);
} else {
ini_set('display_errors', 'Off');
error_reporting(0);
}
 
// Sanitizes GET and POST. This also sanitizes arrays contained within.
$_GET = filter_input_array(INPUT_GET, FILTER_SANITIZE_STRING);
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
 
$WAS_GET_SANATIZED = true;
$WAS_POST_SANATIZED = true;
 
// Adds autoloading for classes.
include('autoload.php');
 
// Sets up session for use.
include('session.php');
?>

What this file does is display errors if debug mode is enabled, sanitizes the $_GET and $_POST variables, and includes other critical files. Here’s the code I use to include the boot file consistently every time (e.g. from my index.php file in the Clockwork Constructors website):

1
2
$ROOT_FOLDER = realpath($_SERVER["DOCUMENT_ROOT"]);
include($ROOT_FOLDER . '/resource/internal/include/boot.php');

What this does is search for the boot.php file from the root directory of the website. I’ve used this on most of my websites (both locally and live) without fail each time.

Accessible Classes

This section pertains to autoloading for classes and is actually quite easy to implement. You may have your own preferred way of going about this, but I’ll show you mine anyways. In my autoload.php file (as included in the boot.php file), I define this code:

1
2
3
4
5
6
7
8
9
<?php
spl_autoload_register(function ($class_name) {
global $ROOT_FOLDER;
 
$class_name = strtolower($class_name);
 
include($ROOT_FOLDER . '/resource/internal/include/object/' . $class_name . '.php');
});
?>

This says to search a specific folder for the class file when that class is instantiated. I use capitalization in my class names, however I use lowercase folders since my websites are running on a GNU/Linux OS (I also think things generally look nicer with all lowercase folder names). That’s why I have to change $class_name to lowercase so that it will search the correct folder. Now I can type something like this:

1
$itemConstructor = new Item();

As opposed to something like this if I didn’t have autoload implemented:

1
$itemConstructor = new resource\internal\include\object\Item();

Additionally this allows for easier maintainability so that if/when I change my class file location I only have to change one line in autoload.php instead of all of the lines that instantiate the class.


If you’d like to read more about how I organize my code then check out my other blog post here: A First Analysis – Clockwork Constructors

A Guide To Website Structure/Organization

Leave a Reply

Your email address will not be published. Required fields are marked *