Creating dynamic web pages using PHP and MySQL

Updated: 31-Oct-2023 / Tags: Full Stack Tutorials / Views: 2249 - Author: George

Introduction

In today's digital age, the web isn't just static pages of text and images anymore. Users expect dynamic, interactive experiences that respond to their input and deliver content tailored to their needs. If you're a web developer or aspiring to become one, you're in the right place because we're about to delve into the exciting world of creating dynamic pages using PHP and MySQL.

What we are going to code

In this tutorial we are going to create a simple shop so you can see how we can output dynamic content from the database, and display it accordingly to the query that we make.
Let me explain: A shop has categories and products. We will have a page named category.php, in which we will display the products listed in a particular category, and we will have a page named product.php, in which we will display each individual product.

By coding our application this way, we don't need to create separate pages for every category or product. This approach is often referred to as dynamic pages or dynamic content
Now this will be a full stack project, so let's begin.

Live Example

I've prepared a live example so you can see first hand what we are going to build.

Let me walk you through. Every time a user lands on our home page we will display a random set of four products. Click on the home link to see it. Also our navigation has an About, and a Contact page. I only created those pages to show you how to highlight the visited menu link.

The important thing is that when you click on a category you see the products that are listed in that particular category, and if you click on a product's name you will see details about that product.

Try it out, you will have a better understanding on what we are going to build.

Now that you have tried out the demo let's see the files, and folders that we need to re-create it.

Project's folder

This is how our file structure looks like.

\-- our store
  |-- index.php		
  |-- config.php		
  |-- category.php
  |-- product.php
  |-- contact.php
  |-- about.php
  
  |-- css    
    |-- styles.css

  |-- includes
    |-- nav.php
    |-- header.php
    |-- footer.php

  |-- Javasccript
    |-- script.js

  |-- php
    |-- functions.php

  |-- products
  	|-- image-1.png  
  	|-- image-2.png  
  	.....

We are gonna need:

  • A css/ folder, and inside a style.css file.
  • An includes/ folder, and inside we create a nav.php, a header.php and a footer.php file.
  • A javascript/ folder and inside a script.js file.
  • A php/ folder and inside a functions.php file.
  • And a products/ folder to store the product images.
  • Next in the project's root, we have an index.php file, for our home page.
  • A config.php file to define the constants that we will use throughout the project.
  • A category.php file to display each category with its products.
  • A product.php file to display each individual product.
  • A contact.php file, and an about.php file so we have some pages in our project, and also to show you how to highlight visited menu links.
That's all the files and folders that we need, but don't bother to create them, just click on the link to Download the whole project's structure including the SQL database file, and the product images, if you like to follow along.

Okay, now that we have the project's structure let's start this tutorial by showing you the database products table.

The products database table

This is how the products table is structured.
We have an id, an image, a price, a description, a category, a meta_description, and a meta_keywords column. In the image column we have the names of the images that are stored in the products/ folder.
In the meta_description, and meta_keywords columns we store information about each product, and we will use them in the product.php page for SEO purposes.

id image title price description category meta_description meta_keywords
1 javascript.jpg Learn JavaScript Quickly: A Complete Beginner’s Guide to Learning JavaScript 15.99 Lorem ipsum dolor sit amet consectetur adipisicing elit. Ratione eligendi quas eius quod. books product description product keywords

We have 19 more products in the table.
If you downloaded the project files, create a database, the name doesn't matter, and insert the products.sql file.

The styles.css file

The first file that we are going to create is the styles.css file. I will not go through the css code, it is not important for this tutorial. Just copy and paste the code in your css file, so the html code that we are going to write later on, will have already the styling applied.

*{
	margin: 0;
	padding: 0;
	box-sizing: border-box;
}

body{
	font-family: sans-serif;
	min-height: 100%;
	color: #555;
}

/* NAVIGATION RULES --------------------  */
nav{
	display: grid;
	grid-template-columns: auto 1fr;
	align-items: center;
	grid-column-gap: 30px;
	grid-template-rows: 70px;
	box-shadow: 0 5px 5px rgba(0,0,0,0.15);
	position: sticky;
	top: 0;
	background-color: white;
	padding-left: 20px;
	padding-right: 20px;
}

