我有一个非常复杂的登录脚本,其中包含 4 个类。
如果用户正确输入他们的详细信息,则表单中的登录会正确登录,但由于某种原因,如果他们输入不正确的数据,则错误消息将无法显示。
我会发布我所有的代码,并尽我所能解释每一点。:)
好的,所以我的登录表单
<?php
include("include/user.php");
?>
<h2>Sign In</h2>
<?php
echo $user->form->num_errors; //nothing prints from this so its not getting the value or its not being set correctly?
print_r($_SESSION['error_array']);// this prints out the errors stored in the session correctly
if($form->num_errors > 0)
{
echo "<font size=\"2\" color=\"#ff0000\">".$form->num_errors." error(s) found</font>";
}?>
<form action="process.php" method="POST">
<table align="left" border="0">
<tr>
<td><span>Email: <?php echo $user->form->error("user"); ?></span></td>
</tr>
<tr>
<td><input type="text" name="user" maxlength="30" value="<?php echo $user->form->value("user"); ?>"></td>
</tr>
<tr>
<td><span>Password: <?php echo $user->form->error("pass"); ?></span></td>
</tr>
<tr>
<td><input type="password" name="pass" maxlength="30" value="<?php echo $user->form->value("pass"); ?>"></td>
</tr>
<tr>
<td colspan="2" align="left"><div class="forgotpass">Forgot Your <a href="forgotpass.php">Password</a>?</div></td>
<td align="right"></td>
</tr>
<tr>
<td colspan="2" align="left"><div class="remember"><label><input type="checkbox" name="remember" <?php if($user->form->value("remember") != ""){ echo "checked"; } ?>>
Remember me </label><br />(Untick this if on a public computer) </div>
<input type="hidden" name="sublogin" value="1"></td>
</tr>
<tr>
<td><input class="button orange" type="submit" value="Login"></td>
</tr>
</table>
</form>
表单操作设置为 process.php 及其已提交的子登录
process.php 是
include("include/user.php");
class Process
{
public function __construct()
{
global $user;
/* User submitted login form */
if(isset($_POST['sublogin']))
{
$this->procLogin();
}
/* User submitted registration form */
else if(isset($_POST['subjoin']))
{
$this->procRegister();
}
/* User submitted forgot password form */
else if(isset($_POST['subforgot']))
{
$this->procForgotPass();
}
/* User submitted edit account form */
else if(isset($_POST['subedit']))
{
$this->procEditAccount();
}
/**
* The only other reason user should be directed here
* is if he wants to logout, which means user is
* logged in currently.
*/
else if($user->logged_in)
{
$this->procLogout();
}
/**
* Should not get here, which means user is viewing this page
* by mistake and therefore is redirected.
*/
else
{
header("Location: index.php");
}
}
/**
* procLogin - Processes the user submitted login form, if errors
* are found, the user is redirected to correct the information,
* if not, the user is effectively logged in to the system.
*/
function procLogin()
{
global $user;
/* Login attempt */
$retval = $user->login($_POST['user'], $_POST['pass'], isset($_POST['remember']));
/* Login successful */
if($retval)
{
$host = $_SERVER['HTTP_HOST'];
$uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\');
$extra = 'index.php';
header("Location: http://$host$uri/$extra");
}
/* Login failed */
else
{
$_SESSION['value_array'] = $_POST;
$_SESSION['error_array'] = $user->form->getErrorArray();
header("Location: ".$user->referrer);
}
}
/**
* procLogout - Simply attempts to log the user out of the system
* given that there is no logout form to process.
*/
function procLogout()
{
global $user;
$retval = $user->logout();
header("Location: ".$user->referrer);
#header("Location: main.php");
}
/**
* procRegister - Processes the user submitted registration form,
* if errors are found, the user is redirected to correct the
* information, if not, the user is effectively registered with
* the system and an email is (optionally) sent to the newly
* created user.
*/
function procRegister()
{
global $form, $user;
/* Convert username to all lowercase (by option) */
if(ALL_LOWERCASE)
{
$_POST['email'] = strtolower($_POST['email']);
}
/* Registration attempt */
$retval = $user->register($_POST['email'],$_POST['fname'],$_POST['lname'],$_POST['pass'],$_POST['pass-confirm']);
/* Registration Successful */
if($retval == 0)
{
$_SESSION['reguname'] = $_POST['email'];
$_SESSION['regsuccess'] = true;
header("Location: ".$user->referrer);
}
/* Error found with form */
else if($retval == 1)
{
$_SESSION['value_array'] = $_POST;
$_SESSION['error_array'] = $form->getErrorArray();
header("Location: ".$user->referrer);
}
/* Registration attempt failed */
else if($retval == 2)
{
$_SESSION['reguname'] = $_POST['email'];
$_SESSION['regsuccess'] = false;
header("Location: ".$user->referrer);
}
}
/**
* procForgotPass - Validates the given username then if
* everything is fine, a new password is generated and
* emailed to the address the user gave on sign up.
*/
function procForgotPass()
{
global $mailer, $form;
/* Username error checking */
$subuser = $_POST['user'];
$field = "user"; //Use field name for username
if(!$subuser || strlen($subuser = trim($subuser)) == 0)
{
$form->setError($field, "* Username not entered<br>");
}
else
{
/* Make sure username is in database */
$subuser = stripslashes($subuser);
if(strlen($subuser) < 5 || strlen($subuser) > 30 || !eregi("^([0-9a-z])+$", $subuser) || (!$user->usernameTaken($subuser)))
{
$form->setError($field, "* Username does not exist<br>");
}
}
/* Errors exist, have user correct them */
if($form->num_errors > 0)
{
$_SESSION['value_array'] = $_POST;
$_SESSION['error_array'] = $form->getErrorArray();
}
/* Generate new password and email it to user */
else
{
/* Generate new password */
$newpass = $user->generateRandStr(8);
/* Get email of user */
$usrinf = $user->getUserInfo($subuser);
$email = $usrinf['email'];
/* Attempt to send the email with new password */
if($mailer->sendNewPass($subuser,$email,$newpass))
{
/* Email sent, update database */
$user->updateUserField($subuser, "password", md5($newpass));
$_SESSION['forgotpass'] = true;
}
/* Email failure, do not change password */
else
{
$_SESSION['forgotpass'] = false;
}
}
header("Location: ".$user->referrer);
}
/**
* procEditAccount - Attempts to edit the user's account
* information, including the password, which must be verified
* before a change is made.
*/
function procEditAccount()
{
global $form, $user;
/* Account edit attempt */
$retval = $user->editAccount($_POST['curpass'], $_POST['newpass'], $_POST['email']);
/* Account edit successful */
if($retval)
{
$_SESSION['useredit'] = true;
header("Location: ".$user->referrer);
}
/* Error found with form */
else
{
$_SESSION['value_array'] = $_POST;
$_SESSION['error_array'] = $form->getErrorArray();
header("Location: ".$user->referrer);
}
}
}
/* Initialize process */
$process = new Process($user);
?>
由于 sublogin 提交,上面的代码调用了用户类中的 $user->login
<?php
include("include/database.php");
include("include/mailer.php");
include("include/form.php");
include("constants.php");
class user
{
var $username; //Username given on sign-up
var $firstname;
var $lastname;
var $userid; //Random value generated on current login
var $userlevel; //The level to which the user pertains
var $time; //Time user was last active (page loaded)
var $logged_in; //True if user is logged in, false otherwise
var $userinfo = array(); //The array holding all user info
var $url; //The page url current being viewed
var $referrer; //Last recorded site page viewed
var $num_active_users; //Number of active users viewing site
var $num_active_guests; //Number of active guests viewing site
var $num_members; //Number of signed-up users
/**
* Note: referrer should really only be considered the actual
* page referrer in process.php, any other time it may be
* inaccurate.
*/
public function __construct(db $db, Form $form)
{
$this->database = $db;
$this->form = $form;
$this->time = time();
$this->startSession();
$this->num_members = -1;
if(TRACK_VISITORS)
{
/* Calculate number of users at site */
$this->calcNumActiveUsers();
/* Calculate number of guests at site */
$this->calcNumActiveGuests();
}
}
function startSession()
{
session_start(); //Tell PHP to start the session
/* Determine if user is logged in */
$this->logged_in = $this->checkLogin();
/**
* Set guest value to users not logged in, and update
* active guests table accordingly.
*/
if(!$this->logged_in)
{
$this->username = $_SESSION['username'] = GUEST_NAME;
$this->userlevel = GUEST_LEVEL;
$this->addActiveGuest($_SERVER['REMOTE_ADDR'], $this->time);
}
/* Update users last active timestamp */
else
{
$this->addActiveUser($this->username, $this->time);
}
/* Remove inactive visitors from database */
$this->removeInactiveUsers();
$this->removeInactiveGuests();
/* Set referrer page */
if(isset($_SESSION['url']))
{
$this->referrer = $_SESSION['url'];
}
else
{
$this->referrer = "/";
}
/* Set current url */
$this->url = $_SESSION['url'] = $_SERVER['PHP_SELF'];
}
/**
* checkLogin - Checks if the user has already previously
* logged in, and a session with the user has already been
* established. Also checks to see if user has been remembered.
* If so, the database is queried to make sure of the user's
* authenticity. Returns true if the user has logged in.
*/
function checkLogin()
{
/* Check if user has been remembered */
if(isset($_COOKIE['cookname']) && isset($_COOKIE['cookid']))
{
$this->username = $_SESSION['username'] = $_COOKIE['cookname'];
$this->userid = $_SESSION['userid'] = $_COOKIE['cookid'];
}
/* Username and userid have been set and not guest */
if(isset($_SESSION['username']) && isset($_SESSION['userid']) && $_SESSION['username'] != GUEST_NAME)
{
/* Confirm that username and userid are valid */
if($this->confirmUserID($_SESSION['username'], $_SESSION['userid']) != 0)
{
/* Variables are incorrect, user not logged in */
unset($_SESSION['username']);
unset($_SESSION['userid']);
return false;
}
/* User is logged in, set class variables */
$this->userinfo = $this->getUserInfo($_SESSION['username']);
$this->username = $this->userinfo['username'];
$this->userid = $this->userinfo['userid'];
$this->userlevel = $this->userinfo['userlevel'];
$this->lastlogin = $this->userinfo['lastlogin'];
$this->townid = $this->userinfo['placeID'];
return true;
}
/* User not logged in */
else
{
return false;
}
}
/**
* generateRandID - Generates a string made up of randomized
* letters (lower and upper case) and digits and returns
* the md5 hash of it to be used as a userid.
*/
function generateRandID()
{
return md5($this->generateRandStr(16));
}
/**
* generateRandStr - Generates a string made up of randomized
* letters (lower and upper case) and digits, the length
* is a specified parameter.
*/
function generateRandStr($length)
{
$randstr = "";
for($i=0; $i<$length; $i++)
{
$randnum = mt_rand(0,61);
if($randnum < 10)
{
$randstr .= chr($randnum+48);
}
else if($randnum < 36)
{
$randstr .= chr($randnum+55);
}else
{
$randstr .= chr($randnum+61);
}
}
return $randstr;
}
/**
* login - The user has submitted his username and password
* through the login form, this function checks the authenticity
* of that information in the database and creates the session.
* Effectively logging in the user if all goes well.
*/
function login($subuser, $subpass, $subremember)
{
/* Username error checking */
$field = "user"; //Use field name for username
if(!$subuser || strlen($subuser = trim($subuser)) == 0)
{
$this->form->setError($field, "* Username not entered");
}
else
{
/* Check if valid email address */
$regex = "^[_+a-z0-9-]+(\.[_+a-z0-9-]+)*"
."@[a-z0-9-]+(\.[a-z0-9-]{1,})*"
."\.([a-z]{2,}){1}$^";#added ^ at end!!!!!!!!!!!!!!!
if(!preg_match($regex,$subuser))
{
$this->form->setError($field, "* Email invalid");
}
$subuser = stripslashes($subuser);
}
/* Password error checking */
$field = "pass"; //Use field name for password
if(!$subpass)
{
$this->form->setError($field, "* Password not entered");
}
/* Return if form errors exist */
if($this->form->num_errors > 0)
{
return false;
}
/* Checks that username is in database and password is correct */
$subuser = stripslashes($subuser);
$result = $this->confirmUserPass($subuser, md5($subpass));
/* Check error codes */
if($result == 1)
{
$field = "user";
$this->form->setError($field, "* Username not found");
}
else if($result == 2)
{
$field = "pass";
$this->form->setError($field, "* Invalid password");
}
/* Return if form errors exist */
if($this->form->num_errors > 0)
{
return false;
}
/* Username and password correct, register session variables */
$this->userinfo = $this->getUserInfo($subuser);
$this->username = $_SESSION['username'] = $this->userinfo['username'];
$this->firstname = $_SESSION['firstname'] = $this->userinfo['firstname'];
$this->userid = $_SESSION['userid'] = $this->generateRandID();
$this->userlevel = $this->userinfo['userlevel'];
/* Insert userid into database and update active users table */
$this->updateUserField($this->username, "userid", $this->userid);
$this->addActiveUser($this->username, $this->time);
$this->removeActiveGuest($_SERVER['REMOTE_ADDR']);
/**
* This is the cool part: the user has requested that we remember that
* he's logged in, so we set two cookies. One to hold his username,
* and one to hold his random value userid. It expires by the time
* specified in constants.php. Now, next time he comes to our site, we will
* log him in automatically, but only if he didn't log out before he left.
*/
if($subremember)
{
setcookie("cookname", $this->username, time()+COOKIE_EXPIRE, COOKIE_PATH);
setcookie("cookid", $this->userid, time()+COOKIE_EXPIRE, COOKIE_PATH);
}
/* Login completed successfully */
return true;
}
}
$db = new db($config);
$form = new Form;
$user = new User($db, $form);
?>
然后是表单类
class Form
{
var $values = array(); //Holds submitted form field values
var $errors = array(); //Holds submitted form error messages
var $num_errors; //The number of errors in submitted form
/* Class constructor */
function __construct()
{
/**
* Get form value and error arrays, used when there
* is an error with a user-submitted form.
*/
if(isset($_SESSION['value_array']) && isset($_SESSION['error_array']))
{
$this->values = $_SESSION['value_array'];
$this->errors = $_SESSION['error_array'];
$this->num_errors = count($this->errors);
unset($_SESSION['value_array']);
unset($_SESSION['error_array']);
}
else
{
$this->num_errors = 0;
}
}
/**
* setValue - Records the value typed into the given
* form field by the user.
*/
function setValue($field, $value)
{
$this->values[$field] = $value;
}
/**
* setError - Records new form error given the form
* field name and the error message attached to it.
*/
function setError($field, $errmsg)
{
$this->errors[$field] = $errmsg;
$this->num_errors = count($this->errors);
}
/**
* value - Returns the value attached to the given
* field, if none exists, the empty string is returned.
*/
function value($field)
{
if(array_key_exists($field,$this->values))
{
return htmlspecialchars(stripslashes($this->values[$field]));
}
else
{
return "";
}
}
/**
* error - Returns the error message attached to the
* given field, if none exists, the empty string is returned.
*/
function error($field)
{
if(array_key_exists($field,$this->errors))
{
return "<font size=\"2\" color=\"#ff0000\">".$this->errors[$field]."</font>";
}
else
{
return "";
}
}
/* getErrorArray - Returns the array of error messages */
function getErrorArray()
{
return $this->errors;
}
}
但出于某种原因,就像我说的表单错误没有出现?我是 oop 的新手,我意识到我的代码并不出色,但我正在努力:)
还有一个数据库类,但除非你需要它,否则不会发布它。花了很长时间试图让它工作但失败了,任何帮助将不胜感激!
编辑
我认为问题与会话有关,我认为这是因为 Form 类的这一部分
if(isset($_SESSION['value_array']) && isset($_SESSION['error_array']))
{
$this->values = $_SESSION['value_array'];
$this->errors = $_SESSION['error_array'];
$this->num_errors = count($this->errors);
unset($_SESSION['value_array']);
unset($_SESSION['error_array']);
}
else
{
$this->num_errors = 0;
}
总是将 num_errors 设置为 0 if 语句总是失败,例如,如果我将 this->num->errors 更改为 3,我会在表单上显示一条消息,指出发现 3 个错误。但是当我在登录页面上 print_r($session) 时,它存储了所有错误数据,所以没有理由 if 应该失败。有任何想法吗??
谢谢
谢谢