Php: Creating A Blog
- WoogieNoogie
-
WoogieNoogie
- Member since: Jun. 26, 2005
- Offline.
-
- Forum Stats
- Member
- Level 15
- Programmer
Creating a Blog
PART 1: What is going to happen?
This tutorial will teach you how to create your own blog tool through HTML, PHP, MySQL, and HTACCESS. This blog does include comments and an admin panel. This tutorial is very bare-bones...easily customisable through CSS and HTML. This tutorial is not meant for design, just the coding.
This coding is very secure, it goes through PHP and HTACCESS to guarantee nobody will be able to hack your blog without knowing the password.
DISCLAIMER!!!
I use HTML 4.01 Transitional coding. My tags are capatalized, and some tags may not work with XHTML.
PART 2:What will I need?
You will need the following for this tutorial to work:
Support for PHP
Support for .htaccess and .htpasswd
One MySQL database
Basic knowledge of PHP
You won't need alot of space. This is mostly handled in the MySQL database, with the PHP files just spitting it out.
PART 3: Starting, with the MySQL database
Alright, to start, create a database for your blog. For tutorial purposes, I'll call mine user_blog. My username will be user_blogger and my password will be password. The last two will come into play later.
Now, open up your MySQL query window. I'm going to give you the code to just inject directly into the database. Here it is...
CREATE TABLE blog_entries (
id INT NOT NULL AUTO_INCREMENT ,
date TEXT NOT NULL ,
author TEXT NOT NULL ,
title VARCHAR (30 )NOT NULL ,
entry LONGTEXT NOT NULL ,
PRIMARY KEY (id)
);
And now, the table for comments...
CREATE TABLE blog_comments (
pid INT NOT NULL AUTO_INCREMENT ,
id INT NOT NULL ,
author TEXT NOT NULL ,
comment TEXT NOT NULL ,
PRIMARY KEY (pid)
);
That should set up your database, if executed correctly. Let's continue, with the directories set up and the HTACCESS and HTPASSWD files.
PART 4: .htaccess and .htpasswd
Alright, let's set up the directories. Start out with creating your main blog directory, then create a directory inside there called admin. Now, open up the directory that comes BEFORE your public_html directory. When you open it in your file manager, you should see the directory "public_html" as a link. Create a file called .htpasswd with nothing else. That is the filename. Go to this site to get your information to put in this file. In the first box, put admin or another username like that, then put the password in the next box. Then, copy and paste the code into your .htpasswd file. For instance, with a username of admin and a password of password, my .htpasswd file would look like this...
admin:SHA1gRjmWMnwg
Now, create a file in the blog admin directory you made, called .htaccess with nothing else. That is the filename. Put this in the file...
AuthGroupFile /dev/null
AuthName "Blog Admin"
AuthType Basic
AuthUserFile /full/path/to/.htpasswd
Now, /full/path/to/.htpasswd is obviously not an actual path. This is the path from the server. It is usually something like /home/user/domain/.htpasswd. This is different for alot of servers, so it's up to you to find that path to your .htpasswd file.
Alright, now your admin directory is protected. Time to move on to creating the admin panel.
CONTINUED ON NEXT POST
- WoogieNoogie
-
WoogieNoogie
- Member since: Jun. 26, 2005
- Offline.
-
- Forum Stats
- Member
- Level 15
- Programmer
PART 5: The Admin Panel
Now, this is the part of the tutorial that depends on you. This tut is designed to help you code a blog, the customising and style is up to you. Don't worry, if you have a stylesheet, this will be extremely easy to style.
In total, excluding the .htaccess file, there are 13 files. Each file explanation will be separated by the filename, underlined and bolded. Create the filename given, then you can copy and paste the code given into your file, followed by your customisation.
index.php
Alright, for this file, I'm just going to use simple header tags and links to the other pages.
<H3><A HREF="post.php">Post a blog</A></H3>
<H3><A HREF="edit.php">Edit a blog</A></H3>
<H3><A HREF="delete.php">Delete a blog</A></H3>
<H3><A HREF="comment.php">Delete a comment</A></H3>
con.php
To make it easier on everyone, I'll give you the coding for opening and closing the MySQL connection, then require those files on the rest of the files. Confused? You shouldn't be...but if you are, don't worry about it. Just follow my lead. Remember, my database name is user_blog, my username is user_blogger and my password is password.
<?php
$conn = mysql_connect ("localhost", "user_blogger", "password");
mysql_select_db ("user_blog");
?>
discon.php
Now, let's make a file to close that connection.
<?php
mysql_close($conn);
?>
Well, that was easy.
post.php
Alright, this is one of two posting pages. This one collects the data from user input, then sends it to the second one for processing. It's a simple HTML form.
<FORM ACTION="process.php" METHOD="post">
<H3>Blog Title</H3>
<INPUT TYPE="text" SIZE="30" NAME="title">
<BR><BR>
<H3>Blog Author</H3>
<INPUT TYPE="text" SIZE="30" NAME="author">
<BR>
<H3>Blog Text</H3>
<TEXTAREA STYLE="width: 300px; height:200px" NAME="text"></TEXTAREA>
<BR><BR>
<INPUT TYPE="submit" VALUE="Post!">
</FORM>
process.php
This is the first file that actually requires PHP to work. I'm going to use a simple if else statement to see if the user has filled out all the fields, then act accordingly.
<?php
if ($_POST['title'] == '' || $_POST['text'] == '' || $_POST['author']) {
echo "Please fill out form elements.";
die();
} else {
require("con.php");
$title = $_POST['title'];
$text = $_POST['text'];
$author = $_POST['author'];
$date = date("l, F d, Y");
mysql_query ("INSERT INTO `blog_entries` ( `id` , `date` , `author` , `title` , `entry` )
VALUES (
'', '$date', '$author', '$title', '$text'
);");
echo "Post successful!";
require("discon.php");
}
?>
Something you can change in this file without harming anything is the date() function. Just change the phrase date("l, F d, Y") to another phrase, using syntax from the PHP date() Manual.
So now, we've made a way to post onto the MySQL database. Let's make a way to edit those entries.
edit.php
Page one of three in the edit series. This page will display all the topic titles in the database, with a link to edit after each one. This link will send them to the editing page, which will then send them to the processing page.
<?php
require("con.php");
$qResult = mysql_query("SELECT * FROM blog_entries ORDER BY id DESC");
$counting = mysql_num_rows($qResult);
if ($counting == 0) {
echo "<H2>No blog posts.</H2>";
}
while($row = mysql_fetch_array($qResult)) {
$title = $row['title'];
$id = $row['id'];
echo "
$title [<A HREF='editpost.php?id=$id'>Edit</A>]
<BR>";
}
require("discon.php");
?>
editpost.php
This page displays the comment title and entry in textboxes, which are editable. It gets the post that the user selected from the previous page.
<?php
$id = $_GET['id'];
require("con.php");
$qResult = mysql_query("SELECT * FROM blog_entries ORDER BY id DESC");
$row = mysql_fetch_array($qResult);
$title = $row['title'];
$id = $row['id'];
$post = $row['entry'];
?>
<FORM ACTION="editaction.php?id=<?php echo $id; ?>" METHOD="post">
<H3>Blog Title</H3>
<INPUT TYPE="text" SIZE="30" NAME="title" VALUE="<?php echo $title; ?>">
<BR><BR>
<H3>Blog Text</H3>
<TEXTAREA STYLE="width: 300px; height:200px" NAME="text">
<?php echo $post; ?>
</TEXTAREA>
<BR><BR>
<INPUT TYPE="submit" VALUE="Update!">
</FORM>
<?php
require("discon.php");
?>
editaction.php
This page gets the information from the previous page and updates the MySQL database accordingly.
<?php
$id = $_GET['id'];
$title = $_POST['title'];
$post = $_POST['text'];
require("con.php");
$qResult = mysql_query("UPDATE blog_entries SET title='$title' , entry='$post' WHERE id='$id'");
require("discon.php");
echo "Post edited successfully!";
?>
delete.php
Time to move on to deleting topics...when editing just isn't good enough. Page one of two. This page displays all the topic titles, with a delete link after them.
<?php
require("con.php");
$qResult = mysql_query("SELECT * FROM blog_entries ORDER BY id DESC");
$counting = mysql_num_rows($qResult);
if ($counting == 0) {
echo "<H2>No blog posts.</H2>";
}
while($row = mysql_fetch_array($qResult)) {
$title = $row['title'];
$id = $row['id'];
echo "
$title [<A HREF='deleting.php?id=$id'>Delete</A>]
<BR>";
}
require("discon.php");
?>
deleting.php
Delete the topic the user just selected.
<?php
$id = $_GET['id'];
require("con.php");
mysql_query("DELETE FROM blog_entries WHERE id=$id");
mysql_query("DELETE FROM blog_comments WHERE id=$id");
require("discon.php");
echo "Post deleted!";
?>
comment.php
With every comment system comes spam. Here's a way to delete those comments on your blog. Page one of three. This one shows the blog titles, like the others, followed by a view comments link.
<?php
require("con.php");
$qResult = mysql_query("SELECT * FROM blog_entries ORDER BY id DESC");
$counting = mysql_num_rows($qResult);
if ($counting == 0) {
echo "<H2>No blog posts.</H2>";
}
while($row = mysql_fetch_array($qResult)) {
$title = $row['title'];
$id = $row['id'];
echo "
$title [<A HREF='viewcom.php?id=$id'>View Comments</A>]
<BR>";
}
?>
- WoogieNoogie
-
WoogieNoogie
- Member since: Jun. 26, 2005
- Offline.
-
- Forum Stats
- Member
- Level 15
- Programmer
viewcom.php
Let's see all the comments on that blog post that the user selected.
<?php
require("con.php");
$id = $_GET['id'];
$qResult = mysql_query("SELECT * FROM blog_comments WHERE id=$id ORDER BY pid DESC");
$counting = mysql_num_rows($qResult);
if ($counting == 0) {
echo "<H2>No comments.</H2>";
}
echo "<H3>";
while($row = mysql_fetch_array($qResult)) {
$pid = $row['pid'];
$author = $row['author'];
$post = $row['post'];
echo "
$author wrote, "$post" [<A HREF='delcom.php?id=$pid'>Delete Comment</A>]
<BR>
";
}
echo "</H3>";
require("discon.php");
?>
delcom.php
And finally, delete the comment from the database.
<?php
$id = $_GET['id'];
require("con.php");
mysql_query("DELETE FROM blog_comments WHERE pid=$id");
require("discon.php");
echo "Comment deleted!";
?>
Alright! Admin panel is done! Secured by HTACCESS and coded through PHP to MySQL. Let's build the public blog now.
PART 6: Public View, Comments, and Admin Login Page
Okay, go to your main blog directory. Let's finish this sucka up. 5 more pages to go! Come on, you can do it!
index.php
This page will display the 6 most recent blog posts. There will be another page for archived posts. Remember, you can edit the layout alot.
<?php
$conn = mysql_connect("localhost", "user_blogger", "password");
$data = mysql_select_db("user_blog");
$qResult = mysql_query("SELECT * FROM blog_entries ORDER BY id DESC LIMIT 5");
$counting = mysql_num_rows($qResult);
if ($counting == 0) {
echo "<H2>No blog posts.</H2>";
}
while($row = mysql_fetch_array($qResult))
{
$postTitle = $row['title'];
$postId = $row['id'];
$postAuthor = $row['author'];
$postDate = $row['date'];
$post = $row['entry'];
echo "<H2>$postTitle</H2>
<H4>Posted: $postDate by $postAuthor</H4>
<P CLASS='blogbody'>$post</P>
<H4>";
$queryc = mysql_query("SELECT * FROM blog_comments WHERE id = $postId");
$comNum = mysql_num_rows($queryc);
echo $comNum;
echo" Comments</H4>
<H4><A HREF='viewpost.php?id=";
echo $postId;
echo "'>View/Add Comments</A></H4>
<HR>
";
}
mysql_close($conn);
?>
One thing about this page, and others outside the admin directory. I connected to my database in the file, instead of making a con.php file. I felt this was a little more safe for these files outside the admin panel.
archive.php
Here's where the rest of the blog posts go, besides the recent 6.
<?php
$conn = mysql_connect("localhost", "user_blogger", "password");
$data = mysql_select_db("user_blog");
$qResult = mysql_query("SELECT * FROM blog_entries ORDER BY id DESC LIMIT 5, 999");
$counting = mysql_num_rows($qResult);
if ($counting == 0) {
echo "<H2>No archived posts</H2>";
}
while($row = mysql_fetch_array($qResult))
{
$postTitle = $row['title'];
$postId = $row['id'];
$postAuthor = $row['author'];
$postDate = $row['date'];
$post = $row['entry'];
echo "<H2>$postTitle</H2>
<H4>Posted: $postDate by $postAuthor</H4>
<P CLASS='blogbody'>$post</P>
<H4>";
$queryc = mysql_query("SELECT * FROM blog_comments WHERE id = $postId");
$comNum = mysql_num_rows($queryc);
echo $comNum;
echo" Comments</H4>
<H4><A HREF='viewpost.php?id=";
echo $postId;
echo "'>View/Add Comments</A>";
}
mysql_close($conn);
mysql_close($queryc);
?>
viewpost.php
Here's where comments come in. This page calls on the selected blog and spits out all the comments with it. Don't forget to customise! This page gets a little more complicated, because two tables are being accessed.
<?php
$conn = mysql_connect("localhost", "user_blogger", "password");
$data = mysql_select_db("user_blog");
$postId = $_GET['id'];
$qResult = mysql_query("SELECT * FROM blog_entries WHERE id = '$postId'");
$row = mysql_fetch_array($qResult);
$postTitle = $row['title'];
$postDate = $row['date'];
$post = $row['entry'];
$id = $row['id'];
echo "<H2>$postTitle</H2>
<H4>Posted: $postDate</H4>
<P CLASS='blogbody'>$post</P>
<HR>
";
$determine = mysql_query("SELECT * FROM blog_comments WHERE id = $postId");
$countit = mysql_num_rows($determine);
$cResult = mysql_query("SELECT * FROM blog_comments WHERE id = $postId ORDER BY id DESC LIMIT $countit");
if ($countit == 0){
echo "<H4>No comments</H4>";
}
while($crow = mysql_fetch_array($cResult))
{
$cAuthor = $crow['author'];
$cPost = $crow['post'];
$name = "$cAuthor";
$comment = "$cPost";
echo "<H4>$name said:</H4>
<P CLASS='comments'>$comment</P>
";
mysql_close($conn);
mysql_close($determine);
}
?>
<FORM ACTION="comment.php?id=<?php echo $_GET['id']; ?>" METHOD="post">
<H4>Author Name</H4>
<INPUT TYPE="text" SIZE="30" NAME="name">
<BR>
<H4>Comment</H4>
<TEXTAREA STYLE="width: 250px; height:150px" NAME="text"></TEXTAREA>
<BR><BR>
<INPUT TYPE="submit" VALUE="Post!">
</FORM>
comment.php
The processing page for the comments added from the form in the last page.
<?php
if ($_POST['name'] == '' || $_POST['text'] == '') {
echo "Fill out the form.";
die();
} else {
$conn = mysql_connect ("localhost", "user_blogger", "password");
mysql_select_db ("user_blog");
$name = $_POST['name'];
$text = $_POST['text'];
$id = $_GET['id'];
mysql_query ("INSERT INTO `blog_comments` ( `id` , `pid` , `author` , `post` )
VALUES (
'$id', '', '$name', '$text'
);");
mysql_close($conn);
echo "Comment posted!";
?>
admin.php
This is the page with a simple password to login to the admin panel.
<?php
$pass = $_POST['password'];
if ($pass) {
echo "<SCRIPT TYPE='text/javascript'>
window.location = 'http://admin:$pass@www.yoursite.com/admin
/';
</SCRIPT>";
} else {
?>
<FORM ACTION="admin.php" METHOD="post">
Password:
<BR>
<INPUT TYPE="password" NAME="password" LENGTH="20">
<INPUT TYPE="submit" VALUE="Login!" NAME="submit">
</FORM>
<?php
}
?>
In the URL after window.location, change "admin" to the username in your HTPASSWD file.
STEP 7: Finishing touches
These are just a few comments I thought I'd add at the end.
At the end of any page where it seems fit, be sure to put a link to the admin login page, a link to the archive, or a link to the main blog page.
If you have a basic knowledge of PHP you will know where you can and cannot use HTML around these scripts.
And that's it! Let me know if you see any flaws and critique the heck out of this thing.
- DFox
-
DFox
- Member since: Aug. 9, 2003
- Offline.
-
- Forum Stats
- Member
- Level 30
- Blank Slate
Wow! Very good tutorial. I can see you put a lot of work into this.
Very nice job.
- WoogieNoogie
-
WoogieNoogie
- Member since: Jun. 26, 2005
- Offline.
-
- Forum Stats
- Member
- Level 15
- Programmer
Whoops, found a mistake. Forgot to add something.
Under comment.php
$name = $_POST['name'];
$text = $_POST['text'];
Should be
$name = htmlspecialchars($_POST['name']);
$text = htmlspecailchars($_POST['text']);
- Taylor
-
Taylor
- Member since: Aug. 19, 2003
- Offline.
-
- Forum Stats
- Member
- Level 09
- Blank Slate
- Taylor
-
Taylor
- Member since: Aug. 19, 2003
- Offline.
-
- Forum Stats
- Member
- Level 09
- Blank Slate
- Jams44
-
Jams44
- Member since: Nov. 8, 2004
- Offline.
-
- Forum Stats
- Member
- Level 07
- Blank Slate
- Khao
-
Khao
- Member since: Sep. 20, 2003
- Offline.
-
- Forum Stats
- Member
- Level 20
- Blank Slate
At 2/1/06 10:39 PM, PillowBiter wrote: test
is this just me or I've seen you doing testes around this forum a lot of time these days..
anyway very good tutorial :)
- Taylor
-
Taylor
- Member since: Aug. 19, 2003
- Offline.
-
- Forum Stats
- Member
- Level 09
- Blank Slate
At 2/1/06 10:43 PM, Khao wrote:At 2/1/06 10:39 PM, PillowBiter wrote: testis this just me or I've seen you doing testes around this forum a lot of time these days..
anyway very good tutorial :)
=)
cURL. =D
'twas posted on by a script/bot. Didn't mean to make it so obvious.
- Khao
-
Khao
- Member since: Sep. 20, 2003
- Offline.
-
- Forum Stats
- Member
- Level 20
- Blank Slate
At 2/1/06 10:49 PM, PillowBiter wrote:
cURL. =D
'twas posted on by a script/bot. Didn't mean to make it so obvious.
lolll well you could make it post things other than "test" like "this thread makes me wet in my special places"
- byteofthat
-
byteofthat
- Member since: Jun. 7, 2004
- Offline.
-
- Forum Stats
- Member
- Level 14
- Programmer
I must say, I am impressed. It's not often you see things like this on NG, I suppose. Good job, for sure.
- WoogieNoogie
-
WoogieNoogie
- Member since: Jun. 26, 2005
- Offline.
-
- Forum Stats
- Member
- Level 15
- Programmer
Thanks for the positive feedback, everyone.
- Toast
-
Toast
- Member since: Apr. 2, 2005
- Offline.
-
- Forum Stats
- Member
- Level 09
- Blank Slate
Very long tutorial, I'll have a look at it more in depth later.
What does 'ORDER BY id DESC' do?
- authorblues
-
authorblues
- Member since: Jun. 21, 2005
- Offline.
-
- Forum Stats
- Member
- Level 12
- Blank Slate
At 2/2/06 06:45 AM, -Toast- wrote: What does 'ORDER BY id DESC' do?
puts the selected pages in descending order based on the "id" column
- Toast
-
Toast
- Member since: Apr. 2, 2005
- Offline.
-
- Forum Stats
- Member
- Level 09
- Blank Slate
At 2/2/06 06:45 AM, -Toast- wrote: Very long tutorial, I'll have a look at it more in depth later.
What does 'ORDER BY id DESC' do?
Nevermind, I read a w3schools tutorial about it.
- juraj
-
juraj
- Member since: May. 15, 2004
- Offline.
-
- Forum Stats
- Member
- Level 29
- Blank Slate
At 2/1/06 10:49 PM, PillowBiter wrote: =)
cURL. =D
'twas posted on by a script/bot. Didn't mean to make it so obvious.
Making a depositing bot, eh? ;)
- NinoGrounds
-
NinoGrounds
- Member since: Nov. 28, 2005
- Offline.
-
- Forum Stats
- Member
- Level 19
- Programmer
At 2/2/06 02:15 PM, juraj wrote:At 2/1/06 10:49 PM, PillowBiter wrote: =)Making a depositing bot, eh? ;)
cURL. =D
'twas posted on by a script/bot. Didn't mean to make it so obvious.
What an awesome Tutorial
- Greeley
-
Greeley
- Member since: Aug. 30, 2005
- Offline.
-
- Forum Stats
- Member
- Level 13
- Blank Slate
Way to go with this man... I'm thinking of coding up my own personal blog and I may have to use this to help me out. Good effort man!
- WoogieNoogie
-
WoogieNoogie
- Member since: Jun. 26, 2005
- Offline.
-
- Forum Stats
- Member
- Level 15
- Programmer
At 2/3/06 05:54 PM, Greeley wrote: Way to go with this man... I'm thinking of coding up my own personal blog and I may have to use this to help me out. Good effort man!
Thanks ;)
- Rantzien
-
Rantzien
- Member since: Jan. 27, 2005
- Offline.
-
- Forum Stats
- Member
- Level 15
- Blank Slate
Seems to be an end bracket ( } ) missing in comment.php too. Great tutorial anyway!
- WoogieNoogie
-
WoogieNoogie
- Member since: Jun. 26, 2005
- Offline.
-
- Forum Stats
- Member
- Level 15
- Programmer
At 2/26/06 08:58 AM, Rantzien wrote: Seems to be an end bracket ( } ) missing in comment.php too. Great tutorial anyway!
Ah..yes, I seem to have forgotten that last bracket to close the else statement. Thanks for pointing that out!
Also, someone pointed out that in editpost.php the line
$qResult = mysql_query("SELECT * FROM blog_entries ORDER BY id DESC");
should be
$qResult = mysql_query("SELECT * FROM blog_entries WHERE id = $id");
- DannyIsOnFire
-
DannyIsOnFire
- Member since: Apr. 14, 2005
- Offline.
-
- Forum Stats
- Member
- Level 21
- Movie Buff
Great tutorial.
This can be used as a news post thingy yeah ?
If so im gonna put it on my site some time this week.
Thanks man =)
- Monodi
-
Monodi
- Member since: Aug. 14, 2005
- Offline.
-
- Forum Stats
- Member
- Level 22
- Blank Slate
- seel
-
seel
- Member since: Jun. 27, 2005
- Offline.
-
- Forum Stats
- Member
- Level 21
- Musician
At 2/1/06 10:27 PM, WoogieNoogie wrote: Whoops, found a mistake. Forgot to add something.
Under comment.php
$name = $_POST['name'];Should be
$text = $_POST['text'];
$name = htmlspecialchars($_POST['name']);
$text = htmlspecailchars($_POST['text']);
Or it should be
$name = addslashes(htmlspecialchars($_POST['name']
));
$text = addslashes(htmlspecialchars($_POST['text']
));
anyway good tut :)
- lobotomized89
-
lobotomized89
- Member since: Jan. 18, 2006
- Offline.
-
- Forum Stats
- Member
- Level 13
- Blank Slate
Also in the process.php instead of:
if ($_POST['title'] == '' || $_POST['text'] == '' || $_POST['author'] )
it should be:
if ($_POST['title'] == '' || $_POST['text'] == '' || $_POST['author'] == '')
Great tutorial man. Very useful.
- Mister-Mind
-
Mister-Mind
- Member since: Jul. 1, 2006
- Offline.
-
- Forum Stats
- Member
- Level 07
- Blank Slate
At 2/1/06 10:23 PM, DFox wrote: Wow! Very good tutorial. I can see you put a lot of work into this.
Very nice job.
seconded!
- WoogieNoogie
-
WoogieNoogie
- Member since: Jun. 26, 2005
- Offline.
-
- Forum Stats
- Member
- Level 15
- Programmer
Thanks...however, it's in need of a HUGE update. I don't use half of these things anymore.
- DrRobot
-
DrRobot
- Member since: Mar. 12, 2006
- Offline.
-
- Forum Stats
- Member
- Level 18
- Game Developer
I do not have this public_html directory you speak of.
Help Please
- harryjarry
-
harryjarry
- Member since: May. 15, 2005
- Offline.
-
- Forum Stats
- Member
- Level 57
- Blank Slate
At 11/5/06 01:13 PM, DrRobot wrote: I do not have this public_html directory you speak of.
Help Please
It is the directory where you also have your index page (you also have projects.html and about.html in it).
So anything in that directory and any directories inside of that one.