nav .brand{
	font-size: 28px;
	font-weight: 900;
	color: #245990;
}

nav a{
	text-decoration: none;
	display: inline-block;
	padding: 10px 35px;
	transition: background-color 0.3s, color 0.3s;
	color: #245990;
	font-size: 18px;
}

nav a:hover,
nav a.active{
	background: #4d9176;
	color: #fff;
	border-radius: 3px;
}
nav a:active{
	background-color: red;
}

/* HEADER RULES ------------------ */
header{
	padding: 40px 20px;
/*	background-color: #f4f4f4;*/
	border-bottom: thin solid #d4d4d4;
}
header h1{}
header .sub-title{
	margin-top: 20px;
	line-height: 28px;
	font-size: 20px;
}

/* MAIN SECTION ------------------ */
main{
	padding: 20px;
	display: grid;
	grid-template-columns: auto 1fr;
	grid-column-gap: 30px;
	margin-top: 30px;
	margin-bottom: 30px;
}
main .left{
	border-right: thin solid #d4d4d4;
	padding-right: 20px;
}
main .section-title{
	font-size: 22px;
	margin-bottom: 30px;
}
main .left a{
	display: block;
	text-decoration: none;
	color: #555;
	font-size: 18px;
	margin-bottom: 10px;
}
main .left a:hover{
	text-decoration: underline;
}

main .right{}
main .right .product{
	display: grid;
	 grid-template-columns: auto 1fr;
	grid-column-gap: 50px;
	grid-row-gap: 50px;
}
main .right .product-left{}
main .right .product-left img{
	height: 150px;
	display: block;
	margin: 0 auto;
}
main .right .product-right{}
main .right .product-right .title{
	font-weight: bold;
	font-size: 18px;
}
main .right .product-right .title a{
	text-decoration: none;
	color: #555;
	line-height: 26px;
}
main .right .product-right .title a:hover{
	text-decoration: underline;
}
main .right .product-right .description{
	margin-top: 10px;
}
main .right .product-right .price{
	font-size: 24px;
	margin-top: 30px;
	color: darkred;
}
main .right .product-right button{
	display: block;
	border: none;
	font-size: 18px;
	padding: 10px 30px;
	margin-top: 50px;
	border: thin solid #d4d4d4;
}

/* FOOTER RULES  */
footer{
	background-color: #333;
	padding: 20px;
	width: 100%;
	color: white;
}

Now let's start coding and let's begin with the config.php file.

The config.php file

In the config.php file we define the login details that you have set to your MySQL server.

<?php 
	define('SERVER', 'localhost');
	define('USERNAME', 'the mysql username');
	define('PASSWORD', 'the mysql password');
	define('DATABASE', 'the database name that you created');

The functions.php file

Next we are going to write the functions.php file, so we have all our functions created and ready to implement them in our html code.

We are going to need five functions.

  • A dbConnect() function to connect to the MySQL server and the database.
  • A getCategories() function to get the product categories that we have in the products table.
  • A getHomePageProducts() function to display the random products in the home page.
  • A getProductsByCategory() function to display the products that are listed in a particular category.
  • And a getProductBytitle() function to fetch the product in the products.php page.

So lets start.

The first thing that i will do in the file is to require the config.php file so we have access to the database login details.

<?php
require "config.php";

The dbConnect function

The first function that we are gonna write is the dbConnect() function.

/**
 * The dbConnect function connects php with the MySQL server.
 * @param  The function does not take any parameters.
 * @return The function returns the mysqli object on success, or false on failure.
 */	
function dbConnect(){
	$mysqli = new mysqli(SERVER, USERNAME, PASSWORD, DATABASE);
	if($mysqli->connect_errno != 0){
		return FALSE;
	}else{
		return $mysqli;
	}
}
  • In line 9 we create a new mysqli object and we pass-in as arguments the constants that we have defined in the config.php file. We store the returned object to the $mysqli variable.
  • In line 10 we have an if statement to check if the connection is successful, by calling the connect_errno (connection error number), property.
  • To have a successful connection the connect_errno property must return zero.
    If NOT we return false. If YES we return the $mysqli object so we can use it in our functions.

