This video follows on the previous week's technique. Explore how to use the expiry date stored in the database to set the session variable to control access or to alert the subscriber when renewal is due within one month.
- [David] Hi, I'm David Powers and welcome to this week's edition of PHP Tips, Tricks, and Techniques. Designed to help you become a smarter, more productive PHP developer. In the previous two editions, we looked at using the PHP password hashing API which offers a more secure method of encrypting and verifying passwords. And setting a future date using PHP relative date strings. Both subjects are useful in their own right but they also act as a curtain raiser to this question from a member.
How can I prevent access when a membership has expired? Several possible solutions spring to mind. You could simply delete the member's account from the database. Without a username and password, they could no longer log in. But that's not a good idea because you would lose all information about the member, making reinstatement a hassle if they decide to rejoin. To avoid losing the member's data, you could set an inactive flag in the database.
Again, not a good idea because it involves manually updating the record. The simple way is to store the expiry date in the database and compare it to today's date as part of the authentication process. And that's the approach I'm going to take. So, let's get to work. In my database table I've got four columns. User ID has the primary key, then username, password, I'm using the PHP password hashing HPI, so I've set this column to the recommended 255 characters, then the expiry column, that is a date column, so it stores the date the member's subscription expires in year, month, date format.
And in my editing program I've got the files from the password hashing episode in their final state. You can download them from the exercise files for this video, however, as before, they don't contain the database connection or an SQL file for the database. You should be able to set that up for yourself. First we need to alter this registration form so that it inserts an expiry date into the member's record. We need to create that expiry date, so after encrypting the password, we'll create a variable called expiry.
And we need an instance of the date time class and we need to create a future date for the expiry. So, we need a relative date string. I'm going to coordinate all memberships to end on the last day of the month and to last for a year. So that relative date string, last day of this month, plus 12 months. We also need to get it into the right format for insertion into the database so I'm going to wrap this in a pair of parenthesis.
And then invoke the format method. For my SQL and Maria DP, it needs to be uppercase Y hyphen M hyphen D, so that's year, month, date. We now need to insert that expiry date into the database, so line 10 our insert statement. First we need the expiry column in there and then we also need a named parameter for the value. So, let's just move that onto the next line and name parameters begin with a colon.
I will call it simply expiry. Then we need to bind the value of expiry to this named parameter. So, we need our statement object and the bind param method. First argument to that is the name parameter, which is expiry. And then the value, which is expiry. So, that fixes the registration form.
We now need to take a look at the login script, so go to login.php. This script also uses a PDO prepared statement to check the user's credentials. And at the moment the select statement on line eight is only selecting the password from users where username is this named parameter. We need to select also the expiry date, so expiry. On line 16 we were originally fetching only a single column, that's no longer valid, so we need to comment that out.
Then on the next line, restore the result of the database query as result. And we need our statement object and we invoke the fetch method and we pass that a constant PDO colon colon fetch ASSOC. That will give us an associative array. And because we're no longer getting PWD, we need to fix this conditional statement on the next line.
We'll use our result, so if the result has got a value, that will equate true, and because we're no longer getting PWD, we need to get that password from the associative array stored in result. That's the name of the column there. Password. Now, this is basically doing the same as it did before, we're just using result, add result password.
So, if result has a value and password verify returns true, we know that the credentials are okay but we still need to check whether the subscription is still valid. So, on the next line we need to create a variable. And that will be for our expiry date. And that will be a date time object. And we pass it, the result that we've got from the database from the expiry column.
Let's just scroll up a little bit so we can see the rest of the script. Now, these next four lines from 20 to 23 redirect a successful login to the member's page, but we need to wrap that in another conditional statement. So, if, and what we need to do here is to compare the current date with the expiry date. And you can compare two date time objects. So, we'll have a new date time instance, new date time, that will be for the current date, then less than or equal to and then the value of expiry.
So, if the current date is less than or equal to the expiry date, this will equate to true, so we can then redirect the user with these four lines of script here. But if the expiry date is earlier than the current date, we need an else block to create a message that the subscription has expired. So, our message, sorry, your subscription expired.
Let's tell them when it expired, be user friendly. So we can get that using our expiry variable and invoke on that the format method. And we don't need to use the year, month, date format, we can use a much more user friendly one. So, if we have a capital F, that's the full month, J is the day with no leading zero, a comma and uppercase Y, which will be the year. So, that fixes both the registration script and the login script.
So, if we go back to register.php and load this into a browser, I can then register myself. I've cleared out the database, so I'm registering anew. Now it's registered me so I can now log in. That's working fine.
Let's log out and let's go to my database and let's just browse in there. There's the expiry date. I'm going to open that up and I'm going to change it to a date before today. That's updated it. Go back and try to log in again using my username and correct password.
And it tells me, sorry, your subscription expired on October the 30th, 2017. Now, the great thing about this is there's no need to check the expiry date on other pages because the session authenticated variable is set only if the membership is still valid when logging in. You could of course check the expiry date after log in to see if only a few days are left and then display a renewal reminder, but that's an exercise that I'll leave you to do on your own. If you need help working out the difference between two dates, check out chapter five of my PHP Date and Time Essential training course in the online library.
Let's recap how to block access when a membership expires. Store the date the membership expires in the database in the format year, month, date. On log in, check the username and password in the normal way. If the user's credentials are authenticated, check that the expiry date is in the future. You can do this by comparing two date time objects, one for the current date and the other for the expiry date. Complete the authentication process only if the membership is still valid.
Well, that's it for this week's PHP Tips, Tricks, and Techniques. Thanks for watching.
Note: The exercise files are free to all members. The code is commented to enhance your learning, but you will need database connectivity for some files to run as intended.