发布表单时 PHP 标头重定向不起作用 - 使用输出缓冲区 - 但在其他情况下呢?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/796444/
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
PHP header redirect not working when posting a form - using output buffer - but does in other cases?
提问by Moak
I have an unusual problem, only happening on one server. Following code
我有一个不寻常的问题,只发生在一台服务器上。以下代码
....
elseif ($_GET['action']=='login') {
if (empty($_POST['login_name'])) { $_POST['login_name']=''; }
if (empty($_POST['login_pass'])) { $_POST['login_pass']=''; }
if (!empty($_POST['send'])) {
if (($_POST['login_name']==_ADMIN_NAME) and ($_POST['login_pass']==_ADMIN_PASS)) {
//Successfully logged in
$_SESSION['logged']=1;
// DOES NOT WORK
header('Location: '.$filename);
die('Command '.$filename);
}
}
// Show Form;
include('plogin.inc.php');
}
elseif ($_GET['action']=='logout') {
$_SESSION['logged']=-1;
// DOES WORK!
header('Location: '.$filename);
}
So the problem is this if i click the link logout, all goes well and i get redirected to $filename. If i submit the login form it checks if the post is correct, set's the session var, but then dies instead of redirecting.
所以问题是如果我点击链接注销,一切顺利,我被重定向到 $filename。如果我提交登录表单,它会检查帖子是否正确,设置会话变量,但随后死亡而不是重定向。
I got output buffers on, all error reporting but (no errors), it doesn't redirect when I post with the form even though it definitely passes (because the session var is set and I get to the die part)
我打开了输出缓冲区,所有错误报告但(没有错误),当我用表单发布时它不会重定向,即使它肯定通过了(因为设置了会话变量并且我到达了模具部分)
What could be the cause for this behavior? Thanks
这种行为的原因可能是什么?谢谢
回答by puzz
I, also, found redirect don't work sometimes after POST request. It is a browser not server-side problem, I think.
我也发现重定向有时在 POST 请求后不起作用。我认为这是浏览器而不是服务器端问题。
I use something like this:
我使用这样的东西:
if( sizeof( $_POST ) == 0 ) header( "Location: " . $url );
else echo '<html><head><meta http-equiv="refresh" content="1;url=' . $url . '"/></head><body>Redirecting to ' . $url . '</body></html>'
In short, if it is a POST request - then I use html refresh redirect, else - normal header redirect.
简而言之,如果它是一个 POST 请求 - 那么我使用 html 刷新重定向,否则 - 正常的标头重定向。
回答by VolkerK
Did you test that a) the code is reached and b) the error reporting really is in effect?
您是否测试过 a) 已到达代码并且 b) 错误报告确实有效?
//Successfully logged in $_SESSION['logged']=1;
// code reached, error_reporting test echo 'debug: would send location header', $filename, $unsetVariableTriggeringWarning; flush();
if (headers_sent()) { die('cannot send location header (anymore)'); } else { header('Location: '.$filename); die(); }
回答by Henrik Paul
The line with
线与
die('Command '.$filename);
would probably be the culprit. If the die(or exit) functions (or actually language constructs) take a string as a parameter, it is printed out on the other side before halting. PHP doesn't like you trying to output anything if you are sending headers.
可能是罪魁祸首。如果die(or exit) 函数(或实际上是语言构造)将字符串作为参数,则在停止之前将其打印在另一侧。如果您发送标头,PHP 不喜欢您尝试输出任何内容。
If you are using a reasonably new PHP (>= 4.3.0 iirc), you can use integers 0..255 to mark exit conditions (if you want to), which will not be printed.
如果您使用的是相当新的 PHP(>= 4.3.0 iirc),您可以使用整数 0..255 来标记退出条件(如果您愿意),它不会被打印出来。
回答by Mario Mueller
might be a simple thing. The header() function does set a header, but does not terminate a script so that the header is sent immidiately after calling header().
可能是一件简单的事情。header() 函数确实设置了一个标头,但不会终止脚本,以便在调用 header() 后立即发送标头。
You need to make php send the script result to the client. As you use output buffering, this result is held back until you trigger your output. Try this instead:
您需要让 php 将脚本结果发送给客户端。当您使用输出缓冲时,此结果会一直保留,直到您触发输出。试试这个:
header('Location: '.$filename);
ob_end_flush();
exit();
Regards, Mario
问候, 马里奥
回答by Binaek Sarkar
When you send a redirect, PHP puts the values in the HTTP Response header. The body follows the header. Therefore, if you echo/print any kind of value before using the Header function, it fails, since the Response Headers are already out. Try the same script before printing any text and it will work.
当您发送重定向时,PHP 会将值放入 HTTP 响应标头中。正文跟随标题。因此,如果您在使用 Header 函数之前回显/打印任何类型的值,它就会失败,因为响应头已经出来了。在打印任何文本之前尝试相同的脚本,它会起作用。
Normal HTTP Response
正常的 HTTP 响应
HTTP/1.1 200 OK Date: Wed, 12 Jan 2011 18:40:22 GMT Server: Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 X-Powered-By: PHP/5.2.14 Expires: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Pragma: no-cache Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Transfer-Encoding: chunked Content-Type: text/html
HTTP/1.1 200 OK 日期:2011 年 1 月 12 日星期三 18:40:22 GMT 服务器:Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 mod_auth_passthrough/2.1 mod_bwlimited/1。 5.0.2.2635 X-Powered-By: PHP/5.2.14 过期: Thu, 19 Nov 1981 08:52:00 GMT Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre -check=0 Pragma: no-cache Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Transfer-Encoding: chunked Content-Type: text/html
[Body of the message]
[邮件正文]
HTTP/1.1 302 Found Date: Wed, 12 Jan 2011 18:40:22 GMT Server: Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 mod_auth_passthrough/2.1 mod_bwlimited/1.4 FrontPage/5.0.2.2635 X-Powered-By: PHP/5.2.14 Location: profile.phpContent-Type: text/html
HTTP/1.1 302 发现日期:2011 年 1 月 12 日星期三 18:40:22 GMT 服务器:Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 mod_auth_passthrough/2.1 mod_bwlimited/1 5.0.2.2635 X-Powered-By:PHP/5.2.14 位置:profile.php内容类型:text/html
回答by Mikl
header('Location: '.$filename);
flush(); //Try to force server to send header before script die
die('Command '.$filename);
I had the same problem: script: header('Location: ...'); die();
我有同样的问题: script: header('Location: ...'); 死();
Script before sending headers received some data via POST, and if data new make changes to DB. It is curious, when POST data small and little changes to DB redirect WORK, when POST data bigger and a lot of changes to DB redirect DON'T WORK. Using flush() after header() solve my problem.
发送标头之前的脚本通过 POST 接收到一些数据,如果数据是新的,则对 DB 进行更改。奇怪的是,当 POST 数据很小并且 DB 重定向工作的变化很小时,当 POST 数据较大并且 DB 重定向的大量更改不工作时。在 header() 之后使用 flush() 解决了我的问题。
PHP Version 5.2.17 Apache/2.2.3 (CentOS)
PHP 版本 5.2.17 Apache/2.2.3 (CentOS)
On my opinion, it looks like server push headers to buffer and dies before sending the buffer content to user, and that is why flush() helped.
在我看来,在将缓冲区内容发送给用户之前,服务器推送标头以缓冲和死亡,这就是 flush() 帮助的原因。
If flush does not working, see comments about output buffering settings and zlib.compression: http://ru2.php.net/manual/en/function.flush.php
如果刷新不起作用,请参阅有关输出缓冲设置和 zlib.compression 的评论:http://ru2.php.net/manual/en/function.flush.php
回答by jab11
from my experience you can't send any content when you're doing redirect. So I'd guess your problem is the die() parameter.
根据我的经验,您在进行重定向时无法发送任何内容。所以我猜你的问题是 die() 参数。
I can't find this in documentation right now but try dying() it without a parameter or just use exit; I bet it will work.
我现在无法在文档中找到它,但是尝试在没有参数的情况下使它死亡()或仅使用 exit;我打赌它会起作用。