There is nothing else here so lets move to the next function.

The getCategories function

With the getCategories() function we will get the product categories.

/**
 * The function is fetching from the products table every unique category name.
 * @param  The function does not take any parameters.
 * @return The function returns an array of the distinct categories.
 */	
function getCategories(){
	$mysqli = dbConnect();
	$result = $mysqli->query("SELECT DISTINCT category FROM products");
	while ($row = $result->fetch_assoc()) {
		$data[] = $row;
	}
	return $data;
}
  • In line 23 we call the dbConnect() function and we store the returned object in the $mysqli variable.
  • In line 24 we fetch every distinct category from the products table, and we store the returned result-set in the $result variable.
  • In line 25 we use a while loop to fetch every row from the database table as an associative array, and store them in the $data[] array in line 26.
  • And in line 28 we return the $data array

The getHomePageProducts function

The getHomePageProducts() function will fetch from the database a random set of products that we are going to display in the home page.

/**
 * The getHomePageProducts function will fetch from the database a random
 * set of products.
 * @param  [int] ($int)  [The number of the random products]
 * @return [array]       [An array of the fetched products]
 */
function getHomePageProducts($int){
	$mysqli = dbConnect();
	$result = $mysqli->query("SELECT * FROM products ORDER BY rand() LIMIT $int");
	while ($row = $result->fetch_assoc()){
		$data[] = $row;
	}
	return $data;
}
  • The function takes as a parameter the number of the products that we want to display.
  • In line 38 we connect to the database.
  • In line 39 we query the database in a random order(ORDER BY rand()), and we set the LIMIT to whatever number we pass in the function as a parameter.
  • Next we loop through the result-set and create an array named $data which holds the random products.
  • And last in line 43 we return the $data array.

The getProductsByCategory function

The getProductsByCategory() function fetches all the products listed in a particular category. We will use this function in the category.php file.

/**
 * The getProductsByCategory function fetches all the products listed in
 * a particular category.
 * @param  [string] $category [The name of the category]
 * @return [array]            [The fetched products]
 */
function getProductsByCategory($category){
	$mysqli = dbConnect();
	$stmt = $mysqli->prepare("SELECT * FROM products WHERE category = ?");
	$stmt->bind_param("s", $category);
	$stmt->execute();
	$result = $stmt->get_result();
	$data = $result->fetch_all(MYSQLI_ASSOC);
	if(count($data) == 0){
		header("Location: index.php");
		exit();
	}else{
		return $data;
	}
}
  • The function takes as a parameter the name of the category($category) so we can display the products that are listed in that category.
  • In line 53 we use again the dbConnect() function to connect to the MySQL server and the database.
  • In line 54 we query the database but this time we use a prepared statement. That is because we will fetch the $category parameter from the browser's url with a GET request, something like ?category=games. So we have to be as secure as we can so nobody will hack our database.
  • So in line 54 we use the prepare() method, and instead of the$category parameter (category = $category), we use a question mark (category = ?).

    $stmt = $mysqli->prepare("SELECT * FROM products WHERE category = ?");

  • Next we bind the question mark with the $category parameter.

    $stmt->bind_param("s", $category);

    The bind_param() method takes two arguments. With the first argument we tell the method what data type the variable that we want to bind is. In our case its a string so we use the letter "s". If we had a number we had used the letter "i" which stands for integer. And the second argument is the variable.

  • Next we execute the statement.
    $stmt->execute();

  • Next we get the result-set in line 57, and in line 58 we fetch from the result-set the products as an associative array.

    $result = $stmt->get_result();
    $data = $result->fetch_all(MYSQLI_ASSOC);
    

  • Next we are going to add an extra security layer.

    if(count($data) == 0){
    	header("Location: index.php");
    	exit();
    }else{
    	return $data;
    }
    		
    • We are going to check if the database query has returned the products that we asked for.
    • So in line 59 we count the products in the $data array, and if the value is zero, we redirect the user to the index.php page using the header() function in line 60.
    • Else we return that $data array.
    • Let me explain the logic here. Basically we are saying that if the category doesn't exist in the database redirect the user to the home page. This will only happen if someone messes with our GET request in the browser's URL to compromise our database. Something like this ?category=',
      or ?category=<script>Do something harmful</script>.
    • So we not only use a prepared statement, but also we validate the returned data to be as secure as we can.
    • I have an article on How to write mysql prepared statements. Check it out.

