Backend to frontend good practice web development
I dedicate this article to my daughter (16yrs), she is now studying full stack web development on WAMP – Apache, MySQL and PHP on a windows server. The server wouldn’t actually matter to this post since I want to consider some critical backened development practices which are derived from the nature and structure of web front end systems.
The following ideas are presented in PHP but they will be good for every interpreted backend programming language like Python and Ruby on Rails.
When we look at .com websites development, we need to understand that the high level architecture of website development is setting the way things work. Unlike simple computer programs (which run on one machine, in front of one user – for example – a desktop word processor), web programs have got a client-server architecture: the server (usually on a remote site) is serving the client or a group of clients (the web users) with web pages. The client is usually a web browser (Chrome / Firefox / Safari etc), the server is usually running several components on top of the operating system – a web server (e.g. Apache), a database server program (e.g. MySQL), and an application server (e.g. PHP / Python). So when you write a PHP code on the server, the PHP application is interpreting it, the database server is accepting the queries and sending back the data results to the application, and the web server is accepting the http/https requests and sending back a packet of HTML and Javascript which the browser on the client side knows how to interpret.
In other words, the application level (PHP) is creating the HTML code. In the eyes of the client (the browser), this command:
<span id="greeting">Hello!</span>
and those commands
<?php $calc = 0; $spanName = "greeting"; echo '<span id='.$spanName.'>Hello!</span>'; $calc = $calc +1; ?>
Are exactly the same, simply because the browser is not receiving any PHP string, once the PHP has been executed in the server, it produces the HTML code which is sent, by the web server, to the external world.
The next important thing to understand in the foundation of web development, is that both the browser, and the application server, are interpreters (this won’t be the case with language like Java and C++) – meaning, that it works line by line, from the top to the bottom. It means that PHP code which is on the bottom, can’t influence HTML output above it (unless in function). This fact makes the good practices of web development look different than in other programming languages. As an example, lets look at the following code:
<html> <body> <h1>My List of 10 items</h1> <?php for ( $i= 0 ; $i <= 10 ; $i++ ) { echo $i."<br>"; } ?> </body> </html>
I will explain later why this code is not good practice, it will work perfectly good but at the moment I wish you to understand that the HTML header is sent before the loop is executed. There is no way back – i.e. once the HTML header is sent, you must continue and plot HTML. HTML however is not the only possible PHP output, which would make life very hard if this code is required to do other things.
Good BackEnd Web Development Practices
Do all backened calculations before the HTML output
I would never mix application (e.g. PHP) calculations inside the HTML tags area, even that application interpreters (PHP) are designed and built to do so. Obviously, to get a dynamic site, you must mix between the application script (e.g. PHP commands) and HTML. But I would not do any calculations in the HTML area, meaning – that I would output variables, and maybe use conditions in that area, but all those variables would be calculated in the application area of the page which must be at the top of the page, this is due to the nature of interpreter language to work from top to bottom. If we take the above example and fix it, it should look like that:
<?php $myListOfItems = ""; for ( $i= 0 ; $i <= 10 ; $i++ ) { $myListOfItems = $myListOfItems . $i . "<br>"; } ?> <html> <body> <h1>My List of 10 items</h1> <?php echo $myListOfItems; ?> </body> </html>
The are lots of motivations why to work like that. The main one is, that computer programs tend to collect complexity, as the requirements become bigger and bigger. Imagine that the above code is used in a 10,000 lines of script… if that script would have many application calculations embedded in, it will be very hard to keep it tidy for debugging. Another reason is, that requirements may change – if for example you would want to count the number of even numbers and put it in the headline, it will be impossible to do it with the original code. Look at the following simple code:
<?php $myListOfItems = ""; $counterOfEven = 0; for ( $i= 0 ; $i <= 10 ; $i++ ) { $myListOfItems = $myListOfItems . $i . "<br>"; if ($i%2 == 0) { $counterOfEven = $counterOfEven+1; } } ?> <html> <body> <h1>My List of 10 items</h1> <h2>Number of even numbers: <?php echo $counterOfEven;?> </h2> <?php echo $myListOfItems; ?> </body> </html>
Even such a simple new requirement would be impossible to be developed on top of the original code.
Gather all functions in a separated include file
I would gather all functions and global variables in one include.php file, that would be included by each application file which requires them. Some people separate the included files by subject matter (e.g. one file for global variables , a separated file for database connections, one file for data function, one file for functions etc) but I would do that only if the total lines of code is so big, that it requires further categorizing. In most applications, I would collect everything in one file, and will separate the database connection functions, variables etc by comments.
Use global variables for anything which is likely to change
If something is likely to change – like – the number of items in your list, use a global variable to set it, and use the global variable wherever you need to use that number. For example, for the above script, I would add an include file with global variables:
////////////////////////////////////////////////////////////////// //////////// GLOBAL VARIABLES //////////////////////// ////////////////////////////////////////////////////////////////// $G_total_number_of_items = "10"
and the main script:
<?php include 'include.php'; $myListOfItems = ""; $counterOfEven = 0; for ( $i= 0 ; $i <= $G_total_number_of_items ; $i++ ) { $myListOfItems = $myListOfItems . $i . "<br>"; if ($i%2 == 0) { $counterOfEven = $counterOfEven+1; } } ?> <html> <body> <h1>My List of <?php echo $G_total_number_of_items;?> items</h1> <h2>Number of even numbers: <?php echo $counterOfEven;?> </h2> <?php echo $myListOfItems; ?> </body> </html>
Use name conventions to distinguish between the global variables and other variables
Some people use CAPITAL_LATTERS_NAMES to highlight global variables. I prefer a prefix like G_ which tells me what type of variables it is: when you use capital letters you limit your options, when you use G_ you could use other prefixes like A_ , B_, etc for other types of variables.
Never hardcode domain names, IP numbers, protocols etc
Domain names, IP numbers and protocols like http and https tend to change. If you hardcode (i.e. embed them in your code) such variables, you will make your life very hard once you wanted to move to another server host or make changes. Just use a global variable for those, or even better – be smart and use the request headers to determine the protocol (by reading the $_SERVER variable), the site folder and others ($_SERVER[‘SCRIPT_NAME’] has got this info).
Use name conventions to separate between publicly available files, and others
Apache server can run applications regardless of the file suffix, meaning when it comes to PHP – php can be executed when it is in .php files, in .htm and .html files or anything else. For security reasons you wouldn’t want to execute scripts on all files, but running them inside .html and .php files is a good idea, since then you could distinguish between files which are serving users (e.g. http://www.yourdomain.com/file.html) and files which are serving other php files (like internal functions files). My preference is to keep .php for internal use, and .html for external use – thus the users don’t really know that you execute php on their html file. It is good if users don’t know which application you use (i.e. php / python / ruby) for security reasons.
Separate the page header, the navigation and the footer in dedicated files
That practice would keep your code very tidy. A typical web page application script should look like this:
<?php include 'include.php'; // functions and global variables ///////////////////////// all php calculations - html header is not sent yet include 'header.html'; // HTML header including the CSS, top Javascripts and header closing tags include 'topNavigation.html'; // content which repeating in some pages - like navigation ?> <h1> Welcome </h1> <?php echo $phpOutput; ?> <?php include 'footer.html'; // content which is repeating in more than one page, like social shares including 'bottom.html'; // bottom javascripts, and the closing body and html tags! this is repating in *all* pages unlike the footer which may repeat in *some* pages ?>
Include the HTML header tags in the header.html file
Some developers tend to add the <html> and <body> tags in each php file, you may have easier life maintaining your application if those tags are added to the header.html file, meaning – once the header.html file is included, you know that the HTML string has started. This is useful in cased when the same script is used for both serving HTML and for returning data for API calls, like in the following example where we use the same data to server a JSON API call:
////////////////////////////////////////////////////////////////// //////////// GLOBAL VARIABLES //////////////////////// ////////////////////////////////////////////////////////////////// $G_total_number_of_items = "10"
<html> <body>
</body> </html>
and the main file:
<?php include 'include.php'; $myListOfItems = ""; $counterOfEven = 0; for ( $i= 0 ; $i <= $G_total_number_of_items ; $i++ ) { $myListOfItems = $myListOfItems . $i . "<br>"; if ($i%2 == 0) { $counterOfEven = $counterOfEven+1; } } if (isset($_GET['api']) AND $_GET['api'] == "true") { $outputArray = array(); $outputArray['counter'] = $counterOfEven; $outputArray['data'] = $myListOfItems; header('Content-Type: application/json'); print_r( $outputArray ); } else { include 'header.html'; ?> <h1>My List of 10 items</h1> <h2>Number of even numbers: <?php echo $counterOfEven;?> </h2> <?php echo $myListOfItems; include 'bottom.html'; } ?>
Require the functions files at the top
Always include your functions and global variables files at the beginning of your script. This way, all the necessary functions and variables are available throughout your code, making maintenance and debugging much easier. Think of it as having all your tools laid out before you start building.
Require the header file just before your HTML code starts
Including the header file right before the HTML output ensures that all the essential scripts, styles, and meta tags are loaded correctly. This keeps your HTML structure clean and organized, much like setting the stage before the performance begins.
Do your best not to loop on database queries
Try to minimize the number of database queries inside loops to enhance performance. Instead, fetch all the necessary data in a single query and then process it within your application logic. This approach reduces the load on your database server and speeds up your application, similar to buying all your groceries in one trip rather than making multiple visits to the store.
Always make sure the code is 100% warnings safe
Ensuring your code is free from warnings helps maintain a high standard of code quality. Use error reporting to catch and resolve any issues during development, which will help avoid potential bugs and improve the reliability of your application. It’s like proofreading an essay to catch any errors before submission.
Avoid using session variables
Relying heavily on session variables can lead to security vulnerabilities and make your application less scalable. Instead, use secure methods such as tokens and cookies for maintaining user state and authentication. This approach enhances the security and robustness of your application, much like using a secure vault instead of a simple lock for your valuables.
Smart use of repeating fields in database design
While normalisation is a fundamental principle in database design to avoid data redundancy, there are scenarios where strategically duplicating fields can enhance performance by reducing the number of queries needed. For example, if you have a users
table and an orders
table, it might be beneficial to include the user’s current email address directly in the orders
table, even though this data is already stored in the users
table.
By doing this, you avoid the need for frequent joins between the orders
and users
tables when querying order details along with user email addresses. This approach can significantly improve query performance, especially in read-heavy applications. Here’s a practical example:
-- Users table CREATE TABLE users ( user_id INT PRIMARY KEY, name VARCHAR(100), email VARCHAR(100) ); -- Orders table with email duplication CREATE TABLE orders ( order_id INT PRIMARY KEY, user_id INT, order_date DATE, total_amount DECIMAL(10, 2), user_email VARCHAR(100), FOREIGN KEY (user_id) REFERENCES users(user_id) );
With this design, when you query for orders, you don’t need to join the users
table to get the user’s email:
SELECT order_id, order_date, total_amount, user_email FROM orders WHERE user_id = 1;
This approach trades off some redundancy for a reduction in the complexity and number of database queries, leading to faster read operations, which is particularly beneficial in high-traffic scenarios.