Jump to content

Any help for a PHP newb?


daneth1712

Recommended Posts

Hi all members of phpfreaks... I hope this is the place that will help me out of a little situation I have been lumbered with  :-\

 

Basically, with an extremely basic understanding and knowledge of php/mysql I have been stuck with the task of creating certain functions for a website. These functions in time will no doubt grow into something alot bigger, but for the time being I need to be able to implement the following;

 

1. a registration form that collects and stores the info into an mysql database, send emails etc etc.

2. an activation process where by the user would enter info that was originally received from the registration form, if page one info is correct, it goes to second page where they input some more info which gets stored.

3. a secure login system and secure area only resticted to those logged in.

 

Part 1 has already been done and works fine, its the other 2 that I wouldnt know where to start.

 

I have looked around at various scripts on the web, but none have really worked for me. I have also tried writing them from scratch and checking various websites to see how to write certains parts. I have enough knowledge to be able to look at php and understand what it does and how, however I have no experience of writing it myself, which is where this all kinda falls down around me....

 

If there are some people about that would be able to offer some help and guidance you would be saving me life!

 

I am sorry to all the experts out there.... seeing a newb like me on here must drive you all mad. ;)

Link to comment
Share on other sites

I assume you are using MySQL the provided code is not entirely portable so you may need the appropriate manual for your specific db vendor.

 

For part 2: add an is_activated column of type BOOLEAN NOT NULL DEFAULT FALSE and activation_code column of type VARCHAR(40) (and an optionally activated_at column of type DATE)

 

Upon registration fill theses columns:

INSERT INTO users (.., activation_code) VALUES (.., SHA1(NOW())) -- Or some other code

 

Upon activation:

UPDATE users SET is_activated = TRUE, activated_at = NOW() WHERE id = $userId AND activation_code = $activationCode

 

Upon login:

SELECT * FROM users WHERE username = $username AND password = $password

 

$result = mysql_query($query);
if (mysql_num_rows($result) === 1) {
    $row = mysql_fetch_assoc($result);
    if (!$row['is_activated']) {
        //not yet activated, close
    }
} else {
    //user not found
}

Link to comment
Share on other sites

You should also look into creating and using sessions.  That will help you make sure no one user can be logged in multiple times at once.

 

Adding registration information to the database is easy, lookup and study mysql queries.

 

To verify the user's email address you could create a random hexadecimal string with every registration, add that to the database and then send the e-mail with the code for confirmation.  The user would then have to input the correct string before you change their user status to activated.

 

Link to comment
Share on other sites

Hi ignace,

 

Just to clarify, I am having to using WAMP on windows. This is not down to my choice, however it is a dedicated server so I have full access to its config files. Its running PHP version 5.2.9 and MySQL version 5.1.33 on Apache server version 2.2.11.

 

OK, well I have 'part' of my login page done, however I went down the route of using cookies, which I have found out are not good to use and to use SESSIONS instead.... I dont really understand how to use sessions, any pointers on offer would be great.

 

<?php
include 'config.php';
ob_start();
echo "Login<br>";
echo "<form action=\"./login.php\" method=\"POST\">";
echo "Username: <br><input type=\"text\" name=\"username\"><br>";
echo "Password: <br><input type=\"password\" name=\"password\"><br>";
echo "<input type=\"submit\" value=\"Login!\">";
echo "</form>";
echo "<br>Dont have an account? Register <a href=\"test.html\">here!</a>";

@$username = ($_POST['username']);
@$password = ($_POST['password']);

$connection = @mysql_connect($hostname, $user, $pass)
or die(mysql_error());
$dbs = @mysql_select_db($database, $connection) or
die(mysql_error());

$sql = "SELECT * FROM 'userinfo' WHERE username = '$username' AND password = '$password'";
$result = @mysql_query($sql,$connection) or die(mysql_error());
$num = @mysql_num_rows($result);

if ($num == 1) {
$cookie_name = "authorised";
$cookie_value = "loggedin";
$cookie_expire = "0";
$cookie_domain = $domain;

setcookie($cookie_name, $cookie_value, $cookie_expire, "/", $cookie_domain, 0);
header ("Location: http://" . $domain . $directory . "index.php");

ob_end_flush();

exit;
}
?>

 

This is then the cookie check on the index.php file. I also get an error on line 3 to do with the $tmp = $_GET['action']; but the logout seems to work fine...

 