Now lets write our last function.

The getProductBytitle function

The getProductBytitle() function will fetch the product by its title.

/**
 * The getProductBytitle function will fetch the product by its title.
 * @param  [string] $title [The product's title]
 * @return [array]        [The fetched product]
 */
function getProductBytitle($title){
	$mysqli = dbConnect();
	$stmt = $mysqli->prepare("SELECT * FROM products WHERE title = ?");
	$stmt->bind_param("s", $title);
	$stmt->execute();
	$result = $stmt->get_result();
	$data = $result->fetch_all(MYSQLI_ASSOC);
	if(count($data) == 0){
		header("Location: index.php");
		exit();
	}else{
		return $data;
	}
}
  • Everything that i explained in the previous function applies here to. So there is nothing else here to say.

And we are done with the functions.php file. Now we have our functions ready to implement them in the html code that follows.

But before we jump to the index.php file we have to create the html code in the nav.php, header.php, and footer.php files that we have inside the includes/ folder.

The navigation

Open the nav.php file and paste-in, the html code to create the store's navigation

<nav>
	<div class="brand">Our Store</div>
	<div class="links">
		<a data-active="index" href="index.php">Home</a>
		<a data-active="about" href="about.php">About us</a>
		<a data-active="contact" href="contact.php">Contact us</a>
	</div>
</nav>
  • Notice the data-active attribute that we have in every link. We are going to target those attributes from the javascript file file to highlight the visited nav link. We are going to associate every data-active value with each page's body id.

    In Example: in the index page we are going to set the id of the body element to "index", <body id="index">.

    In the about page we will have <body id="about">, and in the contact page we will have <body id="contact">. In this way we will use the body id as a reference to target the corresponding link and highlight it. Hope it makes sense.

The header

Next open the header.php file and paste in the header section.

<header>
	<h1>Welcome to our store</h1>
	<p class="sub-title">
		We have a wide collection of electronics, phones, books, and games, and low prices.
	</p>
</header>

The footer

And last open the footer.php file and paste in this very simple footer section.

<footer>
	Our store's footer
</footer>

Okay, we are done with the files in the includes/ folder, so lets go to the index.php page and structure our home page.

The index file

Here is how our index.php file looks like. Every other file that we are going to create will have the exact same structure.

<?php require "php/functions.php" ?>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta name="description" content="We have a wide collection of electronics, phones, books, and games">
	<meta name="keywords" content="phones, books, games, electronics">
	<link rel="stylesheet" href="css/styles.css">
	<title>Our Store</title>
</head>
<body id="index">
	<?php include "includes/nav.php" ?>
	<?php include "includes/header.php" ?>

	<main>
		<div class="left"> 
			<!-- Displaying the categories -->
		</div>
		<div class="right"> 
			<!-- Displaying the products -->
		</div>	
	</main>

	<?php include "includes/footer.php" ?>
	<script src="javascript/script.js"></script>
</body>
</html>	
  • The important things here are:
  • In line 1 we require the functions.php file so we have access to the functions that we wrote there.
    <?php require "php/functions.php" ?>

  • In line 9 we have the link to our stylesheet.
    <link rel="stylesheet" href="css/styles.css">

  • In line 12 we have assigned an id to the body element and set its value to "index". It has the same value as the data-active attribute's home link in the nav.php page. Remember that we are going to target each page's body id to highlight the active nav link.
    <body id="index">

  • In line 13 we include the nav element.
    <?php include "includes/nav.php" ?>

  • In line 14 we include the header element.
    <?php include "includes/header.php" ?>

  • In line 16 we have a main element that will hold our main content. We will displaying the product categories inside the "left" div, and the products inside the "right" div.
    <main>
    	<div class="left"> 
    		<!-- Displaying the categories -->
    	</div>
    	<div class="right"> 
    		<!-- Displaying the products -->
    	</div>	
    </main>
    		

  • In line 25 we include the footer element.
    <?php include "includes/footer.php" ?>

  • And in line 26 we have a script tag that points to our JavaScript file.
    <script src="javascript/script.js"></script>
  • As i said, every other page that we are going to create will have the same structure. We are using here php as a template system to include the files from the includes folder.

