1.7. Registering a New User

With the directory structure laid out and enough of the support code written, the focus can now move to registering a new user. The following code can be saved in the public_files folder as register.php. Figure 1-2 shows the page viewed in a browser.

Figure 1-2. Figure 1-2

<?php
// include shared code
include '../lib/common.php';
include '../lib/db.php';
include '../lib/functions.php';
include '../lib/User.php';

// start or continue session so the CAPTCHA text stored in $_SESSION is
// accessible
session_start();
header('Cache-control: private'),

// prepare the registration form's HTML
ob_start();
?>
<form method="post"
 action="<?php echo htmlspecialchars($_SEVER['PHP_SELF']); ?>">
 <table>
  <tr>
   <td><label for="username">Username</label></td>
   <td><input type="text" name="username" id="username"
    value="<?php if (isset($_POST['username']))
    echo htmlspecialchars($_POST['username']); ?>"/></td>
  </tr><tr>
   <td><label for="password1">Password</label></td>
   <td><input type="password" name="password1" id="password1"
    value=""/></td>
  </tr><tr>

<td><label for="password2">Password Again</label></td>
   <td><input type="password" name="password2" id="password2"
    value=""/></td>
  </tr><tr>
   <td><label for="email">Email Address</label></td>
   <td><input type="text" name="email" id="email"
    value="<?php if (isset($_POST['email']))
    echo htmlspecialchars($_POST['email']); ?>"/></td>
  </tr><tr>
   <td><label for="captcha">Verify</label></td>
   <td>Enter text seen in this image<br/ >
   <img src="img/captcha.php?nocache=<?php echo time(); ?>" alt=""/><br />
   <input type="text" name="captcha" id="captcha"/></td>
  </tr><tr>
   <td> </td>
   <td><input type="submit" value="Sign Up"/></td>
   <td><input type="hidden" name="submitted" value="1"/></td>
  </tr><tr>
 </table>
</form>
<?php
$form = ob_get_clean();

// show the form if this is the first time the page is viewed
if (!isset($_POST['submitted']))
{
    $GLOBALS['TEMPLATE']['content'] = $form;
}

// otherwise process incoming data
else
{
    // validate password
    $password1 = (isset($_POST['password1'])) ? $_POST['password1'] : '';
    $password2 = (isset($_POST['password2'])) ? $_POST['password2'] : '';
    $password = ($password1 && $password1 == $password2) ?
        sha1($password1) : '';

    // validate CAPTCHA
    $captcha = (isset($_POST['captcha']) &&
        strtoupper($_POST['captcha']) == $_SESSION['captcha']);

    // add the record if all input validates
    if (User::validateUsername($_POST['username']) && password &&
        User::validateEmailAddr($_POST['email']) && $captcha)
    {
        // make sure the user doesn't already exist
        $user = User::getByUsername($_POST['username']);
        if ($user->userId)
        {
            $GLOBALS['TEMPLATE']['content'] = '<p><strong>Sorry, that ' .
                'account already exists.</strong></p> <p>Please try a ' .

'different username.</p>';
            $GLOBALS['TEMPLATE']['content'] .= $form;
        }
        else
        {
            // create an inactive user record
            $user = new User();
            $user->username = $_POST['username'];
            $user->password = $password;
            $user->emailAddr = $_POST['email'];
            $token = $user->setInactive();

            $GLOBALS['TEMPLATE']['content'] = '<p><strong>Thank you for ' .
                'registering.</strong></p> <p>Be sure to verify your ' .
                'account by visiting <a href="verify.php?uid=' .
                $user->userId . '&token=' . $token . '">verify.php?uid=' .
                $user->userId . '&token=' . $token . '</a></p>';
         }
    }
    // there was invalid data
    else
    {
        $GLOBALS['TEMPLATE']['content'] .= '<p><strong>You provided some ' .
            'invalid data.</strong></p> <p>Please fill in all fields ' .
            'correctly so we can register your user account.</p>';
        $GLOBALS['TEMPLATE']['content'] .= $form;
    }
}