I assume I would have had to use this code on every page that I wanted pages auth'ed had I stuck with cookies???

 

include 'config.php';
$tmp = $_GET['action'];
if($tmp == "signout"){
$cookie_name = "authorised";
$cookie_value = "";
$cookie_expire = "0";
$cookie_domain = $domain;
setcookie($cookie_name, $cookie_value, $cookie_expire, "/", $cookie_domain, 0);
header ("Location: http://" . $domain . $directory . "login.php");
}

if($_COOKIE['auth'] == "loggedin"){
echo "This is where everything secured needs to be kept.";

echo "<br><a href=\"admin.php?action=signout\">Sign Out</a>";
}else{
header ("Location: http://" . $domain . $directory . "login.php");
exit;
}
?>

 

The registration form is a long page with lots of columns, and I have already added tables etc and this works fine. The process after that would be the activation page, this is not something that will be done immediately after registration, as a code will be sent to the user to input into the activation page. This process is going to be broken down into 2 or 3 pages.

 

The first page will be a form with 2 fields, Name and Email.

 

If that matches in following statement from my poorly formed and uncomplete activation page...

$sql = "SELECT * FROM `userinfo` WHERE name = '$name' AND email_address = '$email'";
$result = @mysql_query($sql,$connection) or die(mysql_error());

 

then...

 

if ($result) {
while ($array= mysql_fetch_assoc($result)) {
echo "<h4><b>$name</b></h4><h4><b>$email</b></h4>\n";}{
header ("Location: ....");}
} 

else {
print "<li>No results. 2</li>";
}

There is obviously no design input yet as you can tell ;)

 

What I dont know how to do is use this info, and transfer the data to the next page, that once it has identified the user that another form can be completed where the activation code is entered, along with creating a username and password for the login process at the top. I obviously need to use SESSIONS across everything and include them within each of the restricted pages. Any help is really appreciated.

Link to comment
Share on other sites

You should also look into creating and using sessions.  That will help you make sure no one user can be logged in multiple times at once.

 

That's not what a session is. A session helps you to store information server-side instead of using it's alternative: client-side cookies. And if you want to allow a user to only login once you'd need to store each session id and upon login verify if their isn't already a session with the specified username.

Link to comment
Share on other sites

I also get an error on line 3 to do with the $tmp = $_GET['action'];

 

Change to:

$tmp = empty($_GET['action']) ? $_GET['action'] : 'default';

change default to anything to what it should fall back.

 

What I dont know how to do is use this info, and transfer the data to the next page, that once it has identified the user that another form can be completed where the activation code is entered, along with creating a username and password for the login process at the top

 

