php 简单的重定向后获取代码示例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4142809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Simple Post-Redirect-Get code example
提问by Mawg says reinstate Monica
I have found many sites that describes PRG, but no simple PHP code example.
我找到了许多描述 PRG 的网站,但没有简单的 PHP 代码示例。
Here's what I implemented:
这是我实施的:
- The
form.php
has an action:validate.php
. - The
validate.php
is never seen by the user; if validates all$_GET
and, if valid writes it to database and generates the HTML of a confirmation page / if not valid, it generates the HTML of an error page explaining what is wrong. - Whichever HTML is generated get stored in a
$_SESSION
variable and thenvalidate.php
callsheader('Location: <as appropriate>);
. - The
submitted.php
ofinvalid_input.php
(in case the user reads the URL) consists only ofecho $_SESSION['form_html'];
.
- 该
form.php
有一个动作:validate.php
。 - 将
validate.php
永远不会被用户看到; 如果全部验证$_GET
,如果有效,则将其写入数据库并生成确认页面的 HTML/如果无效,则生成错误页面的 HTML,解释错误所在。 - 无论生成哪个 HTML 都会存储在一个
$_SESSION
变量中,然后validate.php
调用header('Location: <as appropriate>);
. - 该
submitted.php
的invalid_input.php
(如果用户读取URL)只包括echo $_SESSION['form_html'];
。
That seems to me like protection against both page reload and back button problems.
在我看来,这就像防止页面重新加载和后退按钮问题。
Did I goof by trying to reinvent the wheel?
我是不是通过尝试重新发明轮子来搞砸的?
回答by Hannes
Simplest scenario:
最简单的场景:
if ($_POST) {
// Execute code (such as database updates) here.
// Redirect to this page.
header("Location: " . $_SERVER['REQUEST_URI']);
exit();
}
Use REQUEST_URI
. Do not use PHP_SELF
as in most CMS systems and frameworks PHP_SELF
would refer to /index.php
.
使用REQUEST_URI
. 不要PHP_SELF
像在大多数 CMS 系统和框架中PHP_SELF
所指的那样使用/index.php
.
回答by SW4
A snippet of code:
一段代码:
if (count($_POST)) {
// process the POST data
// your code here- so for example to log a user in, register a new account..
// ...make a payment...etc
// redirect to the same page without the POST data, including any GET info you
// want, you could add a clause to detect whether processing the post data has
// been successful or not, depending on your needs
$get_info = "?status=success";
// if not using rewrite
// header("Location: ".$_SERVER['PHP_SELF'].$get_info);
// if using apache rewrite
header("Location: ".$_SERVER['REQUEST_URI'].$get_info);
exit();
}
回答by bcosca
Browser
HTML form
method=POST
|
v
PHP app
reads $_POST
sends 303 header
|
v
Browser
receives header
redirected to
new page
|
v
PHP app
reads $_GET
does whatever
A common use is in login authentication. That's the process flow when user submits the login form. PHP app authenticates user via $_POST vars. Sends a 303 header back to browser when the user has successfully authenticated. So user is redirected to a new page.
一个常见的用途是登录身份验证。这是用户提交登录表单时的流程。PHP 应用程序通过 $_POST 变量对用户进行身份验证。当用户成功通过身份验证时,将 303 标头发送回浏览器。所以用户被重定向到一个新页面。
回答by Peter
I would like to introduce you to a method that is often used on a greater scale and in much more detail in frameworks.
我想向您介绍一种经常在框架中更大规模、更详细地使用的方法。
What we are going to do
我们要做什么
We have a file called index.php
.
我们有一个名为index.php
.
- We are going to submit a form
- We are going to check for this submit
- We will add the POST data to a session
- We will redirect the user to a confirmation page
- We will display the data and let the user confirm.
- We will submit, and finally process the data.
- We will redirect back to
index.php
and show a notification.
- 我们要提交一个表格
- 我们将检查此提交
- 我们将 POST 数据添加到会话中
- 我们会将用户重定向到确认页面
- 我们将显示数据并让用户确认。
- 我们将提交,并最终处理数据。
- 我们将重定向回
index.php
并显示通知。
The code
编码
<?php
if (!isset($_SESSION)) session_start();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
switch ($_POST['submit']) {
case 'add':
// This is where our first POST will end up
// We can perform actions such as checking the data here
// After that we will add the POST data to a session
$_SESSION['postdata'] = $_POST;
// and unset the $_POST afterwards, to prevent refreshes from resubmitting.
unset($_POST);
// Now we will redirect...
header("Location: ".$_SERVER['PHP_SELF']);
break;
case 'confirm':
// We can now insert the data into the database or email it
// Then we will unset the session and redirect back
unset($_SESSION['postdata']);
// This is to display our notification
$_SESSION['success'] = true;
// And there we go again...
header("Location: ".$_SERVER['PHP_SELF']);
break;
}
// We will exit here because we don't want the script to execute any further.
exit;
}
?>
<?php if (isset($_SESSION['success']) && $_SESSION['success'] == true): ?>
<p>Our data has been processed succesfully</p>
<?php unset($_SESSION['success']); ?>
<?php endif; ?>
<?php if (isset($_SESSION['postdata'])): ?>
<p>
You want to add the following data:<br />
<pre><?php print_r($_SESSION['postdata']); ?></pre>
Is this correct?<br />
<form method="POST" action="<?= $_SERVER['PHP_SELF']; ?>">
<button type="submit" name="submit" value="confirm">Yes</button>
</form>
</p>
<?php else: ?>
<p>
<form method="POST" action="<?= $_SERVER['PHP_SELF']; ?>">
<input type="text" name="..."><br />
<input type="text" name="..."><br />
<input type="text" name="..."><br />
<input type="text" name="..."><br />
<button type="submit" name="submit" value="add">Add something</button>
</form>
</p>
<?php endif; ?>
回答by Elliptical view
Caller.htm
来电.htm
<form method="post" action="Callee.php?Query1">
<input type="text" name="PostData" />
<input type="submit" value="Go" />
</form>
Callee.php(Is called twice.)
Callee.php(被调用两次。)
if ($_POST) {
header("Location: ". $_SERVER['REQUEST_URI']. 'Query2');
// PART1: Use $_POST and $_GET to execute database updates here...
// Now any display (i.e. echo or print) will come after the header.
// ...
die; // When done, GET 'myself' to execute PART2 below.
}
// PART2: Results page goes here...
echo 'PART 2 display output: '; var_dump($_GET);
Notice there are two query strings involved
请注意,涉及两个查询字符串
Look what var_dump says about $_GET:
看看 var_dump 怎么说 $_GET:
PART 2 display output: array(1) { ["Query1Query2"]=> string(0) "" }
Issues with putting header at the endof the POST section like this:
将标题放在POST 部分末尾的问题,如下所示:
header("Location: ". $_SERVER['REQUEST_URI']. 'Query2'); die;
The php manual says: "Remember that header() must be called before any actual output is sent, either by normal HTML tags, blank lines in a file, or from PHP. It is a very common error to read code with include, or require, functions, or another file access function, and have spaces or empty lines that are output before header() is called. The same problem exists when using a single PHP/HTML file."
php 手册说:“请记住,header() 必须在发送任何实际输出之前调用,无论是通过普通的 HTML 标签、文件中的空白行还是来自 PHP。使用 include 读取代码是一个非常常见的错误,或者需要、函数或其他文件访问函数,并且在调用 header() 之前输出有空格或空行。使用单个 PHP/HTML 文件时存在同样的问题。”
However if you need to build 'Query2' based on what happens in the POST section, it may need to be at the bottom of the POST section. This is ok, so long as you don't try to insert any echo's above it, not even for testing.
但是,如果您需要根据 POST 部分中发生的情况构建“Query2”,则它可能需要位于 POST 部分的底部。这没问题,只要您不尝试在其上方插入任何回声,甚至不用于测试。
回答by Pierre
Here is form.php
这是 form.php
<?php
session_start();
// 1) _____________________________________________ POST _____________________________
if ( count($_POST) ) {
$ermsg ='';
…
check data, write some data to database(s), set error message(s) if any
…
$userdata1 = $_POST['htUserdata1'];
$userdata2 = $_POST['htUserdata2'];
…
$_SESSION['PRG'] = array('field1'=>$userdata1,'field2'=>$userdata1,…,'ermsg'=>$ermsg);
session_write_close();
header('Location: ' . $_SERVER['REQUEST_URI'].'?z',true,303);
exit;
// 2) _____________________________________________ REDIRECT ________________________
} else if ( array_key_exists('PRG',$_SESSION) ) {
$userdata1 = $_SESSION['PRG']['field1'];
$userdata2 = $_SESSION['PRG']['field2'];
…
$ermsg = $_SESSION['PRG']['ermsg'];
unset($_SESSION['PRG']);
// 3) _____________________________________________ GET ______________________________
} else {
…
retrieve data from database(s)
…
$userdata1 = dbGet1();
$userdata2 = dbGet2();
…
$ermsg = '';
}
// 4) _____________________________________________ DISPLAY _________________________
?>
<!DOCTYPE html>
<html lang="fr">
…
<form method="post" action="form.php" accept-charset="utf-8">
<input id="htUserdata1" name="htUserdata1" type="text"/>
<input id="htUserdata2" name="htUserdata2" type="text"/>
…
</form>
<script language="javascript">
"use strict";
<?php
$G['htUserdata1'] = $userdata1;
$G['htUserdata2'] = $userdata2;
…
$G['ermsg'] = $ermsg;
$myJSON = json_encode($G);
echo "var G=$myJSON;";
?>
document.getElementById('htUserdata1').value = G.htUserdata1;
document.getElementById('htUserdata2').value = G.htUserdata2;
…
if ( G.ermsg !=='') alert(G.ermsg);
</script></body></html>