使用header()函数发送标题时显示错误页面 [英] Showing error pages when sending header with header() function

查看:125
本文介绍了使用header()函数发送标题时显示错误页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



标题正在发送 - 我绊倒了各种可能的错误使用header(),比如在调用之前有输出。例如,我现在在调用header()函数之前使用ob_start()和ob_clean()。



现在我需要理解为什么我的浏览器/服务器/任何不显示我的错误页面。



以下是我用于测试的HTML页面:

 <!DOCTYPE html PUBLIC -  // W3C // DTD HTML 4.01 Transitional // ENhttp://www.w3.org/TR/html4 /loose.dtd\"> 
< html lang =en>< head>
< meta http-equiv =content-typecontent =text / html; charset = ISO-8859-1>
< title>标题测试< /标题>
< / head>
< body>
<?php
error_reporting(E_ALL);
ini_set('display_errors','1');
ob_start();
ob_clean();
header(HTTP / 1.1 403 - Forbidden,true,403); //我有相同的结果,有或没有true,403
ob_flush();
?>



以下是访问中的标题日志:

  127.0.0.1  -   -  [11 / Feb / 2012:19:14:35 -0600]POST / commentprocessing .php HTTP / 1.1403 266http://127.0.0.1/submitcomments.phpMozilla / 5.0(Windows; U; Windows NT 6.1; en-US; rv:1.9.2.24)Gecko / 20111103 Firefox / 3.6 .24(.NET CLR 3.5.30729; .NET4.0C)

这里是HTML源代码:

 <!DOCTYPE html PUBLIC -  // W3C // DTD HTML 4.01 Transitional // ENhttp:/ /www.w3.org/TR/html4/loose.dtd\"> 
< html lang =en>< head>
< meta http-equiv =content-typecontent =text / html; charset = ISO-8859-1>
< title>标题测试< /标题>
< / head>
< body>
< / body>< / html>

如果我从测试页面中删除PHP代码,那就是我所得到的结果。 / p>

有没有办法根据头中的返回码自动显示错误页面?



我在本地运行Abyss服务器进行这种测试。我在深渊定义了一个自定义错误页面,用于403错误,并且我已检查它在深渊设置中正确拼写,并且该页面实际存在。



不会显示403响应代码的标题 - 这似乎是正确发送,因为它显示在访问日志中。



这可能是我使用深渊本地而不是我的托管公司的服务器?



有什么建议吗?

编辑* * *



tftd,

如果你说的是真的,服务器忽略了我的代码,为什么它使用我指定的代码记录在访问日志中?



而且,如果您提到无法更改响应代码,为什么即使有header()语句或者为什么文档没有明确指出像使用ob_start()和ob_clean()这样的东西不能解决它。



我看到,在不止一个地方,引用使用ob_start()和ob_clean()来删除生成的输出,以使header()调用可以工作。



heera,



谢谢您,至少为了向我展示可以将材料放在doctype声明之上并仍然有效。我不会认为这会起作用。所以,非常感谢你。



然而,如果你剥离了所有的PHP并只包含HTML,那么你的示例仅仅输出将输出的内容。



我已经删除了你的onload调用,以消除由于你没有包含引用函数的脚本而发生的'function not defined'错误。



以下内容将产生与您的示例相同的输出:

 <!DOCTYPE html> 
< html>
< head>< / head>
< body>
这是一些文本
< / body>
< / html>

以下是您的示例,它产生与上述直线HTML相同的输出。

 <?php ob_start();?> 
<!DOCTYPE html>
< html> < HEAD>< /头>>
< body>
这是一些文本
< / body>>< / html>
<?php
$ ob = ob_get_clean();
echo $ ob;
ob_end_flush(); ?>

您经历了相同输出的复杂旅程。



另外,为什么要获取缓冲区的内容并将其回显并回显出来?除了调用ob_get_clean()之外,这些演示还会返回缓冲区的内容,并将其擦除,并且与ob_clean()不同,它会删除缓冲区,并且如果要发送刚删除的输出,则必须使用ob_get_clean( )并保存它,然后使用echo写出来。



这并不仅仅表明你最好做一些事情来保存缓冲区的内容,如果你想要输出,然后调用一个干净的函数?

