How to Create an Object-Oriented Blog Using PHP
In this post, we are going to extend our knowledge of PHP and MySQL a step further by creating a simple blog. While there are countless excellent free blog platforms available on the market, the purpose of this tutorial is to explore the process of creating a blog website to learn advanced database structure techniques and how to use data more efficiently by leveraging object-oriented programming in PHP.
For this tutorial, I assume that you have some basic understanding of PHP, MySQL, and XHTML.
Walk Through the Database Structure
Before we move into our MySQL client and start creating our tables, we should lay out what we want in our blog. The obvious thing we need to include is blog posts, and each post should contain a title, the post itself, an author, and the date it was posted on.
Now, we could just create one table to hold that information and most likely succeed in creating a basic blog. However, with just one table, we will not have as much control over our data. For example, we could store the name of the author in the same table as the blog post, but what if we also want to store the author's email? Adding another field to our table would be the obvious solution.
The problem arises when, down the road, you want to change the email address of that author. Now you have to change it for every single blog post that person has created.
So what we are going to do is create a separate table called people
, where we can store all the information about the author, such as the email, URL, name, and a unique ID. Then, in our blog_posts
table, we will reference the person by that person's unique ID. This ID is referred to as a foreign key, and the relationship between the people
table and the blog_posts
table is called a one-to-many relationship since the same person can create multiple blog posts.
Apart from this, we also want to provide the feature of attaching a tag to each blog post. A blog post could have more than one tag attached to it, so it's a one-to-many relationship. To achieve this, we need to create another table, which can be named something like blog_post_tags
. This table will hold two foreign keys: one for the blog post's ID and the other for the ID of the tag that the blog post is associated with. In this way, we can assign as many tags as we want to a blog post and still be able to edit the information about that specific tag across all posts with a simple MySQL query. Of course, we'll also need the tags
table, which holds the actual tags, and it has two fields: id and name.
Now that we have outlined what our database structure should look like, let's go ahead and create it. I'll be using PhpMyAdmin since it's the most widely used MySQL admin client and is easy to use. There are a few different naming conventions that you can use when you create your database, table, and field names. I like to use all lowercase and underscores in place of spaces. You should avoid using uppercase characters since that's considered to be one of the best practices.
If you don't have PHP and MySQL on your system or a server that can run it, I recommend you download a standalone install of Apache, PHP, and MySQL. MAMP is good for Macs, and WAMP is good for PCs.
Create a Database and Tables
In this section, we'll go ahead and create our database and the necessary tables for our blog website.
Let's go ahead and create a new database called code_tutsplus_blog
. You can either use PhpMyAdmin or the following MySQL command in the MySQL CLI to create a new database:
1 |
CREATE DATABASE code_tutsplus_blog; |
Once a database is created, we can proceed to create the necessary tables.
Create a blog_posts
Table
Go ahead and run the following command to create the blog_posts
table.
1 |
CREATE TABLE blog_posts ( |
2 |
id INT PRIMARY KEY AUTO_INCREMENT, |
3 |
title VARCHAR(255), |
4 |
post TEXT, |
5 |
author_id INT, |
6 |
date_posted DATE |
7 |
);
|
The blog_posts
table has five fields: id
, title
, post
, author_id
, and date_posted
.
We've created the id
field as the primary key and set it to auto-increment. It'll generate a unique identifier for each entry. Whenever we add a new post, it will assign a sequential number, starting from one and incrementing with each subsequent post.
Next, we also need to define the data types for each field. The id
field is set to be of the INT
(short for integer) type, as it should only store numerical values, and we've set the maximum length to 11. The title
field is defined as the VARCHAR
type, with a maximum length of 255. The post
field is defined as the TEXT
type. The author_id
field has the same data type as the id
field. Lastly, the date_posted
field is defined as the DATE
type.
Create a people
Table
Let's go ahead and create our next table, called people
. We are not calling it authors because down the road we might want to create the ability to register and post comments, and those people would not be considered authors.
Go ahead and run the following command to create the people
table.
1 |
CREATE TABLE people ( |
2 |
id INT PRIMARY KEY AUTO_INCREMENT, |
3 |
first_name VARCHAR(255), |
4 |
last_name VARCHAR(255), |
5 |
url VARCHAR(255), |
6 |
email VARCHAR(255) |
7 |
);
|
The id
field is defined as an INT
, set as the primary key, and configured to auto-increment, similar to the id
field in the blog_posts
table. The first_name
, last_name
, url
, and email
fields are set as VARCHAR
, with a maximum length of 255.
Create a tags
Table
Go ahead and run the following command to create the tags
table.
1 |
CREATE TABLE tags ( |
2 |
id INT PRIMARY KEY AUTO_INCREMENT, |
3 |
name VARCHAR(255) |
4 |
);
|
As we did before, the id
field is defined as INT
, set as the primary key, and configured to auto-increment. The name
field is defined as VARCHAR
, with a maximum length of 255.
Create a blog_post_tags
Table
Go ahead and run the following command to create the blog_post_tags
table.
1 |
CREATE TABLE blog_post_tags ( |
2 |
blog_post_id INT, |
3 |
tag_id INT |
4 |
);
|
Both fields are defined as INT
type.
So that's it for creating our database and tables. From the next section onwards, we'll start implementing our blog website with PHP.
How Objects Work in PHP OOP
In this section, we'll briefly discuss OOP in PHP.
Object-oriented programming, commonly referred to as OOP, is an approach which helps you to develop complex applications in a way that's easy to scale and maintain over the long term. In the world of OOP, real-world entities such as Person
, Car
, or Animal
are treated as objects. In object-oriented programming, you interact with your application by using objects. This contrasts with procedural programming, where you primarily interact with functions and global variables.
In OOP, there's the concept of class, which is used to model or map a real-world entity to a template of data (properties) and functionality (methods). An object is an instance of a class, and you can create multiple instances of the same class. For example, there is a single Person
class, but many person objects can be instances of this class—dan
, zainab
, hector
, etc.
The class defines properties. For example, for the Person
class, we might have name
, age
, and phoneNumber
. Then, each person object will have its own values for those properties.
You can also define methods in the class that allow you to manipulate the values of object properties and perform operations on objects. As an example, you could define a save
method which saves the object information to a database.
Before we delve into our PHP code, we need to establish our file and folder structure. For this tutorial, we will create an index.php file in the root folder. Additionally, we will create an includes folder to store our CSS style sheet, JavaScript files, connection.php file, and blogpost.php file.
Create a BlogPost
Class
In this section, we're going to create the BlogPost
class, which is the backbone of our blog application.
Go ahead and create the blogpost.php file in the includes folder with the following contents.
1 |
<?php
|
2 |
class BlogPost |
3 |
{
|
4 |
private $conn; |
5 |
|
6 |
public function __construct($conn) |
7 |
{
|
8 |
$this->conn = $conn; |
9 |
}
|
10 |
|
11 |
public function getBlogPosts() |
12 |
{
|
13 |
$query = "SELECT blog_posts.id, blog_posts.title, blog_posts.post, people.first_name, people.last_name, blog_posts.date_posted |
14 |
FROM blog_posts
|
15 |
INNER JOIN people ON blog_posts.author_id = people.id"; |
16 |
|
17 |
$result = $this->conn->query($query); |
18 |
$blogPosts = $result->fetch_all(MYSQLI_ASSOC); |
19 |
|
20 |
return $blogPosts; |
21 |
}
|
22 |
|
23 |
public function getTagsForBlogPost($blogPostId) |
24 |
{
|
25 |
$query = "SELECT tags.name |
26 |
FROM tags
|
27 |
INNER JOIN blog_post_tags ON tags.id = blog_post_tags.tag_id
|
28 |
WHERE blog_post_tags.blog_post_id = ?"; |
29 |
|
30 |
$stmt = $this->conn->prepare($query); |
31 |
$stmt->bind_param('i', $blogPostId); |
32 |
$stmt->execute(); |
33 |
|
34 |
$result = $stmt->get_result(); |
35 |
$tags = []; |
36 |
while ($row = $result->fetch_assoc()) { |
37 |
$tags[] = $row['name']; |
38 |
}
|
39 |
|
40 |
return $tags; |
41 |
}
|
42 |
|
43 |
public function getBlogPostById($blogPostId) |
44 |
{
|
45 |
$query = "SELECT blog_posts.id, blog_posts.title, blog_posts.post, people.first_name, people.last_name, blog_posts.date_posted |
46 |
FROM blog_posts
|
47 |
INNER JOIN people ON blog_posts.author_id = people.id
|
48 |
WHERE blog_posts.id = ?"; |
49 |
|
50 |
$stmt = $this->conn->prepare($query); |
51 |
$stmt->bind_param('i', $blogPostId); |
52 |
$stmt->execute(); |
53 |
|
54 |
$result = $stmt->get_result(); |
55 |
$blogPost = $result->fetch_assoc(); |
56 |
|
57 |
return $blogPost; |
58 |
}
|
59 |
}
|
60 |
?>
|
In this class, we'll use the mysqli
extension for MySQL database connectivity, which we'll see in a moment. The constructor expects a mysqli
connection object. The __construct
method is called a constructor, and it is automatically called whenever we make a new instance of the BlogPost
object. Next, we've defined a few methods for different purposes.
The getBlogPosts
method retrieves all the blog posts from the blog_posts
table, joining the people
table to retrieve author information.
The getTagsForBlogPost
method retrieves the tags associated with a specific blog post, using a prepared statement and parameter binding to prevent SQL injection.
Finally, the getBlogPostById
method allows you to retrieve a specific blog post by its ID. It extends the existing blog_posts
and people
table join query with an additional WHERE
clause to filter the results based on the provided $blogPostId
.
So we've created our BlogPost
class, which we can use to retrieve blog posts from the database and display it, and that's what our next section is all about.
Display Blog Posts
Set Up a Database Connection
Go ahead and create the connection.php file in the includes folder with the following contents.
1 |
<?php
|
2 |
$servername = "localhost"; |
3 |
$username = "your_username"; |
4 |
$password = "your_password"; |
5 |
$database = "your_database"; |
6 |
|
7 |
|
8 |
$conn = new mysqli($servername, $username, $password, $database); |
9 |
|
10 |
if ($conn->connect_error) { |
11 |
die("Connection failed: " . $conn->connect_error); |
12 |
}
|
Replace localhost
, your_username
, your_password
, and your_database
with your actual database credentials. It establishes a connection to the MySQL server and stores it in the $conn
object.
Create an index.php
File
Go ahead and create the index.php file with the following contents.
1 |
<?php
|
2 |
require "includes/connection.php"; |
3 |
require "includes/blogpost.php"; |
4 |
|
5 |
$objBlogPost = new BlogPost($conn); |
6 |
$arrPosts = $objBlogPost->getBlogPosts(); |
7 |
?>
|
8 |
<div id="main"> |
9 |
<h1>My Simple Blog</h1> |
10 |
<div id="blogPosts"> |
11 |
<?php
|
12 |
if (count($arrPosts)) { |
13 |
foreach ($arrPosts as $post) { |
14 |
$tags = implode(",", $objBlogPost->getTagsForBlogPost($post['id'])); |
15 |
|
16 |
echo "<div class='post'>"; |
17 |
echo "<h1>" . $post['title'] . "</h1>"; |
18 |
echo "<p>" . $post['post'] . "</h1>"; |
19 |
echo "<span class='footer'>Posted By: " . $post['first_name'] . " Posted On: " . $post['date_posted'] . " Tags: " . $tags . "</span>"; |
20 |
echo "</div>"; |
21 |
}
|
22 |
}
|
23 |
?>
|
24 |
</div>
|
25 |
</div>
|
Firstly, we include two required files, connection.php and blogpost.php, using the require
statement.
Then, we are creating an instance of the BlogPost
class by passing the $conn
object (database connection) as a parameter. It allows us to interact with the blog post data using the methods defined in the BlogPost
class.
Next, we've used the getBlogPosts
method of the BlogPost
class, which fetches blog posts from the database and returns them as an associative array.
Finally, we iterate over the array records using the foreach
construct and display the records by formatting it with XHTML.
So that's how you can build a listing page with the help of the BlogPost
class.