Now lets go and display the categories inside the "left" div element.

Displaying the categories

Copy and paste, or better write, the below code inside the "left" div element.

<div class="left"> <!-- Displaying the categories -->
		<div class="section-title">Product Categories</div>
		<?php $categories = getCategories() ?>
		<?php
			foreach ($categories as $category) {
				?>
					<a href="category.php?category=<?php echo $category['category'] ?>"><?php echo ucfirst($category['category']) ?></a>
				<?php
			}
		?>
	</div>
  • In line 19 we call the getCategories() function, and we store the returned array in the $categories variable.
  • In line 21 we loop through the $categories array, and display every category as a link.
  • href="category.php?category=<?php echo $category['category'] ?>" ... when we click on a category we send a GET request to the category.php page with the name of the category in a "key/value" pair. Something like this: href="category.php?category=books".

We are done with the categories, so go lets display the products.

Displaying the products

Again copy and paste, or write the code below inside the "right" div element.

<div class="right"> <!-- Displaying the products -->
	<div class="section-title">Home page</div>
	<?php $products = getHomePageProducts(4) ?>
	<div class="product">
		<?php
			foreach ($products as $product) {
				?>
					<div class="product-left">
						<img src="<?php echo "products/{$product['image']}" ?>" alt="">
					</div>
					<div class="product-right">
						<p class="title">
							<a href="product.php?title=<?php echo urlencode($product['title']) ?>">
								<?php echo $product['title'] ?>
							</a>
						</p>
						<p class="description"><?php echo $product['description'] ?></p>
						<p class="price"><?php echo $product['price'] ; ?>€</p>
					</div>
				<?php
			}
		?>
	</div>
</div>
  • In line 30 we call the getHomePageProducts(4) function and we pass in as an argument the number of the random products that we want to show in the home page. In our case it is four.
  • In line 33 we loop through the $products array, to fetch each product.
  • In line 36 we display the product's image.
  • In line 40 we display the product's title as a link. This time when we click on the product's title we will send a GET request to the products.php page that holds the product's title.
  • In line 44 we display the product's description.
  • And in line 45 we display the product's price.

And we finished with the index.php file. If you run the file in the browser you will see our home page.

Image of an e-shop's home page

I have to say that the most work is done. The next files are kinda identical to the index.php file.
So let's go and create the category.php file.

The category.php file

This is the category.php file in which we are going to display the products that are listed in a particular category. Actually you can copy and paste the code from the index.php file and add the code from line 2 to 10.

<?php require "php/functions.php" ?>
<?php 
	if(isset($_GET['category'])){
		$cat = $_GET['category'];
	}else{
		header("Location: index.php");
		exit();
	}
?>
<?php $products = getProductsByCategory($cat) ?>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta name="description" content="We have a wide collection of electronics, phones, books, and games">
	<meta name="keywords" content="phones, books, games, electronics">
	<link rel="stylesheet" href="css/styles.css">
	<title>Our Store</title>
</head>
<body id="index">
	<?php include "includes/nav.php" ?>
	<?php include "includes/header.php" ?>

	<main>
		<div class="left">
			<div class="section-title">Product Categories</div>
			<?php $categories = getCategories() ?>
			<?php 
				foreach ($categories as $category) {
					?>
						<a href="category.php?category=<?php echo $category['category'] ?>"><?php echo ucfirst($category['category']) ?></a>
					<?php
				}
			?>
		</div>

		<div class="right">
			<div class="section-title">Products in the <?php echo ucfirst($cat) ?> category</div>
			<div class="product">
				<?php 
					foreach ($products as $product) {
						?>
							<div class="product-left">
								<img src="<?php echo "products/{$product['image']}" ?>" alt="">
							</div>
							<div class="product-right">
								<p class="title">
									<a href="product.php?title=<?php echo urlencode($product['title']) ?>">
										<?php echo $product['title'] ?>
									</a>
								</p>
								<p class="description"><?php echo $product['description'] ?></p>
								<p class="price"><?php echo $product['price'] ; ?>€</p>
								
							</div>
						<?php
					}
				?>
			</div>
		</div>
	</main>
		
	<?php include "includes/footer.php" ?>
	<script src="javascript/script.js"></script>
