Blog Post Page
Pre-Reqs
- Understanding of URL query string parameters and the $_GET super global array in PHP
- Understanding of 404 pages, and the header() function in PHP (look it up on the web, or look ahead in chapter 11 of the book)
- Understanding of SQL injection attacks
In this step, we'll create a single PHP page that can display any blog post (very dynamic!).
Before we start on that page, we'll need to add some more code to our PageDataAccess class.
Updating the PageDataAccess class
-
Open PageDataAccess.inc.php and add this method to the class.
- Make sure you understand the code!
- Note the parameter, and the return value (depending on how the code executes, the return value could be different).
- Note that we are NOT using htmlentities() on the content column. We'll talk about that soon.
-
Open page-data-access-tests.php and add this code to it.
-
Open the test page in the browser to make sure it's properly fetching a blog page.
Note that the code also verifies that if there is an error in the SQL statement, the handleError() method is invoked.
Also note that we have confirmed that the handleError() method is throwing an exception, just as it should do.
We "caught" the exception with our test code.
Create a 404 page
- Inside the my-new-site folder, create a page named 404.php
- You can copy code from another page and then make changes if you want, but the page should look something like this when you are done.
Add another global function to the config file (it will redirect users to a 'page not found' page)
- Add this function to the bottom of the config file.
Create the Blog Post Page
- Inside the blog folder, create a page called blog-post.php
-
Set up the page to look like this.
- Make sure you understand this code!
- Note that the $pda variable stores an instance of the PageDataAccess class.
- Note that the pageId query string variable is extracted from the $_GET super global array.
- Note that the pageId is passed in as a parameter to the getPageById() method.
- Note that we are handling the possibility of an invalid pageId by using a try/catch block (in which case we redirect to the 404 page).
- Note that we make sure that the page is set to 'active' (pages that are not 'active' should not be visible on the website - for example, they are not yet ready to be published).
- Note that we set the $pageTitle and $pageDescription variables with data that is fetched from the database.
- Note that the content of the blog post (along with a few other columns from the pages table) are echoed into the MAIN element of the page.
- Test out the blog post page by opening the browser and going to the blog home page, and then clicking on the link to the test blog post.
- Try playing around with the pageId url query string parameter to make sure the the page is properly redirecting to the 404 page when an invalid blog id is used.
Allowing Markup in the Page Content
Notice in the getPageById() method that we are not 'scrubbing' the content column when fetching
a post from the database (by using htmlentities()).
The reason for this is that we may want to allow SOME html tags to be included in the content.
- Open PHPMyAdmin and update the active post to include some html markup.
Preventing XSS Atacks
Take a look at the getPageById() method that we created earlier and note that
we are not using htmlentities() on the content column when we fetch it from the database.
The reason for this, is that we want to allow you to add some HTML tags so that you structure/style the content on your blog posts.
But this opens a huge security vulnerability in our code.
Now would be a good time for me to demonstrate a cross-site scripting attack (also known as XSS attacks)
and then I'll show you how we can try to prevent them from happening.
If a hacker finds a way to insert/update certain information into your database, he/she might be able to pull off an XSS attack.
Right now, it may be difficult for hackers to get to the database, but we will soon be creating PHP pages
that might give them some opportunities.
So let's go ahead and deal with the problem now.
-
Add this function to the config file.
It would be a really good exercise in learning PHP to pick this function apart, and understand what it does!
-
Now go back to the getPageById() method and 'wrap' the content coming from the database like this.
Follow Up Questions:
- What are HTTP headers?
- What is the purpose of a 404 status code header?
- What are some other HTTP status codes?
- What is the purpose of the mysqli_real_escape_string() function? (Not sure if this is a fair question at this point in the course)
- What are the SEO implications of using a single page to display all blog posts?
- What happens if you try to view a blog page that is not 'active' (the 'active' column for the row is set to 'no')?
- What is an XSS attack?