// display the page
include '../templates/template-page.php';
?>

The first thing register.php does is import the shared code files it depends on. Some programmers prefer to place all the include statements in one common header file and include that for shorter code. Personally, however, I prefer to include them individually as I find it easier to maintain.

Other programmers may use chdir() to change PHP's working directory so they don't have to repeatedly backtrack in the file system to include a file. Again, this is a matter of personal preference. Be careful with this approach, however, when targeting older installations of PHP that use safe mode. chdir() may fail without generating any kind of error message if the directory is inaccessible.

<?php
// include shared code
chdir('../'),
include 'lib/common.php';
include 'lib/db.php';
include 'lib/functions.php';
include 'lib/User.php';
...
?>

After importing the shared code files I call session_start(). HTTP requests are stateless, which means the web server returns each page without tracking what was done before or anticipating what might happen next. PHP's session tracking gives you an easy way to maintain state across requests and carry values from one request to the next. A session is required for keeping track of the CAPTCHA value generated by captcha.php.

I like to use output buffering when preparing large blocks of HTML such as the registration form, for greater readability. Others may prefer to maintain a buffer variable and repeatedly append to it throughout the script, like so:

<?php
$GLOBALS['TEMPLATE']['content'] = '<form action="'.
     htmlspecialchars(currentFile()) . '" method="post">';
$GLOBALS['TEMPLATE']['content'] .= '<table>';
$GLOBALS['TEMPLATE']['content'] .= '<tr>';
$GLOBALS['TEMPLATE']['content'] .= '<td><label for="username">Username</label>' .
 '</td>';
...
?>

I find that approach becomes rather cumbersome relatively fast. With output buffering, all I need to do is start the capturing with ob_start(), retrieve the buffer's contents with ob_get_contents(), and stop capturing with ob_end_clean(). ob_get_clean() combines ob_get_contents() and ob_end_clean() in one function call. It's also easier for the engine to fall in and out of PHP mode so such code with large blocks of output would theoretically run faster than with the buffer concatenation method.

No $_POST values should be received the first time a user views the page so the code just outputs the registration form. When the user submits the form, the $_POST['submitted'] variable is set and it knows to start processing the input.

The validation code to check the use rname and password are part of the User class. The two password values are compared against each other and then the password's hash is saved for later storage. Finally, the user's CAPTCHA input is checked with what was previously stored in the session by captcha.php. If everything checks out, the record is added to the database.

The verify.php script referenced in the HTML code is responsible for taking in a user ID and activation token, checking the corresponding values in the database, and then activating the user's account. It must be saved in the publically accessible directory as well.

<?php
// include shared code
include '../lib/common.php';
include '../lib/db.php';
include '../lib/functions.php';
include '../lib/User.php';

// make sure a user id and activation token were received
if (!isset($_GET['uid']) || !isset($_GET['token']))
{
    $GLOBALS['TEMPLATE']['content'] = '<p><strong>Incomplete information ' .
        'was received.</strong></p> <p>Please try again.</p>';

include '../templates/template-page.php';
    exit();
}

// validate userid
if (!$user = User::getById($_GET['uid']))
{
    $GLOBALS['TEMPLATE']['content'] = '<p><strong>No such account.</strong>' .
        '</p> <p>Please try again.</p>';
}
// make sure the account is not active
else
{
    if ($user->isActive)
    {
        $GLOBALS['TEMPLATE']['content'] = '<p><strong>That account ' .
            'has already been verified.</strong></p>';
    }
    // activate the account
    else
    {
        if ($user->setActive($_GET['token']))
        {
            $GLOBALS['TEMPLATE']['content'] = '<p><strong>Thank you ' .
                'for verifying your account.</strong></p> <p>You may ' .
                'now <a href="login.php">login</a>.</p>';
        }
        else
        {
            $GLOBALS['TEMPLATE']['content'] = '<p><strong>You provided ' .
                'invalid data.</strong></p> <p>Please try again.</p>';
        }
    }
}

// display the page
include '../templates/template-page.php';
?>

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.197.212