</body>
</html>
  • Let's see the differences from the index.php file.
  • In line 3 we catch the GET request and the category. If someone messes with the URL and alters the category "key", we send him to the index.php page. For security reasons.
    <?php 
    	if(isset($_GET['category'])){
    		$cat = $_GET['category'];
    	}else{
    		header("Location: index.php");
    		exit();
    	}
    ?>
    		

  • In line 10 we call the getProductsByCategory($cat) function and we pass-in as an argument the category from which we want to fetch its products.
    <?php $products = getProductsByCategory($cat) ?>
  • And that's it. The rest of the page is exactly the same as the index.php file.

Now let create the product.php file.

The product.php file

In the product.php file we will display the product's details when we click on the product's title in the category.php, or in the home page.

<?php require "php/functions.php" ?>
<?php 
	if(isset($_GET['title'])){
		$title = urldecode($_GET['title']);
	}else{
		header("Location: index.php");
		exit();
	}
?>
<?php $product = getProductBytitle($title) ?>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta name="description" content="<?php echo $product[0]['meta_description'] ?>">
	<meta name="keywords" content="<?php echo $product[0]['meta_keywords'] ?>">
	<link rel="stylesheet" href="css/styles.css">
	<title><?php echo $product[0]['title'] ?></title>
	<style>
		main .right .product-left img{
			height: 200px;
		}
		footer{
			position: fixed;
			bottom: 0;
		}
	</style>
</head>
<body id="index">
	<?php include "includes/nav.php" ?>
	<?php include "includes/header.php" ?>

	<main>
		<div class="left">
			<div class="section-title">Product Categories</div>
			<?php $categories = getCategories() ?>
			<?php 
				foreach ($categories as $category) {
					?>
						<a href="category.php?category=<?php echo $category['category'] ?>"><?php echo ucfirst($category['category']) ?></a>
					<?php
				}
			?>
		</div>

		<div class="right">
			<div class="section-title">Product details</div>
			<div class="product">
				<div class="product-left">
					<img src="<?php echo "products/{$product[0]['image']}" ?>" alt="">
				</div>
				<div class="product-right">
					<p class="title"><?php echo $product[0]['title'] ?></p>
					<p class="description"><?php echo $product[0]['description'] ?></p>
					<p class="price"><?php echo $product[0]['price'] ; ?>€</p>
					<button>Buy Now</button>
				</div>
			</div>
		</div>
	</main>
		
	<?php include "includes/footer.php" ?>
	<script src="javascript/script.js"></script>
</body>
</html>
  • Let's see what changes we have in this file:
  • In line 2 we check if there is a GET request which hold the "title" key. If NOT again we redirect the user to the index.php page.
    <?php 
    	if(isset($_GET['title'])){
    		$title = urldecode($_GET['title']);
    	}else{
    		header("Location: index.php");
    		exit();
    	}
    ?>
    <?php $product = getProductBytitle($title) ?>
    		

  • In line 10 we call the getProductBytitle($title) function and pass-in as an argument the product's title.
  • In the description, and keywords meta tags we set the values that we fetch from the products table.
    <meta name="description" content="<?php echo $product[0]['meta_description'] ?>">
    <meta name="keywords" content="<?php echo $product[0]['meta_keywords'] ?>">
    		

  • In line 19 we set the product's title as the page title.
    <title><?php echo $product[0]['title'] ?></title>

  • Setting the description, keywords, and title, are basic SEO actions that we have to make in order search engines can understand the page's content.
  • In line 20 we have some in-page styling. We make the image bigger, and we place the footer at the bottom of the page, because we don't have much content to display.
    <style>
    	main .right .product-left img{
    		height: 200px;
    	}
    	footer{
    		position: fixed;
    		bottom: 0;
    	}
    </style>
    		

  • And last we don't loop through the $products array this time, because there is only one product in the array.
    <div class="product">
    	<div class="product-left">
    		<img src="<?php echo "products/{$product[0]['image']}" ?>" alt="">
    	</div>
    	<div class="product-right">
    		<p class="title"><?php echo $product[0]['title'] ?></p>
    		<p class="description"><?php echo $product[0]['description'] ?></p>
    		<p class="price"><?php echo $product[0]['price'] ; ?>€</p>
    		<button>Buy Now</button>
    	</div>
    </div>
    		