Store the information in your session $_SESSION['name'] = $name; Then on the activation page where he enters his activation code (altough you can bypass this by providing a link in to the e-mail &activation_code=5q37t453qh4gq activate the user and direct to some page) verify the data exists if (isset($_SESSION['name'])) {..exists..} else {..don't..exist..} and redirect them if it doesn't.

 

Here is some more advice:

 

Don't use @ it will make it hard to debug.

 

@$username = ($_POST['username']);

 

Don't use "or die()" your users don't understand what "MySQL Error 1062: .." means. They may even believe they broke it and wil leave your website with a feeling of guilt probably to never return again and you'd be given away information to hackers. Instead use:

 

Add a system environment variable (if you don't know how look it up) named DEBUG and give it the value 1

 

define('DEBUG', getenv('DEBUG') ? getenv('DEBUG') : false);
$defaultErrorHandler = null;
if (DEBUG) {
    error_reporting(E_ALL);
    ini_set('display_errors', TRUE);
    ini_set('log_errors', FALSE);
} else {
    error_reporting(0);
    ini_set('display_errors', FALSE);
    ini_set('log_errors', TRUE);//also report the error in error.log
    $defaultErrorHandler = set_error_handler('error_handler');
}

ob_start();//keep everything in the buffer until we flush it

function error_handler($errno, $errstr, $errfile = '', $errline = 0, array $errcontext = array()) {
     //no errors will be displayed
     if (!headers_sent()) {
         header('Location: /error404.php');
     } else {
         ob_end_clean();//whatever there was we don't need it anymore.
         require_once('error404.php');
     }
}

 

Now whenever you edit your website locally you'll get full error reporting and when you upload your files to your server your error_handler() will kick in (because the server doesn't have the DEBUG environment variable). Use trigger_error() to use the error_handler()

Link to comment
Share on other sites

Hi Guys,

 

Thanks for your replies, found out some interesting stuff!!!

 

Ok, I have completely changed the login function now. Had to go with sessions instead of cookies, I have been told this is a safer approach.

 

here is my login.php page.

<?php
$username=($_POST['username']);
$password=($_POST['password']);

//send back to the login form if page is called from other location
if (!isset($username) || !isset($password)) {
header( "Location: index.html" );
}
elseif (empty($username) || empty($password)) {
header( "Location: index.html" );
}
else{
//add slashes to the username and protect the password with md5
$user = addslashes($_POST['username']);
$pass = md5($_POST['password']);

//set the database connection variables
include('includes/config.php');

//connect to the database
$db = mysql_connect("$hostname", "$adminuser", "$adminpass") or die ("Error connecting to database.");
mysql_select_db("$database", $db) or die ("Couldn't select the database.");
$result=mysql_query("select * from userinfo where username='$user' AND password='$pass'", $db);

//check that at least one row was returned
$row = mysql_num_rows($result);
if($row == 1){
while($row = mysql_fetch_array($result)){

//start the session and register variable to username
session_start();
session_register('username');
?>

 

then I just place the following code in an include file to the top of each page that needs to be secured.

 

<?php
//start the session
session_start();

//check to make sure the session username variable is registered
if(session_is_registered('username')){
$id=$_SESSION['username'];
}
else{
//the session variable isn't registered, send them back to the login page
header( "Location: index.html" );
}
?>

 

This seems to work fine, however I wanted to see if anyne had any thing to suggest or could advise if I am doing something wrong?

 

The next thing I need to do is create a 3 page form that moves the data from one page to the next, not sure where to begin and how to be able to call from other columns in a row that have not been expressed for in the forms.

Link to comment
Share on other sites

login.php

//verify their was actually something posted..
if (empty($_POST))/*nothing posted*/header('Location: index.html');

$username=!empty($_POST['username']) ? $_POST['username'] : null;
$password=!empty($_POST['password']) ? $_POST['password'] : null;

 

Replace:

if (!isset($username) || !isset($password)) {
header( "Location: index.html" );
}
elseif (empty($username) || empty($password)) {
header( "Location: index.html" );
}

 

With:

if (!$username || !$password) {//one or both are left blank
    header('Location: index.html');
}

 

Enclose repeating tasks:

$user = addslashes($_POST['username']);
$pass = md5($_POST['password']);

 

function clean($variable, $allow_tags = false) {
    if (!get_magic_quotes_gpc()) {
        $variable = addslashes($variable);
    }
    if (!$allow_tags) {
        $variable = strip_tags($variable);
    }
    return htmlentities(trim($variable));
}

$user = clean($_POST['username']);
$pass = md5(clean($_POST['password']));

 

Encapsulate application behavior so it may be used anywhere and only has to be modified at one place:

 

//$username and $password have to be validated before calling login() otherwise you wouldn't be able to set appropriate form errors.
function login($username, $password) {// if (!login($username, $password)) { //login failed
    global $db, $config;
    if (!$db) trigger_error('Authentication can not proceed. Database connection not available.');//report silently
    if (!session_id()) trigger_error('Authentication can not proceed. Session hasn\'t yet been started.');
    $logged_in = false;
    $username = mysql_real_escape_string($username);
    $password = mysql_real_escape_string($password);
    $query = "SELECT id, username FROM users WHERE username = '$username' AND password = '$password'";
    $result = mysql_query($query, $db);
    if (mysql_num_rows($result) === 1) {
        $record = mysql_fetch_assoc($result);
        $logged_in = true;
        //make sure that $config['auth_key'] contains a value that you won't use easy
        $_SESSION[$config['auth_key']] = $record;
    }
    return $logged_in;
}

function is_logged_in() {
    return !empty(get_user_session_info());
}

function get_user_session_info() {
    global $config;
    $auth_key = $config['auth_key'];
    return !empty($_SESSION[$auth_key]) ? $_SESSION[$auth_key] : array();
}

 

Create validators for information that is the same over the entire website:

 

function is_valid_username($username) {
   $strlen = strlen($username);
   return ctype_alpha($username) && ($strlen > 8 && $strlen < 16);
}

function is_valid_password($password) {
   $strlen = strlen($password);
   return ($strlen > 6 && $strlen < 16) && preg_match('[A-Za-z0-9]', $password);
}

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.