Choose a version here. If you've not already started the tutorial, just go with the latest one.

30 Aug 2014 Preview version Choose
5 Oct 2014 Explicitly adds a specific charset for htmlspecialchars(), and wraps it with a custom function Choose
16 Oct 2014 Updated redirect function to work with vhost subfolders Choose
4 Nov 2014 Minor improvements: added missing docblock, fixed security issue, CSS tweak. Switched hashing method to DEFAULT instead of BCRYPT, this is best practice. Choose
25 Nov 2014 Improve the notes on getting started, in particular choosing a programmer's editor. Added introduction to mod_rewrite rules. Choose
16 Aug 2018 Some bug fixes, remove compatibility library for earlier version of PHP Choose
OK
NB: There are several versions of this tutorial, each successive one containing additional improvements. If you're in the middle of working through it, please check the versions panel above, to ensure you're not mixing code from different versions.

Make your own blog

Post editing

In this chapter, we will build on our new editing functionality, but first, let's simplify the title HTML block by moving the menu into a separate file:

Expand/contract code area Select previous tab
Select next tab
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<div class="top-menu">
<div class="menu-options">
<?php if (isLoggedIn()): ?>
<a href="edit-post.php">New post</a>
|
Hello <?php echo htmlEscape(getAuthUser()) ?>.
<a href="logout.php">Log out</a>
<?php else: ?>
<a href="login.php">Log in</a>
<?php endif ?>
</div>
</div>
<a href="index.php">
<h1>Blog title</h1>
1
 
 
 
 
 
 
 
 
 
 
 
2
3
4
<?php require 'top-menu.php' ?>
<a href="index.php">
<h1>Blog title</h1>
1
2
3
4
5
6
7
8
9
10
11
12
<div class="top-menu">
<div class="menu-options">
<?php if (isLoggedIn()): ?>
<a href="edit-post.php">New post</a>
|
Hello <?php echo htmlEscape(getAuthUser()) ?>.
<a href="logout.php">Log out</a>
<?php else: ?>
<a href="login.php">Log in</a>
<?php endif ?>
</div>
</div>

That change allows us to wire in the menu fragment separately, without the title, so we can use a custom title in the edit page. You'll see that we set the title to "New post" or "Edit post" depending on whether we can find a primary key in the query string.

Expand/contract code area Select previous tab
Select next tab
78
79
80
81
 
 
 
 
 
 
82
83
84
<?php require 'templates/head.php' ?>
</head>
<body>
<?php require 'templates/title.php' ?>
<?php if ($errors): ?>
<div class="error box">
78
79
80
81
82
83
84
85
86
87
88
89
90
<?php require 'templates/head.php' ?>
</head>
<body>
<?php require 'templates/top-menu.php' ?>
<?php if (isset($_GET['post_id'])): ?>
<h1>Edit post</h1>
<?php else: ?>
<h1>New post</h1>
<?php endif ?>
<?php if ($errors): ?>
<div class="error box">

Let's also add in a cancel link in the edit page, to make it easier to abandon an edit:

Expand/contract code area Select previous tab
Select next tab
120
121
122
 
123
124
125
type="submit"
value="Save post"
/>
</div>
</form>
</body>
120
121
122
123
124
125
126
type="submit"
value="Save post"
/>
<a href="index.php">Cancel</a>
</div>
</form>
</body>

On the home page, and for logged-in users only, I next added an edit link against each post, like so:

Expand/contract code area Select previous tab
Select next tab
50
51
52
53
54
55
56
 
 
 
 
 
 
57
58
59
<p>
<?php echo htmlEscape($row['body']) ?>
</p>
<div class="read-more">
<a
href="view-post.php?post_id=<?php echo $row['id'] ?>"
>Read more...</a>
</div>
</div>
<?php endwhile ?>
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<p>
<?php echo htmlEscape($row['body']) ?>
</p>
<div class="post-controls">
<a
href="view-post.php?post_id=<?php echo $row['id'] ?>"
>Read more...</a>
<?php if (isLoggedIn()): ?>
|
<a
href="edit-post.php?post_id=<?php echo $row['id'] ?>"
>Edit</a>
<?php endif ?>
</div>
</div>
<?php endwhile ?>

You may have noticed that the class name (read-more) of the wrapping div was no longer accurate, which is why I changed this to something more generic. As it happens, this section doesn't have any CSS rules specifically attached to it, but it's good to have something for future styles to hook onto).

Lastly, let's make a another nice easy change - there's no point in rendering the login page if we are already logged in. So, after the session is started, if we find we are logged in already, redirect back to the home page.

Expand/contract code area Select previous tab
Select next tab
11
12
13
 
 
 
 
 
 
14
15
16
}
session_start();
// Handle the form posting
$username = '';
11
12
13
14
15
16
17
18
19
20
21
22
}
session_start();
// If we're already logged in, go back home
if (isLoggedIn())
{
redirectAndExit('index.php');
}
// Handle the form posting
$username = '';