并且,ob_end_flush()被记录下来,无论我遇到它,自动调用脚本/页面完成。为什么要演示一些自动发生的事情,除非您在使用我们的某种类型或另一种类型的同花顺呼叫显示结果相同的输出时,如果在刷新调用后未创建额外输出。



好像你的ob_end_clean()调用完全不显示任何东西,嗯,还是这样?

那么,为什么要生成输出,从缓冲区获取,擦除并删除缓冲区,然后输出您保存的内容?究竟是什么,这证明了什么?现在,如果你想演示ob_start()在输出上的位置和ob_clean在输出上的位置差异, ()删除以前的输出,为什么不从这样的例子开始:

 <?php ob_start();?> 
<!DOCTYPE html>
< html>
< head>< / head>
< body>
这是一些文本
< / body>
< / html>
<?php
ob_clean(); //擦除输出缓冲区
回声这是最好的时期,这是最糟糕的时期。
?>

唯一的输出是

 这是最好的时期,这是最糟糕的时期。 

如果您注释掉ob_clean()调用:

 <?php ob_start();?> 
<!DOCTYPE html>
< html>
< head>< / head>
< body>
这是一些文本
< / body>
< / html>
<?php
// ob_clean(); //擦除输出缓冲区
回声这是最好的时期,这是最糟糕的时期。
?>

现在输出:

 <!DOCTYPE html> 
< html>
< head>< / head>
< body>
这是一些文本
< / body>
< / html>
这是一些文本这是最好的时代,这是最糟糕的时期。

如果您将我的原始示例并将ob_start()向下移动到第二块PHP代码中,这:

 <!DOCTYPE html> 
< html>
< head>< / head>
< body>
这是一些文本
< / body>
< / html>
<?php
ob_start();
ob_clean(); //擦除输出缓冲区
回声这是最好的时期,这是最糟糕的时期。
?>

输出结果为:

 <!DOCTYPE html> 
< html>
< head>
< / head>
< body>
这是一些文本
< / body>
< / html>
这是一些文字这是最好的时代,这是最糟糕的时期。

这些是我将提供的示例,以显示ob_start()和ob_clean ()调用。



再次,您的示例将完成HTML所做的功能,即PHP不存在。



如果你说你必须使用ob_start,ob_get_clean(),echo和ob_end_flush()来产生输出 - 那么,我期望从一个只知道ob_get_clean()和ob_end_flush()的程序员那里获得输出。 b
$ b

我希望那些出于某种原因认为他或她不得不负责将输出提供给用户的程序员;他们必须采取缓冲区内容,并使用回声发送给用户。



我根本不明白为什么你写了那个例子,你做了什么或什么,除了放置ob_start()之外,您还试图演示。



至于真实世界 - 在现实世界中,程序员需要理解语言特征使用和任何替代品。他们需要理解概念 - 比如PHP会自动发送任何生成的输出,而程序员不得不调用函数将其传递给用户。



您称我为缓冲错误。那么,关于ob_sat()调用的位置,其他一切都很好。



如果您在某种问题中发布了您的示例,我的答复将会是 -



完全不需要使用PHP来实现您想要做的事情。取出PHP并使用直接的HTML - 输出将是相同的。



很抱歉,除了ob_start展示位置之外,该示例只显示一个奇怪而有趣的方式来获取一个HTML给用户。



也许你只是没有花时间考虑最好的例子,在第一次决定之后这个例子是为了演示。



如果我们忽略这样一个事实:这个例子并没有直接的HTML所做的事情,而是以一种错综复杂的方式输出缓冲区,这个例子确实让我直观了一件事 - 你可以在doctype之前放置一些东西,它会被处理,而且我感谢你指出了我。

mc_kennedy,



我读了您指向的页面,但我认为这并不适用,因为第一行输出没有以HTTP /开始,因为页面指定。



我基于我在源视图窗口中看到的内容owser。第一行是doctype或

给所有人一般 -

看起来好像是在说什么,有些人认为,你必须在文件的最顶端有header()调用,这将允许你正确地发送响应代码。

那么,我试过了,PHP在最上面,后面是标准HTML,我没有看到任何区别。



我错了,认为服务器会有不同的反应,比如说,一个200而不是一个403?

我有这个错误,我期望 - 让服务器反应,不知何故,到403或500错误 - 是不存在的?



