<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>edrackham &#187; MySQL</title>
	<atom:link href="http://edrackham.com/category/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://edrackham.com</link>
	<description>PHP, MySQL, JavaScript and Other Web Tutorials!</description>
	<lastBuildDate>Tue, 21 Feb 2012 11:57:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>PHP Login Script Tutorial</title>
		<link>http://edrackham.com/php/php-login-script-tutorial/</link>
		<comments>http://edrackham.com/php/php-login-script-tutorial/#comments</comments>
		<pubDate>Wed, 06 Oct 2010 21:04:34 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Membership]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[Sessions]]></category>
		<category><![CDATA[User Authentication]]></category>

		<guid isPermaLink="false">http://edrackham.com/?p=100</guid>
		<description><![CDATA[This PHP login script / tutorial will show you how you can have users register on your site, and log in to access secure areas. I have seen a few tutorials around the web which show how this can be done, but they all seem to lack in security. This user membership tutorial will show [...]]]></description>
			<content:encoded><![CDATA[<p>This PHP login script / tutorial will show you how you can have users register on your site, and log in to access secure areas. I have seen a few tutorials around the web which show how this can be done, but they all seem to lack in security. This user membership tutorial will show a better way of having users authenticated once logged in by using their session ID.<span id="more-100"></span><div align="center" style="margin-bottom: 20px;">
<script type="text/javascript"><!--
google_ad_client = "pub-4159646232668987";
google_ad_slot = "5003066961";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div></p>
<h2><a href="http://edrackham.com/tutorials/user-membership-with-php-mysql/" target="_blank">DEMO: HERE</a></h2>
<h2>The Table</h2>
<p>Firstly, we need to create a table to store our users. I&#8217;m using phpMyAdmin to administer my database, so setting up the table is pretty easy for me. You can use the following SQL statement to create your `users` table, using whichever method you prefer:</p>
<pre name="code" class="php">
CREATE TABLE `users` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
    `email` VARCHAR( 255 ) NOT NULL ,
    `password` VARCHAR( 32 ) NOT NULL ,
    `session_id` VARCHAR( 32 ) NULL ,
    `date_registered` DATETIME NOT NULL ,
    UNIQUE (`email`)
) ENGINE = MYISAM ;
</pre>
<p>A few things to note here:</p>
<ul>
<li>We&#8217;re going to be hashing the passwords (using MD5), so we know that the password field will be exactly 32 characters in length</li>
<li>For extra security, we&#8217;re going to re-authenticate users across pages using their session ID, so we &#8211; again &#8211; need a field which is exactly 32 characters</li>
<li>We&#8217;re making the email field unique. This isn&#8217;t completely necessary, as we&#8217;ll be checking for duplicate email addresses within the register form, but it&#8217;s just an extra &#8220;lock on the door&#8221; so to speak. So if anything failed within the PHP code, the database would still fail on the insert.</li>
</ul>
<p>&nbsp;</p>
<p><div align="center" style="margin-bottom: 20px;">
<script type="text/javascript"><!--
google_ad_client = "pub-4159646232668987";
google_ad_slot = "5003066961";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div></p>
<h2>The main config file</h2>
<p>It makes sense to have an include which will set up a few things for us on every page we want to secure. This file should have the <strong>session_start()</strong> function call in it &#8211; because without this, we wouldn&#8217;t be able to use sessions at all! We also need to establish a database connection, and finally, check for an authenticated user.</p>
<p>Create a new file called <strong>config.php</strong> and paste the following code into it:</p>
<pre name="code" class="php">
// Start the session (pretty important!)
session_start();

// Establish a link to the database
$dbLink = mysql_connect('YOUR HOSTNAME', 'YOUR USERNAME', 'YOUR PASSWORD');
if (!$dbLink) die('Can\'t establish a connection to the database: ' . mysql_error());

$dbSelected = mysql_select_db('YOUR DATABASE', $dbLink);
if (!$dbSelected) die ('We\'re connected, but can\'t use the table: ' . mysql_error());

// Run a quick check to see if we are an authenticated user or not
// First, we set a 'is the user logged in' flag to false by default.
$isUserLoggedIn = false;
$query 		= 'SELECT * FROM users WHERE session_id = "' . session_id() . '" LIMIT 1';
$userResult 	= mysql_query($query);
if(mysql_num_rows($userResult) == 1){
	$_SESSION['user'] = mysql_fetch_assoc($userResult);
	$isUserLoggedIn = true;
}else{
	if(basename($_SERVER['PHP_SELF']) != 'login.php'){
		header('Location: login.php');
		exit;
	}
}
</pre>
<p>Ok, so firstly we&#8217;re calling <strong>session_start()</strong>. This is an extremely important function to call if you want to use server-side session variables. This function should ALWAYS be called before any output has been sent to the browser &#8211; even newlines. It&#8217;s generally a good idea to just call session_start() at the very top of your code, on every page. Why are we using session variables anyway? Well, it&#8217;s much easier to handle arrays of data across pages if we do this. In this example, we will be storing the user&#8217;s details (such as name, email address etc&#8230;) within a session variable array, so we can access it on any number of secure pages we have.</p>
<p>Lines 5 to 9 are simply establishing a connection to our database. I&#8217;m not going to go into too much detail on how you use PHP to connect to a database, but you do need to replace the following four items within these lines:</p>
<ul>
<li><strong>YOUR HOSTNAME</strong> &#8211; This is generally <strong>localhost</strong>, but can be another named, or IP of a remote host where your database resides.</li>
<li><strong>YOUR USERNAME</strong> &#8211; Replace this with your username for accessing your database.</li>
<li><strong>YOUR PASSWORD</strong> &#8211; Replace this with your password for accessing your database.</li>
<li><strong>YOUR DATABASE</strong> &#8211; Replace this with the name of your database you want to access.</li>
</ul>
<p>&nbsp;</p>
<p><div align="center" style="margin-bottom: 20px;">
<script type="text/javascript"><!--
google_ad_client = "pub-4159646232668987";
google_ad_slot = "5003066961";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div></p>
<h2>The Auto-Authentication</h2>
<p>Within the config.php file, I think it&#8217;d be a good idea to automatically authenticate the user. This means that every time a page is loaded (with our config.php file in the header) we&#8217;ll be doing a quick check to see if they&#8217;re authenticated, and if they are &#8211; we&#8217;ll set a boolean flag to indicate this, and a session based array full of their information.</p>
<p>Line 13 sets the boolean flag <strong>$isUserLoggedIn</strong> to false by default. Line 14 sets up a query to get any user who has the session id set to <strong>session_id()</strong>. <strong>session_id()</strong> is a PHP function which returns a 32 character length string with the user&#8217;s current session variable. This is a unique string that PHP will generate for every user on your site. This will timeout (change to a new session ID) based on the PHP ini setting <strong>session.gc_maxlifetime</strong>. Generally, you won&#8217;t need to change this timeout limit, but if you need to, you should be able to add the following to the top of the config file (just under session_start() should do fine):</p>
<pre name="code" class="php">
ini_set(’session.gc_maxlifetime’, 60*60);
</pre>
<p>Which will set the timeout to one hour &#8211; 60 seconds multiplied by 60. You can make this even bigger if you like, but it&#8217;s a good idea to keep your timeouts down to around 30mins, so if a registered &#8211; and logged in &#8211; user leaves their computer for over 30mins, someone else won&#8217;t be able to use the secure area (as the session would have timed out).</p>
<p>Line 15 simply executes the query, and stores the return result of the query in <strong>$userResult</strong>.</p>
<p>Line 16 checks to see if we have a result returned. If we do, it means that we have found a user in our users table, with a session ID which exactly matches the result of session_id(). Therefore, it&#8217;s safe to say that the user is an already-logged-in user, and as such, we can authenticate them.</p>
<p>We do this on lines 17 and 18 by setting a session variable array <strong>$_SESSION['user']</strong> to the array of data that we get back when we fetch the row of data, and then setting the <strong>$isUserLoggedIn</strong> flag to true.</p>
<p>The remaining lines in our config.php file are there so that we can handle what happens to a non-authenticated user. If no logged-in-user is found, we check to see what page we&#8217;re currently on. If we&#8217;re not on our login.php page, we redirect the user to our login.php page. We need to check that we&#8217;re not on the login page before doing the redirect, otherwise we&#8217;d end up putting the user in an infinite loop. For example, regardless of what page you&#8217;re on (including the login.php page), we&#8217;d ALWAYS be redirecting the user to the login.php page. Just under that we&#8217;re calling <strong>exit;</strong>. This should always be called after doing a <strong>header(&#8216;Location: &#8230;&#8217;);</strong> call, as the page <em>can</em> still continue to render after the header has been executed, causing all sorts of problems.</p>
<h2>The Login &#038; Register Page</h2>
<p>Yep &#8211; we&#8217;re clever, so we&#8217;re going to have the login and register functionality / forms on the same page!</p>
<p>Create a new file called <strong>login.php</strong> and copy the following code into it:</p>
<pre name="code" class="php">
&lt;?php
include_once('config.php');

// Reset errors and success messages
$errors = array();
$success = array();

// Login attempt
if(isset($_POST['loginSubmit']) &amp;&amp; $_POST['loginSubmit'] == 'true'){
	$loginEmail = trim($_POST['email']);
	$loginPassword 	= trim($_POST['password']);

	if (!eregi(&quot;^[_a-z0-9-] (.[_a-z0-9-] )*@[a-z0-9-] (.[a-z0-9-] )*(.[a-z]{2,3})$&quot;, $loginEmail))
		$errors['loginEmail'] = 'Your email address is invalid.';

	if(strlen($loginPassword) &lt; 6 || strlen($loginPassword) &gt; 12)
		$errors['loginPassword'] = 'Your password must be between 6-12 characters.';

	if(!$errors){
		$query 	= 'SELECT * FROM users WHERE email = &quot;' . mysql_real_escape_string($loginEmail) . '&quot; AND password = MD5(&quot;' . $loginPassword . '&quot;) LIMIT 1';
		$result = mysql_query($query);
		if(mysql_num_rows($result) == 1){
			$user = mysql_fetch_assoc($result);
			$query = 'UPDATE users SET session_id = &quot;' . session_id() . '&quot; WHERE id = ' . $user['id'] . ' LIMIT 1';
			mysql_query($query);
			header('Location: index.php');
			exit;
		}else{
			$errors['login'] = 'No user was found with the details provided.';
		}
	}
}

// Register attempt
if(isset($_POST['registerSubmit']) &amp;&amp; $_POST['registerSubmit'] == 'true'){
	$registerEmail = trim($_POST['email']);
	$registerPassword = trim($_POST['password']);
	$registerConfirmPassword 	= trim($_POST['confirmPassword']);

	if (!eregi(&quot;^[_a-z0-9-] (.[_a-z0-9-] )*@[a-z0-9-] (.[a-z0-9-] )*(.[a-z]{2,3})$&quot;, $registerEmail))
		$errors['registerEmail'] = 'Your email address is invalid.';

	if(strlen($registerPassword) &lt; 6 || strlen($registerPassword) &gt; 12)
		$errors['registerPassword'] = 'Your password must be between 6-12 characters.';

	if($registerPassword != $registerConfirmPassword)
		$errors['registerConfirmPassword'] = 'Your passwords did not match.';

	// Check to see if we have a user registered with this email address already
	$query = 'SELECT * FROM users WHERE email = &quot;' . mysql_real_escape_string($registerEmail) . '&quot; LIMIT 1';
	$result = mysql_query($query);
	if(mysql_num_rows($result) == 1)
		$errors['registerEmail'] = 'This email address already exists.';

	if(!$errors){
		$query = 'INSERT INTO users SET email = &quot;' . mysql_real_escape_string($registerEmail) . '&quot;,
																		password = MD5(&quot;' . mysql_real_escape_string($registerPassword) . '&quot;),
																		date_registered = &quot;' . date('Y-m-d H:i:s') . '&quot;';

		if(mysql_query($query)){
			$success['register'] = 'Thank you for registering. You can now log in on the left.';
		}else{
			$errors['register'] = 'There was a problem registering you. Please check your details and try again.';
		}
	}

}
?&gt;
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta charset=&quot;utf-8&quot;/&gt;
  &lt;title&gt;Login to the secure area&lt;/title&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width; initial-scale=1.0; maximum-scale=1.0;&quot;/&gt;
  &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;default.css&quot;/&gt;
&lt;/head&gt;

&lt;body&gt;
  &lt;header&gt;&lt;h1&gt;Login / Register Here&lt;/h1&gt;&lt;/header&gt;

	&lt;form class=&quot;box400&quot; name=&quot;loginForm&quot; action=&quot;&lt;?php echo $_SERVER['PHP_SELF']; ?&gt;&quot; method=&quot;post&quot;&gt;
		&lt;h2&gt;Login&lt;/h2&gt;
		&lt;?php if($errors['login']) print '&lt;div class=&quot;invalid&quot;&gt;' . $errors['login'] . '&lt;/div&gt;'; ?&gt;

		&lt;label for=&quot;email&quot;&gt;Email Address&lt;/label&gt;
		&lt;input type=&quot;text&quot; name=&quot;email&quot; value=&quot;&lt;?php echo htmlspecialchars($loginEmail); ?&gt;&quot; /&gt;
		&lt;?php if($errors['loginEmail']) print '&lt;div class=&quot;invalid&quot;&gt;' . $errors['loginEmail'] . '&lt;/div&gt;'; ?&gt;

		&lt;label for=&quot;password&quot;&gt;Password &lt;span class=&quot;info&quot;&gt;6-12 chars&lt;/span&gt;&lt;/label&gt;
		&lt;input type=&quot;password&quot; name=&quot;password&quot; value=&quot;&quot; /&gt;
		&lt;?php if($errors['loginPassword']) print '&lt;div class=&quot;invalid&quot;&gt;' . $errors['loginPassword'] . '&lt;/div&gt;'; ?&gt;

		&lt;label for=&quot;loginSubmit&quot;&gt;&amp;nbsp;&lt;/label&gt;
		&lt;input type=&quot;hidden&quot; name=&quot;loginSubmit&quot; id=&quot;loginSubmit&quot; value=&quot;true&quot; /&gt;
		&lt;input type=&quot;submit&quot; value=&quot;Login&quot; /&gt;
	&lt;/form&gt;

	&lt;form class=&quot;box400&quot; name=&quot;registerForm&quot; action=&quot;&lt;?php echo $_SERVER['PHP_SELF']; ?&gt;&quot; method=&quot;post&quot;&gt;
		&lt;h2&gt;Register&lt;/h2&gt;
		&lt;?php if($success['register']) print '&lt;div class=&quot;valid&quot;&gt;' . $success['register'] . '&lt;/div&gt;'; ?&gt;
		&lt;?php if($errors['register']) print '&lt;div class=&quot;invalid&quot;&gt;' . $errors['register'] . '&lt;/div&gt;'; ?&gt;

		&lt;label for=&quot;email&quot;&gt;Email Address&lt;/label&gt;
		&lt;input type=&quot;text&quot; name=&quot;email&quot; value=&quot;&lt;?php echo htmlspecialchars($registerEmail); ?&gt;&quot; /&gt;
		&lt;?php if($errors['registerEmail']) print '&lt;div class=&quot;invalid&quot;&gt;' . $errors['registerEmail'] . '&lt;/div&gt;'; ?&gt;

		&lt;label for=&quot;password&quot;&gt;Password&lt;/label&gt;
		&lt;input type=&quot;password&quot; name=&quot;password&quot; value=&quot;&quot; /&gt;
		&lt;?php if($errors['registerPassword']) print '&lt;div class=&quot;invalid&quot;&gt;' . $errors['registerPassword'] . '&lt;/div&gt;'; ?&gt;

		&lt;label for=&quot;confirmPassword&quot;&gt;Confirm Password&lt;/label&gt;
		&lt;input type=&quot;password&quot; name=&quot;confirmPassword&quot; value=&quot;&quot; /&gt;
		&lt;?php if($errors['registerConfirmPassword']) print '&lt;div class=&quot;invalid&quot;&gt;' . $errors['registerConfirmPassword'] . '&lt;/div&gt;'; ?&gt;

		&lt;label for=&quot;registerSubmit&quot;&gt;&amp;nbsp;&lt;/label&gt;
		&lt;input type=&quot;hidden&quot; name=&quot;registerSubmit&quot; id=&quot;registerSubmit&quot; value=&quot;true&quot; /&gt;
		&lt;input type=&quot;submit&quot; value=&quot;Register&quot; /&gt;
	&lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>It&#8217;s not as scary as it looks. Lines 1 to 66 contain the main PHP functionality for the page, whereas the rest is simple HTML markup with a few little extras for validation (which, again, many other similar tutorials don&#8217;t cover!).</p>
<p>We start by including our config.php file which we&#8217;ve just created. We&#8217;re assuming that the file is in the same directory as this login.php file. This can be changed easily, but just remember to either update your paths to your config file, or set a globally accessible variable to build the paths dynamically.</p>
<p>Because we have included that config.php file, we can already assume the following:</p>
<ul>
<li>We have declared <strong>session_start()</strong>, so we don&#8217;t need to re-declare that at all.</li>
<li>We have a valid database connection</li>
<li>We have run a check for a valid, logged-in user</li>
</ul>
<p>&nbsp;</p>
<p>We&#8217;re then declaring two empty arrays to hold errors and success messages. This will be used for validating the form, and notifying the user that they have successfully registered.</p>
<p>Next, we have two main if statements. One for the login attempt, and one for the register attempt. Both of which are looking for a hidden form variable to be set, with a value of &#8216;true&#8217;. I do this, as it&#8217;s my preferred method for checking for a form post, but feel free to use whatever method of checking for a form submission you prefer. The way this setup works is that on a standard page load (i.e. without a form submission) neither of the if statements will return true, as no form data would have been sent to it &#8211; but if we submit one of the forms, it will post back to itself and be dealt with accordingly. I like this method, as it allows me to keep functionality specific to a certain page, contained within that page.<br />
<div align="center" style="margin-bottom: 20px;">
<script type="text/javascript"><!--
google_ad_client = "pub-4159646232668987";
google_ad_slot = "5003066961";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div></p>
<h3>The Login Attempt If Block</h3>
<p>We&#8217;re firstly cleaning the posted variables, by <strong>trim()</strong>-ing them. This removes whitespace from the left and right side of the variable. This also gets around people just posting empty form elements, or form elements which have only spaces in them.</p>
<p>This is also setting a variable that we&#8217;ll use further down the page when we get to the form. How many times have you filled out a form on the web, only to have it not validate and then be faced with the same form &#8211; but completely blank! We&#8217;re going to use the <strong>$loginEmail</strong> variable on the <strong>loginEmail</strong> form element as the value, so if they mistype something, at least they won&#8217;t have to write their email address again (provided they typed it right the first time). It&#8217;s more of a proof-of-concept thing, rather than a MUST-DO for this tutorial.</p>
<p>After those two lines comes the validation. We&#8217;re using a regular expression to validate the email address, and simply checking the string length of the password to ensure it falls between 6 and 12 characters. If either fail, the <strong>$error</strong> array will be populated with the appropriate error messages, which will be used further down the page when we get to the actual form.</p>
<p>Following that, we have another if statement checking to see if we <strong>don&#8217;t</strong> have any errors. If we don&#8217;t, we then look on the database for a user with the email address provided, and the password &#8211; which is MD5 hashed using the <strong>MD5()</strong> MySQL function. If we get a result (in other words, there is a user with the email address and password provided), we update that row for the user so that their session_id field in our database gets the value of the PHP provided session_id().</p>
<p>We then simply push them to our landing page for authenticated users &#8211; in this example, it&#8217;s index.php. As we&#8217;ll be including the config.php file across all secure pages, we know we don&#8217;t need to worry about anything else, because our config.php file does a user authentication check every page anyway <img src='http://edrackham.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<h3>The Register Attempt If Block</h3>
<p>Very similar to the login attempt if block, but within this, we have a <strong>confirmPassword</strong> form element that we need to make sure matches the password form element, and lines 50 to 53 are also checking that the email address doesn&#8217;t exist within the database. We don&#8217;t want two people registering under the same email address!</p>
<p>Provided we have no errors, we insert a new record for the user into our users table, setting the email address, password (using MD5), and date registered. If the query succeeds when we execute it (on line 60), we can set a success message which will be displayed below, otherwise we set an error message.</p>
<h3>The Forms</h3>
<p>I&#8217;m not going to go into too much detail regarding the markup of the actual HTML page, but I will say that it is using HTML5 (for those unfamiliar), and there is a stylesheet included to aid the layout of the forms / labels. Feel free to create your own, or take mine from the <a href="http://edrackham.com/tutorials/user-membership-with-php-mysql/">actual tutorial itself</a>.</p>
<p>The forms themselves (<strong>loginForm</strong> and <strong>registerForm</strong>) should be self explanatory, but you just need to note the following:</p>
<ul>
<li>Both forms have their action set to <strong>$_SERVER['PHP_SELF']</strong>. This makes sure that the form posts the submitted data to the same page (which will be dealt with accordingly as in our main PHP block at the top of the page.</li>
<li>Within the forms I am checking for the existence of error or success array variables, such as <strong>$errors['loginEmail']</strong>, and if they exist, I&#8217;m outputting the error message wrapped in a div with appropriate styling.</li>
<li>The login form has a hidden form element called <strong>loginSubmit</strong>, whereas the register form has a hidden form variable called <strong>registerSubmit</strong>. They are both set to &#8216;<strong>true</strong>&#8216;. This is so we can identify which form was submitted when we post the data to the page. <em>There are other ways of doing this, but I find this the cleanest for this tutorial.</em></li>
<li>The register form has an extra field called <strong>confirmPassword</strong>, which is used to check that the user has entered their password correctly when they register.</li>
</ul>
<p>And that is all we need for our login / register page.</p>
<h2>The Secure Page(s)</h2>
<p><em>Almost</em> finally, we need to create a secure page to demonstrate this authentication / user membership is working.</p>
<p>Create a new file called <strong>index.php</strong> and copy in the following code:</p>
<pre name="code" class="php">
&lt;?php
include_once('config.php');
?&gt;
&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;meta charset=&quot;utf-8&quot;/&gt;
  &lt;title&gt;Welcome to the secure area&lt;/title&gt;
  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width; initial-scale=1.0; maximum-scale=1.0;&quot;/&gt;
  &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;default.css&quot;/&gt;
&lt;/head&gt;

&lt;body&gt;
  &lt;header&gt;&lt;h1&gt;Secure Area&lt;/h1&gt;&lt;/header&gt;

	&lt;p&gt;This is one (of many potential) pages that reside in the secure area. All you need to remember to do is to include the &lt;strong&gt;config.php&lt;/strong&gt; file, which handles the user authentication every time.&lt;/p&gt;

	&lt;p&gt;Your user details are as follows:&lt;/p&gt;
	&lt;ul&gt;
		&lt;?php foreach($_SESSION['user'] as $key =&gt; $value){ ?&gt;
			&lt;li&gt;&lt;?php echo $key; ?&gt; &lt;strong&gt;&lt;?php echo $value; ?&gt;&lt;/strong&gt;&lt;/li&gt;
		&lt;?php } ?&gt;
	&lt;/ul&gt;

	&lt;footer&gt;
		&lt;a href=&quot;logout.php&quot;&gt;Logout&lt;/a&gt;
	&lt;/footer&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>The magic here, is that we don&#8217;t need to to much at all! As you can see, we don&#8217;t need to do anything but include the <strong>config.php</strong> file. You can create as many secure pages as you like, but just remember to have the config file included at the top of your pages. This page will always ensure that your customers are logged in and authenticated at all times, and if they&#8217;re not &#8211; they&#8217;ll be pushed right back to the login.php page.</p>
<h2>Logging a User Out</h2>
<p>The final part of this tutorial is showing how we log a user out securely.</p>
<p>Create a new file called <strong>login.php</strong> and add the following code:</p>
<pre name="code" class="php">
include_once('config.php');
$query = 'UPDATE users SET session_id = NULL WHERE id = ' . $_SESSION['user']['id'] . ' LIMIT 1';
mysql_query($query);
unset($_SESSION['user']);
header('Location: login.php');
exit;
</pre>
<p>Very simple. We&#8217;re simply updating the users table to set the currently logged in user&#8217;s session ID (as stored in the database) to NULL, unsetting the $_SESSION['user'] variable, then pushing them to the login.php page.</p>
<p>This concludes my simple &#8211; but secure &#8211; user membership / authentication tutorial using PHP and MySQL. You should have learned how to securely authenticate a user, track their authentication across multiple pages, and securely log them out. If you have any questions at all, please post them in the comments and I&#8217;ll do my best to answer them for you.</p>
<p>Don&#8217;t forget, there is a&#8230;</p>
<h2><a href="http://edrackham.com/tutorials/user-membership-with-php-mysql/" target="_blank">DEMO: HERE</a></h2>
<p><div align="center" style="margin-bottom: 20px;">
<script type="text/javascript"><!--
google_ad_client = "pub-4159646232668987";
google_ad_slot = "5003066961";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div></p>
]]></content:encoded>
			<wfw:commentRss>http://edrackham.com/php/php-login-script-tutorial/feed/</wfw:commentRss>
		<slash:comments>27</slash:comments>
		</item>
		<item>
		<title>Simple PHP MySQL Class</title>
		<link>http://edrackham.com/php/simple-php-mysql-class/</link>
		<comments>http://edrackham.com/php/simple-php-mysql-class/#comments</comments>
		<pubDate>Tue, 17 Aug 2010 20:50:35 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Class]]></category>

		<guid isPermaLink="false">http://edrackham.com/uncategorized/simple-php-mysql-class/</guid>
		<description><![CDATA[That&#8217;s right! I have a simple MySQL class file that you can use in your PHP projects. I&#8217;ve been using it for years, and it&#8217;s never let me down! You can grab it on my Github: http://github.com/a1phanumeric/PHP-MySQL-Class. Setup The setup is simple: Simply include this class into your project like so: include_once('/path/to/class.MySQL.php'); Then make sure [...]]]></description>
			<content:encoded><![CDATA[<p>That&#8217;s right! I have a simple MySQL class file that you can use in your PHP projects. I&#8217;ve been using it for years, and it&#8217;s never let me down!</p>
<p>You can grab it on my Github: <a href="http://github.com/a1phanumeric/PHP-MySQL-Class">http://github.com/a1phanumeric/PHP-MySQL-Class</a>.</p>
<p><span id="more-32"></span></p>
<h2>Setup</h2>
<p>The setup is simple:</p>
<p>Simply include this class into your project like so:</p>
<pre name="code" class="php">include_once('/path/to/class.MySQL.php');</pre>
<p>Then make sure you have the following definitions set:</p>
<pre name="code" class="php">MYSQL_HOST
MYSQL_USER
MYSQL_PASS
MYSQL_NAME</pre>
<p>I usually include them in a globally included config file.</p>
<p><div align="center" style="margin-bottom: 20px;">
<script type="text/javascript"><!--
google_ad_client = "pub-4159646232668987";
google_ad_slot = "5003066961";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div></p>
<p>MYSQL_HOST = The hostname of the MySQL server (usually, but not always, &#8216;localhost&#8217;).</p>
<p>MYSQL_USER = Your username for the server / database</p>
<p>MYSQL_PASS = Your password for the server / database</p>
<p>MYSQL_NAME = The name of your database</p>
<h2>Usage</h2>
<p>To use this class, you&#8217;d first init the object like so:</p>
<pre name="code" class="php">$oMySQL = new MySQL();</pre>
<p>The class constructor will perform a connection to the database automatically. To execute statements simply use:</p>
<pre name="code" class="php">$oMySQL->ExecuteSQL($query);</pre>
<p>There&#8217;s plenty more to do with this class, such as get instantly arrayed results using:</p>
<pre name="code" class="php">$oMySQL->ArrayResults();</pre>
<p>Or:</p>
<pre name="code" class="php">$oMySQL->ArrayResultsWithKey();</pre>
<p>So have a play and let me know what you think &#8230;or fork me!</p>
<p>The code is all here:</p>
<p><a href="http://github.com/a1phanumeric/PHP-MySQL-Class">http://github.com/a1phanumeric/PHP-MySQL-Class</a></p>
]]></content:encoded>
			<wfw:commentRss>http://edrackham.com/php/simple-php-mysql-class/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Get Random Row with MySQL Without ORDER BY RAND()</title>
		<link>http://edrackham.com/featured/get-random-row-with-mysql-without-order-by-rand/</link>
		<comments>http://edrackham.com/featured/get-random-row-with-mysql-without-order-by-rand/#comments</comments>
		<pubDate>Wed, 05 Mar 2008 12:12:24 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[Featured]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[fast]]></category>
		<category><![CDATA[random row]]></category>

		<guid isPermaLink="false">http://edrackham.com/mysql/get-random-row-with-mysql-without-rand/</guid>
		<description><![CDATA[This is an update to a previous post of mine which uses the RAND() method. Using the following code, you can retrieve a random row much, much faster (MySQL 4.1.x/5.0.x), with thanks to Jan Kneschke: SELECT FROM AS r1 JOIN (SELECT ROUND( RAND( ) * ( SELECT MAX( id ) FROM ) ) AS id [...]]]></description>
			<content:encoded><![CDATA[<p>This is an update to a <a href="http://edrackham.com/php/get-random-row-with-mysql/" title="Slower, but useful for smaller tables">previous post of mine</a> which uses the RAND() method. Using the following code, you can retrieve a random row much, much faster (MySQL 4.1.x/5.0.x), with thanks to Jan Kneschke:</p>
<p>SELECT <COLUMN> FROM <TABLE> AS r1<br />
JOIN (SELECT ROUND(<br />
  RAND( ) * (<br />
    SELECT MAX( id ) FROM <TABLE>)<br />
  ) AS id<br />
) AS r2<br />
WHERE r1.id >= r2.id<br />
ORDER BY r1.id ASC<br />
LIMIT 1;</pre>
<p><div align="center" style="margin-bottom: 20px;">
<script type="text/javascript"><!--
google_ad_client = "pub-4159646232668987";
google_ad_slot = "5003066961";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div></p>
<p>Replace:</p>
<ul>
<li><strong>&lt;COLUMN&gt;</strong> with the name of the column(s) you wish to retrieve</li>
<li><strong>&lt;TABLE&gt;</strong> with the name of the table you wish to retrieve the data from</li>
</ul>
<p>I've tested this with a table with over 660,000 records, and got a response in 0.0200 seconds, whereas with ORDER BY RAND() i got a response in 2.1599 seconds.</p>
<h4>Total Number of Rows:</h4>
<p><img src="http://edrackham.com/images/posts/num-rows.gif" alt="Cardinality" style="border:1px solid #ccc" /></p>
<h4>Old Method:</h4>
<p><img src="http://edrackham.com/images/posts/faster-rand-mysql-old-query.gif" alt="Old Method" style="border:1px solid #ccc" /></p>
<h4>New Method:</h4>
<p><img src="http://edrackham.com/images/posts/faster-rand-mysql-new-query.gif" alt="New Method" style="border:1px solid #ccc" /></p>
<p><div align="center" style="margin-bottom: 20px;">
<script type="text/javascript"><!--
google_ad_client = "pub-4159646232668987";
google_ad_slot = "5003066961";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div></p>
]]></content:encoded>
			<wfw:commentRss>http://edrackham.com/featured/get-random-row-with-mysql-without-order-by-rand/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Get Random Row with MySQL</title>
		<link>http://edrackham.com/php/get-random-row-with-mysql/</link>
		<comments>http://edrackham.com/php/get-random-row-with-mysql/#comments</comments>
		<pubDate>Sat, 09 Feb 2008 00:51:31 +0000</pubDate>
		<dc:creator>Ed</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://edrackham.com/php/get-random-row-with-mysql/</guid>
		<description><![CDATA[UPDATE: Please see my newer atricle on how to retrieve a random row, faster, without RAND(). This post assumes you know how to create and use a connection to a MySQL database in PHP and have a table named &#8216;quotes&#8217; as shown below. In this post, I will aim to teach you how to use [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE:</strong> Please see my newer atricle on <a href="http://edrackham.com/mysql/get-random-row-with-mysql-without-rand/" title="Blink, and you'll miss it!">how to retrieve a random row, faster, without RAND()</a>.</p>
<p><div align="center" style="margin-bottom: 20px;">
<script type="text/javascript"><!--
google_ad_client = "pub-4159646232668987";
google_ad_slot = "5003066961";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div></p>
<p>This post assumes you know how to create and use a connection to a MySQL database in PHP and have a table named &#8216;quotes&#8217; as shown below. In this post, I will aim to teach you how to use PHP to pull random quotes from a MYSQL table of quotes. This can be easily extended to pull a random banner as will be explained at the end of the post.</p>
<p>Let&#8217;s firstly assume we have a MySQL table similar to the following:</p>
<pre>+----+------------------------------------------------+
| id | quote                                          |
+----+------------------------------------------------+
| 1  | I know Karate... and many other Chinese words! |
+----+------------------------------------------------+
| 2  | w00t this is geeky                             |
+----+------------------------------------------------+
| 3  | You're CLINICALLY MENTAL!                      |
+----+------------------------------------------------+</pre>
<p><div align="center" style="margin-bottom: 20px;">
<script type="text/javascript"><!--
google_ad_client = "pub-4159646232668987";
google_ad_slot = "5003066961";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div></p>
<p>Now, in your PHP code, we need to:</p>
<ol>
<li>Build a suitable MySQL query to obtain a random result from the &#8216;quotes&#8217; table.</li>
<li>Store the result of the query to be used in the HTML somewhere.</li>
<li>Output the result in the HTML somewhere.</li>
</ol>
<p>So, for step one we&#8217;d use something like the following:</p>
<pre name="code" class="php">$sSQLQuery = "SELECT quote FROM quotes ORDER BY RAND() LIMIT 1";
$aResult = mysql_query($sSQLQuery);
$aRow = mysql_fetch_array($aResult, MYSQL_ASSOC);
$sQuoteOfTheDay = $aRow['quote'];</pre>
<p>There, the variable &#8216;$sQuoteOfTheDay&#8217; now has the value of our randomly pulled quote. Let&#8217;s just analyse each line of the code above to see what it does.</p>
<pre name="code" class="php">$sSQLQuery = "SELECT quote FROM quotes ORDER BY RAND() LIMIT 1";</pre>
<p>This line stores the MySQL query we&#8217;re going to use against the database. It says, in laymans terms, &#8220;Select just one random value of the quote field from the table named quotes&#8221;. All this line does though is store the query into the variable &#8216;$sSQLQuery&#8217;.</p>
<pre name="code" class="php">$aResult = mysql_query($sSQLQuery);</pre>
<p>This line runs the MySQL query, storing the result of running the query in the variable &#8216;$aResult&#8217;. It&#8217;s important that we store the result of the mysql_query in a variable, as the result of running a successful MySQL query using PHP&#8217;s function &#8216;mysql_query&#8217; doesn’t return a nicely formatted array that we can necessarily use.</p>
<pre name="code" class="php">$aRow = mysql_fetch_assoc($aResult);</pre>
<p>This is probably the hardest line for me to explain. Firstly, many of you may have seen a similar line like this used in a &#8216;while&#8217; loop. However, our MySQL query used the &#8216;LIMIT 1&#8242; string, so we know we’re only going to get ONE result, hence no need for a loop. The function &#8216;mysql_fetch_assoc&#8217; takes one parameter: the result of the successful &#8216;mysql_query&#8217; which as we know is &#8216;$aResult&#8217;. My biggest tip here is to use the &#8216;assoc&#8217; method wherever possible, as it creates the array in such a way that we can reference each element by the column name, not a number. This is particularly useful if you ever update the MySQL table to have more columns.</p>
<p>Anyway, this line basically says &#8216;Fill the variable &#8216;$aRow&#8217; with the CURRENT row of the returned query&#8217;. We know that the CURRENT row of the returned query is the ONLY row, hence (again) the lack of a loop. As the result of our query would return something like:</p>
<pre>+-----------------------------------------------+
| quote                                         |
+-----------------------------------------------+
| You're CLINICALLY MENTAL!                     |
+-----------------------------------------------+</pre>
<p><div align="center" style="margin-bottom: 20px;">
<script type="text/javascript"><!--
google_ad_client = "pub-4159646232668987";
google_ad_slot = "5003066961";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div></p>
<p>Our variable (or array) would literally look something like:</p>
<pre name="code" class="php">Array ( "quote" = "You're CLINICALLY MENTAL!" )</pre>
<p>Which leads us on to our last line:</p>
<pre name="code" class="php">$sQuoteOfTheDay = $aRow['quote'];</pre>
<p>Which just assigns the value of &#8216;$aRow['quote']&#8216; to the variable &#8216;$sQuoteOfTheDay&#8217;. In other words, &#8216;$sQuoteOfTheDay&#8217; now has the value of a random quote pulled from the database of quotes.</p>
<p>To use this in an HTML page, we would simply just use this (AFTER the above code has grabbed the random quote from the DB for us):</p>
<pre name="code" class="php">echo $sQuoteOfTheDay;</pre>
<p>Which will output the quote of the day somewhere in the HTML code.</p>
<p>As I said at the beginning, this can be extended easily to pull an image for a banner by simply changing the quotes table to store image paths such as &#8216;images/my_image.png&#8217; which can then be pulled in the same way, and then output similar to the following:</p>
<pre name="code" class="php"><img src="<?= $sImageOfTheDay; ?>" alt="My Image" /></pre>
<p>Obviously we changed the variable name here to $sImageOfTheDay just to keep things constant.</p>
<p>Hope this has helped someone!</p>
]]></content:encoded>
			<wfw:commentRss>http://edrackham.com/php/get-random-row-with-mysql/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

