PHP Tips & Tricks - A Picture Upload, Part 3
The next feature to add to our picture upload application is to enforce some form of access control. There are all sorts of odd characters lurking on the Internet and we do not want to let the world upload any image to our server, so we have to set about implementing a log in system. We may not even want everyone to be able to even see our image gallery, so we need to setup different usernames and passwords for image uploading and image viewing.
We know that we are going to need a login form so the end user can enter his username and password. We can whip up a quick html form like this...
<form method="POST" enctype="multipart/form-data" name="login_form" action="<?$_SERVER["PHP_SELF"];?>">
<p><input type="text" name="username" size="20"></p>
<p><input type="text" name="password" size="20"></p>
<p><input type="submit" value="Login" name="action"></p>
We name this file login_form.php, and then we will include it in our login.php file. This goes back to part 1 of this project, where we want to separate out the php from the HTML. In fact, when we go through our new login.php file, you will notice that its general layout is very much like our upload.php file.
It will break down into 3 sections..
1.) An action section that will determine what to do when our
end user submits the form.
2.) A section to display the form.
3.) A section to display error messages.
You may have heard of a story where it is said that the intuit (eskimos) have over 400 words for snow. Well that may or may not be true, but programmers have over 400 ways of laying out a program. (and that is a conservative estimate) The most important thing to be is consistent. When you compare upload.php and login.php, you will see a familiar pattern. This helps tremendously when someone else is trying to figure out your code. That someone may even end up being yourself when you come back to look at the code 3 months down the road.
So with that in mind, here is the actual login code.
if(session_id() == "")
if($_POST["action"] == "Login")
//error checking and results
$error["username"] = "A username is required.";
$error["password"] = "A password is required.";
//we have a username password to work with
$username = trim(strtolower($_POST["username"]));
$password = trim(strtolower($_POST["password"]));
if(($username == "administrator") && ($password == "letmein"))
$_SESSION["username"] == "administrator";
else if(($username == "guest") && ($password == "ticket"))
$_SESSION["username"] == "guest";
$error["login"] = "Login failed.";
while(list($key, $val) = each($error))
To make our simple username and password protected pages, we are utilizing php's session functions. Sessions are extremely handy for carrying variables across webpages. Depending on how the server is setup, these variables could be stored in a variety of places. Our quick login code utilizing sessions is not meant to gaurantee a high level of security, we are only interested in keeping the general public from spying on our picture gallery.
The two main things to really pay attention to, are the use of the header function, and the use of session_register/$_SESSION. Sessions can be very tricky. The syntax for utilizing a session has changed from older versions of php. In newer versions you should not have to call session_register, but I have included it in here because it does not hurt and it will cover those who might
be running on older versions.
The login code is basically checking to see that our end user has entered 1 of the 2 usernames we have setup (and makes sure that the password matches) It then sets the session username variable to that username. If we have administrator, it uses the header function to push the end user to our upload.php page. If we have guest, it pushes to our list_images.php page.
However, there is one very important thing we have not done yet. We have not actually protected our upload.php, and list_images.php pages! We need to add some kind of code to the top of these 2 pages so that if we do not have the username session, push the end client to our login.php page. Once again, we utilize sessions and header.
On upload.php we add this.
if(session_id() == "")
if($_SESSION["username"] != "administrator")
And on list_images.php we add this.
if(session_id() == "")
if($_SESSION["username"] == "administrator")
else if($_SESSION["username"] == "guest")
That should do the trick. We have to be very careful were we place the header function. It is usually best to keep it very near the top of your script. If any output is sent out (such as a variable name or even a blank echo) the header function will fail. If the header function fails to push the end user, the rest of the code will continue to execute. It is for that reason that we include a die function call.
There is still a lot of room for improvement on our little gallery, but we have included all the basic functionality. A lot of things that we have made in the code could be handled more efficiently if we utilized a database (such as storing username and passwords, image locations, etc..) But with this framework we have covered what we set out to do.