如果我使用的方法会导致header()调用被忽略,为什么日志显示我发送的代码?



现在我明白我应该自己生成错误页面,我怀疑(好,更可疑,更像是想要的那样。)



但是我希望服务器能够以不同的方式响应不同的响应代码,这根本就不会发生?

Bob

解决方案

除了其他答案,您使用对象缓冲是错误的,下面是一个简单的例子

 <?php ob_start();?> 
<!DOCTYPE html>
< html>
< head>< / head>
< body onload =initialize()>
这是一些文本
< / body>
< / html>
<?php
$ ob = ob_get_clean();
echo $ ob;
ob_end_flush();
?>

在现实世界中,您必须以不同的方式使用它,这仅仅是一个例子。


I want to send some response codes in response (what else?) to various conditions.

The header is being sent - I tripped over the various errors you can make using header(), such as having output before the call before. I figured out those sort of issues, for instance, I now use ob_start() and ob_clean() before the header() function call.

Now I need to understand why my browser/server/whatever is not showing me an error page.

Here's the HTML page which I'm using for testing:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en"><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>Header Testing</title>
</head>
<body>
<?php
     error_reporting(E_ALL);
     ini_set('display_errors', '1');
     ob_start();
     ob_clean();
     header("HTTP/1.1 403 - Forbidden", true, 403); // I get the same results with or without "true, 403"
     ob_flush();
?>

Here's the header from the access log:

127.0.0.1 - - [11/Feb/2012:19:14:35 -0600] "POST /commentprocessing.php HTTP/1.1" 403 266 "http://127.0.0.1/submitcomments.php" "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.24) Gecko/20111103 Firefox/3.6.24 ( .NET CLR 3.5.30729; .NET4.0C)"

Here is the HTML source:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en"><head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>Header Testing</title>
</head>
<body>
</body></html>

That is exactly what I'd get if I removed out the PHP code from the test page.

Is there any way to have an "error" page display automatically based on the return code in the header?

I am running Abyss server locally for this sort of testing. I have a custom error page defined in Abyss for 403 errors and I've checked that it is spelled correctly in the Abyss setup and the page actually exists.

That page is not being displayed for the header with the 403 response code - which seems to be sent properly since it shows in the access log.

Could this be an issue with my using Abyss locally and not the server of my hosting company?

Any suggestions?

EDIT***

tftd,

If what you said is true, that the server is ignoring my code, why is it logged in the access log with the code I specified?

And, if what you said about being unable to change the response code, why even have the header() statement OR why does not the documentation clearly point out that such as things as using ob_start() and ob_clean() won't resolve get around it.

I've see, in more than one place, references to using ob_start() and ob_clean() to delete generated output so that the header() call will work.

heera,

Thank you, at least for showing me that material can be placed above the doctype statement and still be effective. I would not have thought that would work. So, thank you for that.

However, your example merely outputs exactly what would be output if you stripped out all of the PHP and had just the HTML.

I have removed your onload call to eliminate the 'function not defined' error which would have occurred since you did not include a script containing the referenced function.

The following will produce the same output as your example:

<!DOCTYPE html>
<html>
<head></head>
<body>
This is some text
</body>
</html>

Here's your example, which produces the same output as the straight HTML above.

<?php ob_start();?>
<!DOCTYPE html>
<html>   <head></head>>
<body>
This is some text
</body>></html>
<?php
$ob=ob_get_clean();
echo $ob;
ob_end_flush(); ?>

You take a convoluted journey to the same output.

Also, why get the contents of the buffer and turn around and echo it out? What does that demonstrate other than a call to ob_get_clean() returns the contents of the buffer, erases it, and, unlike ob_clean(), deletes the buffer and if you want to send the output you just erased, you have to use ob_get_clean() and save it and then use echo to write it out.

Doesn't that just demonstrate that you had better do something to save the contents of the buffer, if you want to output, before calling a clean function?

And, ob_end_flush() is documented, everywhere I've encountered it, as being automatically called went the script/page finishes. Why demonstrate something that happens automatically, unless you were showing that with our with out a flush call, of one type or another, results in the same output, provided additional out is not created after the flush call.

Seems like your ob_end_clean() call doesn't demonstrate anything at all, hmmm, or does it?

