This post will cover creating a very simple blog in php. It will only consist of posts. The front-end will only be two pages, an index page to list all posts and a view page to view a post.
There will be a backend control panel for managing posts and admins, this guide will also include a user authentication system to login administrators.
There will be two mysql tables, blog_posts and blog_members.
Every page will need a database connection, this will be opened in config.php:
Start output buffering, then headers can be used anywhere. Start sessions this will be needed for the admin area.
Define the database connection details then open a PDO connection.
Also set the timezone, adjust this as needed.
Next create an autoload function this will include any class as it is called this stops you having to manually include all classes, for this project there is only a single class but this set up the feature for more classes in future developments.
Inside the function, the name passed to is is converted into lowercase then check to see if the file exists if it does it is then included.
Lastly the user class is instantiated and passed the database connection ($db) so the class has access to the database.
The index file will list all posts from the posts table.
A query is ran to select the columns from blog_posts then ordered by the postID in descending order.
Then the posts are looped through on each loop display the title, description date posted and a link to read the full post.
The query is wrapped inside a try catch statement so if there is any errors a PDO Exception will be used to display them.
The id for the post is past to the next page in what’s called a query string ?id will become a variable in the url = assignes the value.
viewpost.php is used to display any post that has been clicked on.
This query will use a prepared statement, the record to be selected is based upon the id been passed from a $_GET[‘id’] request, as such a normally query is not recommended, a prepared statement is much better. The prepare will ‘prepare’ the database for query to be run then when $stmt->execute is ran the items from the array will be bound and sent to the database server, at no point does the two connect to there is no way to tamper with the database.
That’s it for the front end! its very simple but its also very easy to expand and add more features.
Every page in the admin area will start by including the config file and checking if the admin is logged in, otherwise they are redirect to the login page.
Once submitted the username and password are collected from the form then passed to a login method in the user class (I’ll come to that shortly) if this returns true, they have logged in are are taken to the admin otherwise they are shown an error.
The user class is used to login and logout users verify their password and create a hash of their password.
The first function that will get called as soon as the class is ran is an automatic function called __construct this method is passed a database connection this is then assigned to a variable within the class so all methods will have access to it.
To check if a user is logged in a method is_logged_in() looks for a session called loggedin if its set and is true their is a logged in user and returns true otherwise is would return nothing.
In order to verify a password matched a password given on login the hashed password needs to be fetched from the database, the username is passed to the database and the hashed password is returned.
The login method expects the users username and password then the fetches users password based on their username from the get_user_hash method in order to use the verify_hash method.
If a match is found a session is set and the method returns true.
The blog posts are listed in a table, again using a query to select all records and display them ordered by the postID in descending order, then looped through to list all posts, each post has an edit and delete link the edit link passes the postID to edit-post.php in order to edit the selected post.
PHP Delete function
If the get request delpost has been sent then a prepared statement is ran to delete the post where the postID matches the id passed in the array. Then the page is reloaded passing a status to the url in indexphp?action= the action is used on the page to confirm the deletion.
There is an admin menu that will be display on every page, whilst this could be added to each page it makes more sense to add links to a separate file called menu.php that can be included into every file, that way any changes only need to be applied once.
The menu is very simple for this site the links are inside a ul list, the view website links back to the root of the project by going back a directory using ../ in the href path.
The form to add a post is made up of input’s and textareas, each section has a name which will become a variable in php when the form is submitted.
The forms also use what’s called sticky forms meaning if validation fails then show all content entered into the form.
For textarea’s rather then making the admins enter the html for the text themselves its better to use an editor, I’ve chosen to use a popular one called <a href=’http://www.tinymce.com’>TinyMCE</a> To use it you would normally have to download the files from tinyMCE’s website upload them and configure the config, thankfully they have recently released a CDN version so you can include tinyMCE by simply referencing the CDN and then your setup options:
This will convert all textarea’s into editors.
To process the form data once its been submitted is a simple process first make sure the form has been submitted. Then remove any slashed in the $_POST array. Then extract all posts items inside $_POST by using extract($_POST) any post element is then accessible by using just its name so $_POST[‘postTitle’] becomes $postTitle.
Next validate the data, these are very basic validation rules. These can be improved upon, if any of the if statements are true then an error is needed, adding an error to an array called error is a simple way to collect multiple errors.
Next if no error has been set then insert the data into the database, this is using prepared statements the place holders :postTitle, :postDesc etc are using to bind the matching array elements when execute to add the data into the correct columns. Once inserted the user is redirected back to the admin a action status is appended to the url ?action=added.
This is very much like the add page except before the menu a query must be ran to select the correct post from the database to populate the form with.
The query needs to select the record where the postID matched the id passed in the $_GET[‘id’] request, as this can be manipulated a prepared statement is used.
The form also has an hidden field with the name postID and a value from the database this is used when updating the record to determine which post to make the changes to.
Adding and editing users is very similar to posts I will go over only what’s different.
Present the form to be filled in, notice the password have a type of password this stops the password being show in the form.
As part of processing the form new users will need a hash to be created from the user class this is done by passing the password from the form into the class object and use the create_hash method.
Next a normal insert statement is ran in the array the password is not used but instead the hashedpassword is given.
To edit a user first the user needs to be retrieved from the database using a prepared statement where the memberID matches the id passed in the get request.
The password fields are not populated, this are only filled in to change the password.
When running validation the password checks should only run if a password has been entered.
When updating the database a check is made to see if the password has been set, if so then the password is updated otherwise another update is ran without updating the password.
When the password is to be updated a new hash is created from the user object.
That’s all the notable differences the files in full are available in the download I’ll also list the full files below: