在调试过程中,我看到,一切顺利。出于调试目的,在
之前 header('Location:'.wsurl.'me.php');
根据生成的网址
$redirect=wsurl.'me.php';
Netbeans显示正确的网址
但是在获取此屏幕的浏览器窗口
http://img849.imageshack.us/img849/9861/c6949d6ea7ba47909d2cc37.png
并且它不会重定向到任何网址:只是保持原样。
什么阻止重定向?
以下是signin
方法的完整代码
public function signin() {
if ($this->validation->check()) {
foreach ($_POST as $k => $v)
$$k = $v;
$stmt = $this->db->prepare("
SELECT u.id, u.fname, u.lname, u.mname, u.type, u.email, u.salt,
u.pass, u.salt, u.approved, u.ban, u2.status
FROM `users` AS u
LEFT OUTER JOIN `log` AS u2
ON u2.user_id = u.id
WHERE u.email = ? LIMIT 1") or die($this->db->error);
$stmt->bind_param("s", $email) or die($stmt->error);
$stmt->execute() or die($stmt->error);
$stmt->store_result();
$ip = ip2long($ip);
if ($stmt->num_rows > 0) {
$stmt->bind_result($id, $fname, $lname, $mname, $type, $email, $salt, $db_pass, $salt, $approved, $ban, $status) or die($stmt->error);
$stmt->fetch() or die($stmt->error);
$stmt->close();
if ($status != 1) {
if ($approved == 1) {
if ($ban == 0) {
$hash = hash('sha256', $salt . hash('sha256', trim($pass)));
if ($hash == $db_pass) {
$token = sha1(microtime(true) . mt_rand(10000, 90000));
if (isset($remember) && $remember == "on") {
$timeout = time() + 60 * 60 * 24 * COOKIE_TIME_OUT;
$stmt = $this->db->prepare("INSERT INTO `log` (`user_id`,`ip`, `token`, `timeout`, `status`,`signin_dt`) VALUES (?,?,?,?,1,NOW())") or die($db->error);
$stmt->bind_param("iiiii", $id, $ip, $token, $timeout) or die($stmt->error);
setcookie('auth', "$token", $timeout);
} else {
$stmt = $this->db->prepare("INSERT INTO `log` (`user_id`,`ip`, `status`,`signin_dt`) VALUES (?,?,1,NOW())") or die($db->error);
$stmt->bind_param("ii", $id, $ip) or die($stmt->error);
session_start();
session_regenerate_id(true); //this is a security measure
$_SESSION['user_id'] = $id;
$_SESSION['token'] = $token;
$_SESSION['HTTP_USER_AGENT'] = md5($_SERVER['HTTP_USER_AGENT']);
$_SESSION['remote_ip'] = $_SERVER['REMOTE_ADDR'];
}
$stmt->execute() or die($stmt->error);
$stmt->close();
$redirect=wsurl.'me.php';
header('Location: '.$redirect); die;
} else {
die($this->ajax->respond(3));
}
} else {
die($this->ajax->respond(4));
}
} else {
die($this->ajax->respond(5));
}
} else {
die($this->ajax->respond(6));
}
} else {
die($this->ajax->respond(7));
}
}
}
答案 0 :(得分:2)
圣洁的鳄梨!这是一个很多的if-statements !!
很多if语句会增加Cyclomatic Complexity,这是一件非常糟糕的事情。在过去的四十年中,许多长期研究已经最终证明,具有高圈复杂性的项目实际上总是失败,因为它们太昂贵而无法维护和扩展。
请参阅http://en.wikipedia.org/wiki/Cyclomatic_complexity
如何从头开始并使用return语句和异常来控制流程呢?它会更漂亮,更容易理解,更容易[单元]测试,并且不容易出错。
这是我在自己的代码中使用的内容:
class UserController
{
public function login()
{
$username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
$password = filter_input(INPUT_POST, 'password', FILTER_SANITIZE_STRING);
$status = $this->userManager->validatePassword($password);
if ($status == UserManager::LOGGED_IN)
{
$this->createUserSession();
}
}
}
然后我有了这个:
class SecurityController
{
const NOT_LOGGED_IN = 501;
public function ensureHasAccess()
{
if ($this->isLoggedIn() === false)
{
throw new RuntimeException('User is not logged in', self::NOT_LOGGED_IN);
}
}
}
所以你需要做的就是确保登录用户在页面上运行的东西是这样做的:
$guard = new SecurityController;
$guard->ensureHasAccess();
那么,最后,在web / index.php中,我有这个:
try
{
// DO web stuff here.
}
catch (RuntimeException $e)
{
if ($e->getCode() == SecurityController::NOT_LOGGED_IN)
{
// Oops! The user isn't logged in... Redirect!!
header('Location: http://' . $_SERVER['HTTP_HOST'] . '/user_directory/?errmsg=not+logged+in');
exit; // Thanks, drrcknlsn!
}
}
我甚至创建了一个演示应用来教人们这类东西。 PHP大学的代码仓库的一部分:http://repo.phpexperts.pro/source/user_directory/files
答案 1 :(得分:0)
如果ajax_respond()
向浏览器发送输出,则无法通过header()
调用来执行此操作,因为输出已经发送。 AJAX响应通常不会跟随任何重定向,因为客户端浏览器不打算重新加载页面。相反,AJAX响应在页面中处理,不会发生重定向。
答案 2 :(得分:0)
显然,如果您要重定向到wsurl . 'me.php'
并且浏览器只是尝试请求me.php
,那么您的问题是wsurl
为空。我不知道究竟wsurl
到底是什么,但如果它应该是变量,那么它应该是$wsurl
而不是wsurl
。如果它是常量,请确保它定义的文件包含在此文件中。无论它是什么,请确保正确拼写它,使用适当的外壳等。
但是你应该真的使用PHP错误日志。在这样的情况下,它会告诉你到底出了什么问题以及在哪里。