So, why generate output, get it from the buffer, erase and delete the buffer, and then output the contents you saved? What exactly, does that demonstrate? How to do something simple in a convoluted, strange way?

Now, if you wanted to demonstrate the difference the placement of the ob_start() makes on the output and that ob_clean() deletes previous output, why not start with an example like this:

<?php ob_start();?> 
<!DOCTYPE html>
<html>
<head></head>
<body>
This is some text
</body>
</html>
<?php
ob_clean(); // erase output buffer
echo "It was the best of times, it was the worst of times."
?>

The only output from that would be

It was the best of times, it was the worst of times.

If you comment out the ob_clean() call:

<?php ob_start();?>
<!DOCTYPE html>
<html>
<head></head>
<body>
This is some text
</body>
</html>
<?php
//ob_clean(); // erase output buffer
echo "It was the best of times, it was the worst of times."
?>

The output is now:

<!DOCTYPE html>
<html>
<head></head>
<body>
This is some text
</body>
</html>
This is some textIt was the best of times, it was the worst of times.

If you take my original example and move the ob_start() down into the second piece PHP code, like this:

<!DOCTYPE html>
<html>
<head></head>
<body>
This is some text
</body>
</html>
<?php
ob_start();
ob_clean(); // erase output buffer
echo "It was the best of times, it was the worst of times."
?>

The output is:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
This is some text
</body>
</html>
This is some text It was the best of times, it was the worst of times.

Those are the examples I would provide to show the effect of the placement of the ob_start() and ob_clean() calls.

Again your example does exactly what the HTML would do were the PHP not there.

If you were saying that you must use ob_start, ob_get_clean(), echo, and ob_end_flush() to produce output - well, I would expect that from a programmer who only knew about ob_get_clean() and ob_end_flush().

I'd expect that from a programmer who, for some reason, thought he or she had to take charge to get the output to the user; that they had to take the buffer contents and use echo to send it to the user.

I simply don't understand why your wrote that example as you did or what, besides placement of the ob_start(), you were trying to demonstrate.

As for the "real world" - in the real world programmers are expected to understand the language features they use and any alternatives to them. They are expected to understand concepts - such as PHP automatically sending any generated output without the programmer having to call a function to get it to the user.

You called my use of buffering wrong. Well, it was, as regards the placement of the ob_sat() call, but everything else is just fine.

If you had posted your example in a question of some sort, my reply would have been -

There is absolutely no need to use an PHP to achieve what you are tyring to do. Take out the PHP and use the straight HTML - the output will be the same.

I'm sorry, but that example, except for the ob_start placement, demonstrates nothing but a strange and convo9luted way to get a HTML to a user.

Perhaps you just didn't take the time to consider the best example to use, after, first deciding what the example was to demonstrate.

If we ignore that fact that the example does nothing that the straight HTML does and it goes about outputting the buffer in a convoluted way, all your example did was set me straight on one thing - you can put something before the doctype and it will be "processed. And I thank you for pointing that out to me.

mc_kennedy,

I read the page you pointed me at but I don't think that applies since the first line of output does no start with HTTP/, as the page specifies.

I'm basing that on what I see in the source view window in my browser. The first line is either the doctype or a

To everyone in general --

It seems that what is being said, by some people, is that you have to have the header() call at the very top of the file and that will allow you to send response codes correctly.

Well, I tried that, with the PHP at the very top and followed by standard HTML, and I don't see any difference.

Am I wrong is thinking that a server will react differently to, say, a 200 than to a 403?

Do I have this all wrong and what I'm expecting - to have the server react, somehow, to the 403 or 500 error - is simply something that does not exist?

If the approach I was using would cause the header() call to be ignored, why does the log show the code I was sending?

I now understand that I should generate the error pages myself, I suspected (well, more than suspected, more like figured that was required.)

But am I expecting a server to react to different responses codes in different ways and this simply does not happen?

Bob

解决方案

Addition to other answers your use of object buffering is wrong, here's a simple example of that

<?php ob_start();?>
  <!DOCTYPE html>
  <html>
  <head></head>
  <body onload="initialize()">
     This is some text
  </body>
 </html>
<?php 
  $ob=ob_get_clean(); 
  echo $ob; 
  ob_end_flush();
?>

In real world you have to use it differently, it's just an example.

这篇关于使用header()函数发送标题时显示错误页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