Step 1: prerequisite
What do we need to know to make a news script?
Well, actually if you have gone through all the tutorial's chapters until now, you already know everything. But to make sure that you have the required level, I will list what you need to know:
- Work with a database (this is almost indispensable all the time now!)
- Work with forms (go through the corresponding chapter again if needed)
- Work with dates and timestamps
Well, that's all
You will see that combining Database + Forms enables you to make most standard scripts!
Step 2: preparing the script
Now we have to wonder about the functioning of the news script. First of all, a bit of a "new" question: how many PHP pages will we have to create?
Until now, our scripts held on a single page. Here, we could have done it as well, but the page would have become too big and it would have been a useless complication of things.
So we're going to "separate" our script in several pages to clarify our work.
There will be 2 distinct parts for this news script:
- Displaying the news: this script will display the 5 latest news (for instance) on your home page. It is really easy to make (a query in the database and you're done).
Usually, the pieces of news are displayed in your site's home folder (index.php).
- Administration: made of 2 PHP pages from which we can add, edit, delete news. These pages must be protected by .htaccess (see Appendix) to avoid people writing news as a new game. We will create the 2 following pages:
- list_news.php: this page lists all the news saved in the database, and offers you to edit or delete each of them. There might also have a big link for "Add an item of news", which returns to the page redirect_news.php.
Here's a preview of this page:
- compose_news.php: this page is in fact a small form in which we will compose news. We will only need to write the title and the text.
Page preview:
If we make a diagram to represent the files' organization, it looks a bit like this:
As you can see, there will be 4 files in the "admin" folder: .htaccess and .htpassword for the protection by password (explained in the .htaccess appendix), and the 2 administration files: list_news.php and compose_news.php
As for the index.php file, it is the home file of your website and contains the few code lines needed to post the latest news for your guests.
Now let's see the table's structure. I propose that we create a table called "news", which will contain the following fields:
As usual we need an auto-increment "id" field, but also fields for the "title" and "content" of the item of news.
Not failing to mention a "timestamp" field which will allow us to store the timestamp of the moment when the item of news was displayed. As we saw it in the date and time chapter, we will be able to retrieve all the information we want from this timestamp (day, time...)
A few things to know about links:
- The link "Add an item of news" on the page list_news.php is a standard HTML link that leads to redirect_news.php
- On the page list_news.php, if we click on "Edit" for an item of news, it leads to the page redirect_news, but this time with a parameter that indicates the id of the item of news to be modified. If we take the item of news n°3 as an example, the link would be:
redirect_news.php?edit_news=3
Remember to pre-fill the fields "title" and "content" if it is a news modification!
- If we click on "delete" for an item of news on the page list_news.php, it reloads the page list_news.php with a parameter that will indicate an item of news has to be deleted. For instance, the link for the item of news whose id number is 3 will be:
list_news.php?delete_news=3
When we will validate the redirect_news.php form, we'd better come back on the page list_news.php. The form tag will then be:
<form action="list_news.php" method="post">
In list_news.php, we will check if the variables $_POST['title'] and $_POST['content'] exist: it would mean that some pieces of information have to be saved in the database.
I advise you to create a hidden field (input type="hidden") in the form. It will retain the id of the item of news that we are editing. If it's a new piece of news, put 0 as the value.
In this way, when we will process the pieces of information in list_news.php, we will be able to check if it is a fresh piece of news or not:
- The value of the hidden field is 0: it is a fresh item of news. We must perform INSERT INTO
- The value of the hidden field is other than 0: the item of news is being edited. In this case, update the corresponding item of news.
We have finally seen everything... except for 3 little functions you will have to remember to use: nl2br, addslashes and stripslashes.
- nl2br: as we have seen, it allows you to go to the next line automatically in HTML. You have to perform a nl2br just before displaying the news to convert the "Enter" key pressed into <br /> tags.
- addslashes: in fact, it's not always compulsory to use this function depending on your host. But you'd better take the good habit of using it. So, BEFORE saving the title and content of the item of news, apply an addslash to them. It will add \, which will spare you bugs (MySQL particularly dislikes apostrophes).
- stripslashes: this function does the exact opposite. Use it just before you display the title and content of the item of news to avoid having visible backslashes.
You will need this function notably in the page that displays the news to your guests (index.php).
Always bear in mind when you compose a piece of news that you can type HTML code. We won't do htmlspecialchars or mysql_real_escape_string this time because you will be the only one composing your news (you are not going to hack your own website, are you?)
Step 3: your turn!
Let's get cracking!
The script is not particularly complicated. It could have been a lot more, but I preferred to keep only "vital" functions; add, edit, delete a piece of news.
As there are many pages, I advise you to be organized and, ABOVE ALL, to think a bit about your script before getting started coding like maniacs
It will prevent you from getting all confused, which will make your code all the more legible.
I almost forgot a detail: when you
edit an item of news, do not update the timestamp. We just keep the creation date of the item of news.
Step 4: correction
You've been coding relentlessly for 3 days and 3 nights, without even eating, drinking or sleeping...
All this because of me
Come on friends, the time of relief has come!
Now it's time to look at the correction.
If you made it, well done!
If not, well take a leaf out my book, and remember that you are still able to make up for your result in the next practical
OK, we have 3 pages to correct. We will start with the easiest one: index.php, it is your site's homepage where the pieces of news are displayed.
Code: PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head>
<title>Welcome to my site</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
h1, h3
{
text-align:center;
}
h3
{
background-color:black;
color:white;
font-size:0.9em;
margin-bottom:0px;
}
.news p
{
background-color:#CCCCCC;
margin-top:0px;
}
.news
{
width:70%;
margin:auto;
}
</style>
</head>
<body>
<h1>Welcome to my site!</h1>
<p>Here are the latest items of news:</p>
<?php
mysql_connect("localhost", "np", "password");
mysql_select_db("mybase");
// We retrieve the 5 latest items of news
$return = mysql_query('SELECT * FROM news ORDER BY id DESC LIMIT 0, 5');
while ($data = mysql_fetch_array($return))
{
?>
<div class="news">
<h3>
<?php echo $data['title']; ?>
<em> - <?php echo date('m/d/Y H\hi', $data['timestamp']); ?></em>
</h3>
<p>
<?php
// We delete the potential backslashes THEN we create the HTML enter key pressed (<br />)
$content = nl2br(stripslashes($data['content']));
echo $content;
?>
</p>
</div>
<?php
} // End of news loop
?>
</body>
</html>
|
Nothing really surprising: simple query, you've seen worse

We make a loop to display the 5 latest items of news.
I calculated the date from the timestamp: I extracted the date and time.
At last, I made
stripslashes to remove the title and content backslashes.
You can even notice that I combined the
stripslashes function with
nl2br on a line: we sure can
Let's go through the 2 administration pages now.
We'll start with list_news.php. Note that I disabled the news addition and deletion on purpose, to avoid that you go modifying everything
Code: PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head>
<title>News list</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
h2, th, td
{
text-align:center;
}
table
{
border-collapse:collapse;
border:2px solid black;
margin:auto;
}
th, td
{
border:1px solid black;
}
</style>
</head>
<body>
<h2><a href="compose_news.php">Add an item of news</a></h2>
<?php
mysql_connect("localhost", "np", "password");
mysql_select_db("coursphp");
//-----------------------------------------------------
// Check 1 : do we want to post an item of news?
//-----------------------------------------------------
if (isset($_POST['title']) AND isset($_POST['content']))
{
$title = addslashes($_POST['title']);
$content = addslashes($_POST['content']);
// We check if it is a news modification or not
if ($_POST['id_news'] == 0)
{
// It is not a modification, we create a new entry in the table
mysql_query("INSERT INTO news VALUES('', '" . $title . "', '" . $content . "', '" . time() . "')");
}
else
{
// We protect the variable "id_news" to avoid an SQL fault
$_POST['id_news'] = addslashes($_POST['id_news']);
// This is a modification, we only update the title and content
mysql_query("UPDATE news SET title='" . $title . "', content='" . $content . "' WHERE id='" . $_POST['id_news'] . "'");
}
}
//--------------------------------------------------------
// Check 2 : do we want to delete an item of news ?
//--------------------------------------------------------
if (isset($_GET['delete_news'])) // If we ask to delete an item of news
{
// Then we delete the corresponding item of news
// We protect the variable "id_news" to avoid an SQL fault
$_GET['delete_news'] = addslashes($_GET['delete_news']);
mysql_query('DELETE FROM news WHERE id=\'' . $_GET['delete_news'] . '\'');
}
?>
<table><tr>
<th>Edit</th>
<th>Delete</th>
<th>Title</th>
<th>Date</th>
</tr>
<?php
$return = mysql_query('SELECT * FROM news ORDER BY id DESC');
while ($data = mysql_fetch_array($return)) // We make a loop to list the items of news
{
?>
<tr>
<td><?php echo '<a href="compose_news.php?edit_news=' . $data['id'] . '">'; ?>Edit</a></td>
<td><?php echo '<a href="list_news.php?delete_news=' . $data['id'] . '">'; ?>Delete</a></td>
<td><?php echo stripslashes($data['title']); ?></td>
<td><?php echo date('m/d/Y', $data['timestamp']); ?></td>
</tr>
<?php
} // End of loop listing news
?>
</table>
</body>
</html>
|
I remind you that on the test version ("Try out!" link), I disabled the functions add, edit, and delete news on purpose, to avoid some people making trouble with it
If you really want to test this script, create some PHP files on your hard drive
2 checks before displaying the spreadsheet:
- Check 1: we check if we want to post an item of news. If the page redirect_news.php has sent us information, it means we have to post one. First, we apply an addslash to the title and content to avoid bugs like I told you. Then we check the value of id_news:
- If it is 0 => it's a fresh item of news so we perform an INSERT AUTO.
- If it is anything other than 0 => then we modify the item of news corresponding to that id only.
- Check 2: we check if we did not click on a "Delete" link. If that is the case, then we delete the corresponding news.
After, it is a simple loop to list all the items of news' titles in a spreadsheet.
We move on to the last file: compose_news.php
Code: PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" >
<head>
<title>Compose an item of news</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css">
h3, form
{
text-align:center;
}
</style>
</head>
<body>
<h3><a href="list_news.php">Return to the news list</a></h3>
<?php
mysql_connect("localhost", "np", "password");
mysql_select_db("coursphp");
if (isset($_GET['edit_news'])) // If you ask to edit a piece of news
{
// We protect the variable "edit_news" to avoid an SQL fault
$_GET['edit_news'] = mysql_real_escape_string(htmlspecialchars($_GET['edit_news']));
// We retrieve the pieces of information of the corresponding item of news
$return = mysql_query('SELECT * FROM news WHERE id=\'' . $_GET['edit_news'] . '\'');
$data = mysql_fetch_array($return);
// We place the title and the content in simple variables
$title = stripslashes($data['title']);
$content = stripslashes($data['content']);
$id_news = $data['id']; // This variable is used to remember that this is a modification
}
else // We are composing a fresh item of news
{
// The variables $title and $content are empty, since it is a fresh item of news
$title = '';
$content = '';
$id_news = 0; // The value of the variable is 0, so we will remember that it is not a modification
}
?>
<form action="list_news.php" method="post">
<p>Title : <input type="text" size="30" name="title" value="<?php echo $title; ?>" /></p>
<p>
Content :<br />
<textarea name="content" cols="50" rows="10">
<?php echo $content; ?>
</textarea><br />
<input type="hidden" name="id_news" value="<?php echo $id_news; ?>" />
<input type="submit" value="Send" />
</p>
</form>
</body>
</html>
|
First we check if we have to edit an item of news or compose a new one.
We prepare the variables: this way, the fields will be empty if it is a fresh item of news, or will be filled with the text of the old item of news if it is a modification.
Note that the hidden field called "id_news" is very important. It will allow us to know in list_news.php if we are dealing with an
addition or a
modification of news.
Step 5: improve this script!
Just the once won't hurt, I'll tell you that my script is in fact the minimum, and that we could find loads of ways to improve it!
Here are some tracks, so that you can keep on racking your brains:
- The design is as minimalist as usual. You will find it very easy to modify it, as it only requires a simple modification of the HTML code.
- You could add a field in the table "news" that would be called "timestamp_modification". This field would contain the last modification's timestamp.
- Add also a field "nickname" that would contain the nickname of the item of news' author. You might have to add a field in the form (next to the title for instance) to indicate the nicknames.
- It would be nice also if your guests could submit items of news. Create a new page, 'submit_news.php" for instance, accessible to everyone (no .htaccess protection as all your guests must be allowed to submit items of news). The submitted items of news would be automatically registered in the table "news", but not validated (so that they can be displayed only if you give your consent ;)). To handle the news validation, you can add (again) a new field in the table called "valid":
- If its value is 1, the item of news is validated, and displayed.
- If its value is 0, the item of news has not been validated yet, and is not displayed in index.php
- You should also plan to make a paging system, like we did for the Guest book. Indeed, when you'll have 200 items of news, it's going to be a bit heavy to load on your admin page. Besides, if you make a paging system for list_news.php, you could also do one in "records.php" accessible to all your guests, where the old items of news would be visible
- Another possibly interesting thing: make news comments. For this, you will need to create a new table "comments", in which there would be 2 id:
- First, a standard "id", corresponding to the "id" of the comment (using auto-increment).
- A second field, "id_news" that contains the id number of the item of news to which the comment corresponds to.
So to obtain all the comments of the item of news n°3, you would make the SQL request:
SELECT * FROM comments WHERE id_news=3
...And you would obtain only the comments of the item of news n°3
There you go, these are only suggestions. But if you want to get any better, I highly recommend that you try and make some
Don't forget that the forum is at your total disposal if you need any help!