And we are done with the product.php page. Basically we are done with the functionality in our shop. But we have a couple of things left to do, and that is to create the about, and the contact page, and highlight the visited menu link.
This will be quick.

The about page

This is the about.php page. Basically its our starting template, without the main content. Notice in line 17 that we have set the body's id to "about".

<?php require "php/functions.php" ?>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta name="description" content="We have a wide collection of electronics, phones, books, and games">
	<meta name="keywords" content="phones, books, games, electronics">
	<link rel="stylesheet" href="css/styles.css">
	<title>Our Store</title>
	<style>
		footer{
			position: fixed;
			bottom: 0;
		}
	</style>
</head>
<body id="about">
	<?php include "includes/nav.php" ?>
	<?php include "includes/header.php" ?>

	<main>
		<h2>The about page</h2>
	</main>
		
	<?php include "includes/footer.php" ?>

	<script src="javascript/script.js"></script>
</body>
</html>

The contact page

The contact.php page is identical to the about page. Notice again that we set the body id to "contact".

<?php require "php/functions.php" ?>
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta name="description" content="We have a wide collection of electronics, phones, books, and games">
	<meta name="keywords" content="phones, books, games, electronics">
	<link rel="stylesheet" href="css/styles.css">
	<title>Our Store</title>
	<style>
		footer{
			position: fixed;
			bottom: 0;
		}
	</style>
</head>
<body id="contact">
	<?php include "includes/nav.php" ?>
	<?php include "includes/header.php" ?>

	<main>
		<h2>The contact page</h2>
	</main>
		
	<?php include "includes/footer.php" ?>

	<script src="javascript/script.js"></script>
</body>
</html>	

Now that we have created all the pages, there is a last thing that we have to do and that is to use javascript to highlight the visited nav link. So lets go to the JavaScript file.

The script.js file

In the script.js file we have the code that will highlight the visited nav link.

let navLinks = document.querySelectorAll(".links a");
let bodyId = document.querySelector("body").id;

for(let link of navLinks){
	if(bodyId == link.dataset.active){
		link.classList.add("active");
	}
}
  • In line 1 we targeting all a tags that are inside the "links" element, in the nav.php file.
  • Next we are targeting the body id of the page that we are currently on.
  • In line 4 we use a for-of loop to go through the navlinks.
  • Inside the loop we find the data-active attribute that has the same value as the body id, and we use the classList.add() method to add the .active class that we have in the css file. This will add a background color to the visited nav link.

And that's it, we finished this full stack tutorial on how to create dynamic content using PHP and MySQL.
I hope you liked it.

Conclusion

In summary, we saw how PHP and MySQL form a powerful team for creating dynamic web pages.
How to structure the files and folders to be more organized.
How to write the functions that we needed to get the categories, and the products.
We saw how to use foreach loops to cycle through the database data and display them inside HTML tags.
How to use the meta-description and meta-keywords tags so our pages are SEO optimized.
And also we saw how to highlight the visited menu links using a few lines of JavaScript code.

Last Words

Thanks for reading, i hope you find the article helpful.
Please leave a comment if you find any errors, so i can update the page with the correct code.

Source code

If you feel like avoiding all the copying and pasting, you can buy me a coffee and get the source code in a zip file. Get the source code

Buy me a coffee

If you like to say thanks, you can buy me a coffee.

Buy me a coffee with paypal

Comment section

You can leave a comment, it will help me a lot.

Or you can just say hi. 😉