在阻止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?如你所见,我有点困惑。
感谢您的帮助。
答案 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');
回顾一下:重要的是你在发布后进行重定向。其他一切,比如传递一个变量,完全取决于你想要的方式。
答案 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>