我对PHP Post / Redirect / Get感到困惑

时间:2011-10-06 23:50:50

标签: php html forms post get

在阻止PHP表单重新提交的article中,我阅读了以下内容:

(不引用)这可能是接收表单数据的页面,例如名为“form.php”:

<form action="submit.php">
  <input type="text" name="user" required />
  <input type="password" name="pass" required />
  <input type="submit" value="Log in" />
</form>

因此,处理POST数据的页面将被称为“submit.php”。如果登录正确,则此代码将运行:

header('Location: /login/form.php?success=true');

但是,用户无法导航到上面的网址?另外,GET变量的目的是什么?难道我不能在form.php上有一个脚本来检查用户是否已登录?

在submit.php,我应该将登录的用户名保存为 $ _ SESSION ['username'] ,然后检查form.php中是否 isset()?此外,由于其中“成功”的URL不是很漂亮,再次重定向用户是否经济?我应该使用PHP header()还是Javascript window.location.href?如你所见,我有点困惑。

感谢您的帮助。

4 个答案:

答案 0 :(得分:5)

  

但是,用户无法导航到上面的网址吗?

是的,他可以。这不会导致任何不好的事情。

  

另外,GET变量的目的是什么?

要有一些标志,表示表单已成功处理,您需要祝贺用户。

  

我不能在form.php上有一个脚本来检查用户是否已登录?

嗯,你可以让你的代码保持你喜欢的方式。没有任何强烈的要求

  

在submit.php,我应该将登录的用户名保存为$ _SESSION ['username'],然后检查form.php中是否有isset()?

如果您需要在当前会话中保留它 - 是的,请执行此操作。

  

此外,由于其中“成功”的网址不是很漂亮,再次重定向用户是否经济实惠?

重定向到哪里。重定向非常便宜。

  

我应该使用PHP header()还是Javascript window.location.href?

你肯定应该在php中这样做,否则你会遇到你试图避免PRG-way的麻烦。

答案 1 :(得分:2)

PRG或Post / Redirect / Get只是一种可用于阻止消息框的模式。你如何详细地使用它(这篇文章只是一般性的建议)取决于你的需求。

如果你想在cookie或会话或get变量中标记成功的flash消息,那完全取决于你。第二次重定向不会有帮助,你会了解到如果你玩它。

唯一重要的部分是,在收到POST请求后,您会进行重定向。然后,用户仍然可以在历史记录中前后移动,而不会被要求重新提交POST数据。

模式有效并且很好。就在两天前,我又做了一次,一步一步的weppapp安装程序可以更好地浏览浏览器界面。

关于您的重定向

此代码错误:

header('Location:/login/form.php?success=true');

首先,你需要在冒号之后有一个空格:

header('Location: /login/form.php?success=true');

然后地址必须是绝对URI,它必须包含完整的URL:

header('Location: http://example.com/login/form.php?success=true');

header()旁边,你应该根据RFC提供一个消息体,许多所谓的“网络开发者”甚至不知道:

$url = 'http://example.com/login/form.php?success=true';
header(sprintf('Location: %s', $url));
printf('<a href="%s">Moved</a>.', $url);
exit;

不要忘记退出。当然,这几乎是重新启动轮子,而是安装PHP的http扩展,然后就行了:

http_redirect('/login/form.php?success=true');

您找到nifty helper here

回顾一下:重要的是你在发布后进行重定向。其他一切,比如传递一个变量,完全取决于你想要的方式。

答案 2 :(得分:1)

是的,你永远不应该依赖GET变量(甚至是隐藏的POST变量)来说“确定,让我进去,我是一个有效的用户!”。

就个人而言,我会从链接中删除GET信息,并仅依赖会话变量。记得放置'session_start();'作为第一行代码,如果您使用PHP来激活会话。

对于submit.php:

<?php
session_start();
if ($_POST['user'] && $_POST['pass']) { // Make sure both variable are set
 if (your_method) {
 // Code to check if the user and pass are valid however you plan
  $_SESSION['user'] = $_POST['user'];
  $_SESSION['loggedin'] = time();
 }
}
header('Location: form.php'); // Either way, pass or fail, return to form.php
exit();
?>

然后在form.php中:

<?php
session_start();
$activeuser = false;
if ($_SESSION['user'] && $_SESSION['loggedin'] < (time()+600)) {
// Check if the user exists and the last access was with in 10 minutes.
 $_SESSION['loggedin'] = time(); // If so, keep them up to date!
 $activeuser = true;
}
if ($activeuser) {
 // whatever should show to someone logged in
} else {
 // Show log in form
}
?>

此外,您可能已经知道这一点,但默认的传输方法是GET,因此请务必在表单标记中指定method =“post”。

通常最好使用header()来重定向,因为Javascript是客户端的,可以避免,这会破坏您的网站运行的意图。

答案 3 :(得分:1)

POST / REDIRECT / GET背后的主要思想,正如您所链接的文章所指出的那样,是为了避免用户重新提交数据(大部分时间)。一般来说,你不希望相同的POST(具有完全相同的数据)发生两次 - 实际上,在某些情况下,它可能最终会再次执行某些操作(如收取信用卡),这将是不好的

您在问题中询问的大部分内容都是实施细节(例如在重定向中发送?success request参数)。

在实践中,通常情况下,您重定向成功。例如,如果用户的输入未通过验证,则不会重定向,而是重新显示表单以及相关的错误消息。

这是一个基本的例子,都在一个脚本中。我试图只包括重要的东西,尽可能少的外来东西。

<强>的login.php

<?php
/**
 * ensure user supplied both username & password
 * @return mixed true or an array of error messages
 */ 
function validate_login_values($vars){
    $errors = array();
    if (empty($vars['username'])) $errors[] = 'You must supply a username, genius.';
    if (empty($vars['password'])) $errors[] = 'You must supply a password, dummy.';
    if (empty($errors)) return true;
    return $errors; // $errors must be an array.
}

if (! empty($_POST)){
    $validationResults = validate_login_values($_POST);
    if ($validationResults === true){
        // assume here that authenticate properly escapes it's arguments before sending them
        // to the database.
        if (authenticate($_POST['username'],$_POST['password'])){
            //GREAT SUCCESS!  The user is now logged in.  Redirect to home page
            header("Location: /");
            die();
        }
        $errors[] = 'Invalid username/password.  Try again, slim";

    }else{
        $errors = $validationResults; // validate_login_values created errors.
    }  
}
?>

<h1>Log In, Friend!</h1>]

<?php 
//display errors, if there were any
if (! empty($errors)): ?>
<div class="errors">Something went horribly wrong:
<ul><?php foreach($errors as $e) echo "<li>$e</li>"; ?></ul>
<div>
<?php endif; ?>

<form method="POST">
<!--   //username, password, and submit   -->
</form>