我对PHP Post/Redirect/Get感到困惑
在一篇关于防止重新提交PHP表单的文章中,我阅读了以下内容: (不引用)这可能是接收表单数据的页面,例如称为“form.php”:我对PHP Post/Redirect/Get感到困惑,php,html,forms,post,get,Php,Html,Forms,Post,Get,在一篇关于防止重新提交PHP表单的文章中,我阅读了以下内容: (不引用)这可能是接收表单数据的页面,例如称为“form.php”: 但是,用户不能导航到上面的URL吗?另外,GET变量的用途是什么?难道我不能在form.php上有一个脚本来检查用户是否登录了吗 在submit.php中,我是否应该将登录的用户名保存为$\u SESSION['username'],然后检查form.php中的isset()是否正确?此外,由于一个带有“success”的URL并不漂亮,再次重定向用户是否经济?我应
但是,用户不能导航到上面的URL吗?另外,GET变量的用途是什么?难道我不能在form.php上有一个脚本来检查用户是否登录了吗 在submit.php中,我是否应该将登录的用户名保存为$\u SESSION['username'],然后检查form.php中的isset()是否正确?此外,由于一个带有“success”的URL并不漂亮,再次重定向用户是否经济?我应该使用PHP header()还是Javascriptwindow.location.href?正如您所见,我有点困惑 谢谢你的帮助
但是,用户不能导航到上面的URL吗 是的,他能。但这不会导致任何不好的结果 另外,GET变量的用途是什么 若要使用一些标志来表示表单已成功处理,您需要向用户表示祝贺 难道我不能在form.php上有一个脚本来检查用户是否登录了吗 嗯,您可以按照自己喜欢的方式保存代码。没有任何强烈的要求 在submit.php中,我是否应该将登录的用户名保存为$_SESSION['username'],然后检查form.php中的isset()是否正确 如果您需要在当前会话中保持它-是的,请这样做 此外,由于一个带有“success”的URL并不漂亮,再次重定向用户是否经济 重定向到哪里。重定向是非常便宜的事情 我应该使用PHP header()还是Javascript window.location.href
你绝对应该在php中这样做,否则你会遇到你试图避免的问题。是的,你永远不应该依赖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中:
<form action="submit.php">
<input type="text" name="user" required />
<input type="password" name="pass" required />
<input type="submit" value="Log in" />
</form>
<?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是客户端的,可以避免,这会破坏您对站点运行的意图。正如您链接的文章所指出的,POST/redirect/GET背后的主要思想是避免用户重新提交数据(大多数时候)。一般来说,你不希望同一个帖子(数据完全相同)发生两次——事实上,在某些情况下,它可能会第二次执行某些操作(比如向信用卡收费),这是不好的 您在问题中询问的大部分内容都是实现细节(比如在重定向中发送?success请求参数) 在实践中,通常发生的情况是成功时重定向。例如,如果用户的输入未通过验证,则不重定向,而是重新显示表单以及相关的错误消息 这里是一个基本的例子,全部在一个脚本中。我试着只包括重要的东西,尽量少一些无关的东西 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>
PRG或Post/Redirect/Get只是一种可以用来阻止消息框的模式。如何详细使用它(本文仅提供一般性建议)取决于您的需要 如果您想在cookie、会话或get变量中标记success 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');
在标题()旁边,您应该按照RFC提供一个消息正文,许多所谓的“web开发人员”甚至不知道:
$url = 'http://example.com/login/form.php?success=true';
header(sprintf('Location: %s', $url));
printf('<a href="%s">Moved</a>.', $url);
exit;
你找到了
重述一下:重要的是,在发布后进行重定向。其他一切,如传递变量,完全取决于您希望如何执行。“但是,用户不能导航到上面的URL吗?”——是的,他可以。那么?你是对的,没有POST数据不会造成任何伤害。url中的?成功
,没有什么比这更难看的了。我一直在使用类似的东西,因为大多数人都不注意这一点,而且这非常简单。我假设该示例中的查询字符串用于form.php
来确定是否应该显示成功消息。如果您愿意,您可以在会话中执行此类操作。重要的是有一个重定向,因此重新加载不会重新执行POST,只是无害地进入成功页面。@user805556:这是任何形式的通用解决方案,例如添加评论形式。在这种情况下,检查消息是否已成功添加并不像if(isset($\u SESSION…
Ok)那样简单,这会让它变得清晰一些。但是,由于我从不使用单独的登录页面,而是在每个页面上都有它们,我是否应该重定向到以下位置:?“submit.php?page=whather.php”然后使用该变量重定向回该特定页面?还有,如何在PHP中找到当前页面,以便
$url = 'http://example.com/login/form.php?success=true';
header(sprintf('Location: %s', $url));
printf('<a href="%s">Moved</a>.', $url);
exit;
http_redirect('/login/form.php?success=true');