This will be the last part of the tutorial. Below are links to the previous 2 parts. Sorry for the lack of whitespace use, I’m trying to save you from scrolling horizontally ![]()
Link to part 1
Link to part 2
So far, we can register and log in. Now we want to be able to update our profile and add pictures. We’ll need to add another table in our database to store references of the users pictures.
If we were to store the actual picture into the database it could become very big, especially if you decide to allow your users to upload videos too. A better option would be to upload the picture into a directory on the web server and keep a reference to the picture in our database.
So first lets add our table. I added size and type to explain how to retrieve those values but I won’t be using them in my version of the site.
CREATE TABLE `db`.`user_photos` ( `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY , `profile_id` INT NOT NULL , `title` VARCHAR( 128 ) NOT NULL , `size` INT NOT NULL , `type` VARCHAR( 128 ) NOT NULL , `reference` VARCHAR( 255 ) NOT NULL ) ENGINE = MYISAM
The first 2 parts of the login system set everything up but the output looks terrible. We’ll add some css to make the site somewhat presentable. Give the sections a background and align the form elements with css.
style.css
.formElm { margin-bottom:5px; } .formElm label { float:left; width:120px; } div.divider { width:450px; margin:20px auto; background-color:#C1f0f6; border:4px #0ebfe9 double; padding:10px; }
Now we’re ready to make our profile control panel. At the top of our profilecp.php we need to start our session to see if the user is authenticated. So we start our session and include our database info.
profilecp.php
<?php session_start(); include "db_connect.php"; ?>
Next we’ll link to the stylesheet we just created and echo one of the session variables we created when the user first logged in (on index.php).
profilecp.php
<html> <head> <link rel="stylesheet" href="style.css"> <title><?php echo $_SESSION['username']; ?>'s Homepage</title> </head> <body> <div class="divider">
So now the title of the page will be that user’s name. This is how we’ll be referencing our user and their id for interaction with our database.
Now we’ll need to pull this users info. The SQL to do this using our session variable would be:
profilecp.php
<?php if($_SESSION['id']) //session id is established { echo "<a href=\"home.php\">Home</a><br/>"; //ugly navigation echo "<a href=\"logout.php\">Logout</a><br/>"; //grab record with the correct id $sql="SELECT * from `users` WHERE `id`='".$_SESSION['id']."'"; $res=mysql_query($sql); $row=mysql_fetch_assoc($res); //pull entire row of info and store in to a variable
We have all of this users info. We need to let them update it. We’ll do the usual if !POST method. If the form hasn’t posted, output the html, otherwise update the database.
profilecp.php
if(!$_POST['update'])
{
?>
</div>
<div class="divider">
<form method="post" action="profilecp.php">
<br/><strong>Profile Control Panel</strong><br/><br/>
<div class="formElm">
<label for="first">First Name</label>
<input id="first" type="text" name="first" maxlength="32" value="<?php echo $row['first']; ?>">
</div>
<div class="formElm">
<label for="last">Last Name</label>
<input id="last" type="text" name="last" maxlength="32" value="<?php echo $row['last']; ?>">
</div>
<div class="formElm">
<label for="email">Email</label>
<input id="email" type="text" name="email" maxlength="255" value="<?php echo $row['email']; ?>">
</div>
<div class="formElm">
<label for="about">About</label>
<textarea id="about" cols="40" rows="6" name="about"><?php echo $row['about']; ?></textarea>
</div>
<input type="submit" name="update" value="Update">
</form>
</div>That will be the form to update the text portion of the profile. We also want to allow them to add pictures. The form will submit to addpics.php where we’ll create directories and interact with our database. Heres the html for that. We’ll make addpics.php later.
profilecp.php
<div class="divider"> <form enctype="multipart/form-data" action="addpics.php" method="POST"><br/> <strong>Upload Pictures</strong><br/><br/> <div class="formElm"> <label for="title">Title</label> <input id="title" type="text" name="title" maxlength="32"><br/> </div> <div class="formElm"> <label for="file">File</label> <input id="file" type="file" name="pics" maxlength="255"><br/> </div> <input type="submit" value="Add"> </form> </div>
Since they can add pictures, we’ll need to let them delete them too. This form will submit to deletepics.php which will handle removing entries from our database and deleting the file from the web server.
profilecp.php
<div class="divider"> <?php $sql2 = "SELECT * FROM user_photos WHERE profile_id =".$_SESSION['id']; $res2 = mysql_query($sql2) or die(mysql_error()); if(mysql_num_rows($res2) > 0) //user has pictures { echo "<strong>Delete Pictures</strong><br/><br/>"; echo "<form name=\"deletefile\" method=\"post\" action=\"deletefile.php\">"; //output a checkbox next to each pic so they can delete multiple pics with one click while($file = mysql_fetch_array($res2)) { echo "<input name=\"files[]\" type=\"checkbox\" value=\"".$file['reference']."\">"; echo "<a href=\"".$_SESSION['username']."/pics/".$file['reference']."\"/> <img src=\"".$_SESSION['username']."/pics/thumbs/".$file['reference']."\"/></a><br/><br/>"; } echo "<input type=\"submit\" name=\"delfile\" value=\"Delete Files\">"; echo "</form>"; } else //they havent uploaded any pics yet! { echo "Please upload some pictures!<br/>"; }
This next part handles updating the database for the text portion only. The files addpics.php and deletepics.php take care of the rest.
} else { $first_name=protect($_POST['first']); $last_name=protect($_POST['last']); $about=protect($_POST['about']); $email=protect($_POST['email']); $sql3 = "UPDATE `users` SET `first`='$first_name',`last`='$last_name', `email`='$email',`about`='$about' WHERE `id`='".$_SESSION['id']."'"; $res3 = mysql_query($sql3) or die(mysql_error()); echo "Your profile has been successfully updated!"; } //else no session id was created, user is not authenticated...redirect to index }else echo "<script language=\"Javascript\" type=\"text/javascript\">document.location.href='index.php'</script>"; ?> </div> </body> </html>
Now we’re ready to make addpics.php which handles the pictures. This file will create a directory for the user, add the picture to that directory and also create a thumbnail of the picture. First we’ll add our thumbnail function to our db_connect.php so we can call it in the rest of our files. This function is not my work, I found it googling when I was teaching myself php. Credit goes to http://icant.co.uk/articles/phpthumbnails/
add the function to db_connect.php
function createthumb($name,$filename,$new_w,$new_h) { $system=explode(".",$name); if (preg_match("/jpg|jpeg/",$system[1])){$src_img=imagecreatefromjpeg($name);} if (preg_match("/png/",$system[1])){$src_img=imagecreatefrompng($name);} $old_x=imageSX($src_img); $old_y=imageSY($src_img); if ($old_x > $old_y) { $thumb_w=$new_w; $thumb_h=$old_y*($new_h/$old_x); } if ($old_x < $old_y) { $thumb_w=$old_x*($new_w/$old_y); $thumb_h=$new_h; } if ($old_x == $old_y) { $thumb_w=$new_w; $thumb_h=$new_h; } $dst_img=ImageCreateTrueColor($thumb_w,$thumb_h); imagecopyresampled($dst_img,$src_img,0,0,0,0,$thumb_w,$thumb_h,$old_x,$old_y); if (preg_match("/png/",$system[1])) { imagepng($dst_img,$filename); } else { imagejpeg($dst_img,$filename); } imagedestroy($dst_img); imagedestroy($src_img); }
Now that the functions ready we’ll go on to making addpics.php. We need to start our session again and include our db_connect.php file. Then we’ll use the mkdir command to create our directories. We have to make sure they dont exist first also. The entire addpics.php code is below with comments.
addpics.php
<?php session_start(); include "db_connect.php"; if($_SESSION['id']) //make sure theres a session id { //pull user info for this id $sql = "SELECT username FROM `users` WHERE `id`='".$_SESSION['id']."'"; $res = mysql_query($sql) or die(mysql_error()); //record doesnt exist...redirect to index.php if(mysql_num_rows($res) != 1) { session_destroy(); echo "<script language=\"Javascript\" type=\"text/javascript\"> document.location.href='index.php'</script>"; } else { $row = mysql_fetch_assoc($res); //pull entire row of info $title = protect($_POST['title']); //post value of title from the profilecp form if(!$title) //they must include a title { echo "<script language=\"Javascript\" type=\"text/javascript\"> alert(\"You must choose a title for your picture!\") document.location.href='profilecp.php'</script>"; } // the @ in front is to supress warning messages $target = $row['username']; //name of directory will be the username if(!is_dir($target)) @mkdir($target); //if directory does not exist, create it $target = $target . '/pics'; //store pictures in 'pics' subdirectory //check if pics subdirectory has been created, if not create it if(!is_dir($target)) @mkdir($target); //Heres where we use the FILES variable //a double array with the name and then parameter ($_FILES['name']['param']) $target = $target."/".basename($_FILES['pics']['name']) ; $size = $_FILES['pics']['size']; //if you want to limit size $pic = $_FILES['pics']['name']; $type = $_FILES['pics']['type']; //if you want to limit type (jpg,gif,png) //insert the reference of file into the database $sql2= "INSERT INTO `user_photos` (`profile_id`,`title`,`size`,`type`,`reference`) VALUES ('".$_SESSION['id']."','$title','$size','$type','$pic'); "; $res2 = mysql_query($sql2) or die(mysql_error()); //move the file into the correct directory if(move_uploaded_file($_FILES['pics']['tmp_name'], $target)) { echo "<script language=\"Javascript\" type=\"text/javascript\"> alert(\"Your picture has been uploaded\") document.location.href='profilecp.php'</script>"; } else //if something goes wrong display and error message { echo "<script language=\"Javascript\" type=\"text/javascript\"> alert(\"There was an error, try again\") document.location.href='profilecp.php'</script>"; } //create thumbnail and move it into the thumbnail directory $target2 = $row['username']; $target2 = $target2 . '/pics'; $target2 = $target2 . '/thumbs'; if(!is_dir($target2)) @mkdir($target2); $target2 = $target2."/".basename($_FILES['pics']['name']) ; createthumb($target,$target2,150,150); } }else echo "<script language=\"Javascript\" type=\"text/javascript\"> document.location.href='index.php'</script>"; ?>
Addpics.php is done, now on to deletepics.php. We use the unlink function to delete the file from our web server.
The entire deletepics.php
<?php session_start(); header("Location:profilecp.php"); include "db_connect.php"; $profile_id = $_SESSION['id']; if(!$profile_id) //no session id...redirect to index.php { echo "<script language=\"Javascript\" type=\"text/javascript\"> alert(\"You are not logged in!\");document.location.href='index.php'; </script>"; } else { foreach($_POST['files'] as $num => $id) //for each picture that was checked { //delete reference in database @mysql_query("DELETE FROM user_photos WHERE profile_id='$profile_id' AND reference='$id'"); unlink($_SESSION['username']."/pics/".$id); //delete pic in directory unlink($_SESSION['username']."/pics/thumbs/".$id); //delete thumbnail } } ?>
Alright…almost there. Everything looks good for the user that logs in. But we need something that’ll show of our users profile to anyone that visits, whether they are registered or not. So we’ll make a profile.php. All it does is grab the username from the url, find that users info and output it all to the page. We’ll be using the GET method to pull from the url.
profile.php
<?php session_start(); include "db_connect.php"; $sql="SELECT * from `users` WHERE `username`='".$_GET['username']."'"; $res=mysql_query($sql) or die(mysql_error()); if(mysql_num_rows($res) != 1)//no user with that username exists { echo "<script language=\"Javascript\" type=\"text/javascript\"> alert(\"This user does not exist\") document.location.href='index.php'</script>"; } else { $row=mysql_fetch_assoc($res); //pull the users info ?> <html> <head><link rel="stylesheet" href="style.css"></head> //use php to echo whats stored in our database <div class="divider"> <strong><?php echo $_SESSION['username'] ; ?>'s Profile</strong><br/> Name: <?php echo $row['first']. " " .$row['last'] ?> <br/> Email: <?php echo $row['email'] ?> <br/> About: <?php echo $row['about'] ?> <br/> </div> <div class="divider"> <strong>Pictures</strong><br/><br/> <?php //find this users pictures $result = mysql_query("SELECT reference FROM user_photos WHERE`profile_id`='".$row['id']."'"); //show the pictures thumbnail as a link to the full picture while ($row2 = mysql_fetch_array($result, MYSQL_ASSOC)) { echo "<a href=\"".$_GET['username']."/pics/".$row2['reference']."\"> <img src=\"".$_GET['username']."/pics/thumbs/".$row2['reference']."\"></a><br/>"; } } ?>
So to test this out say we had a username of ‘bananas’. If we went to localhost/yoursite/profile.php?username=bananas the page that comes up should be bananas profile. To clean this up we can use mod_rewrite in our .htaccess file. With the code below you only need to go to localhost/yoursite/bananas and you should see that users profile.
.htaccess
RewriteEngine on RewriteRule ^([a-zA-Z0-9_-]+)$ profile.php?username=$1 RewriteRule ^([a-zA-Z0-9_-]+)/$ profile.php?username=$1
We’re finally done! Thats everything! You should have a fully working login system (hopefully). I’ve attached all of the source code to the post. It can be found below. If there are any bugs or errors please let me know. I hope this helps! Tell me how it works for you!
Zip of all source code
php_login_system.zip


#1 by Zach on February 13, 2010 - 5:39 am
Thanks a bunch for this tutorial.
I’m using it as a basis for a small file hosting app for some friends and family.
I’m having some drama with adding password changing, ive messed around with the script and also the addition another user posted in the comments.
I can change the password, but for some reason, its not changing to the password I enter into the form.
All that aside, I am curious about the security aspects of the script, maybe that could be a topic for some more tutorials, I would really love to build on this script and you’ve made it so easy to this point!
Keep up the good work, I look forward to more =)
#2 by Bhavik on February 21, 2010 - 10:16 pm
Hey thanks for the comments! Im working on redoing this entire login system using a php framework (codeigniter or cakephp) to show a better/easier way of developing in php. This is going to take awhile though, very busy lately with work and school. This will address the security issues.