在PHP中触发500内部服务器错误并显示Apache错误页面

时间:2011-12-31 09:27:34

标签: php apache

如何在PHP中触发 500内部服务器错误 404页面未找到 Apache错误?

对于500内部服务器错误,我尝试了以下代码:

header("HTTP/1.0 500 Internal Server Error");

但它显示了一个空白页面。 如何以Apache的默认格式显示错误?

请指导..

10 个答案:

答案 0 :(得分:13)

您可以将Apache错误文档复制到Web根目录中(或将它们符号链接)并使用header()设置错误代码并将这些文档作为输出。这可能是最好的,除非你有令人信服的理由不这样做。但是,如果这对你不起作用,有一些替代方案(虽然是hacky替代方案)。

对于500,只需在代码中添加一个错误。

<?php throw new Exception('Nooooooooooooooo!'); ?>

PHP脚本将引发异常,从而产生常规的Apache 500错误页面。 (但请注意,如果PHP初始设置display_errors设置为0,这只会导致Apache错误。在大多数开发配置中,情况并非如此。在大多数生产配置中就是这种情况。如果你不知道你的生产服务器的设置,你只需要测试一下它是否有效。)

对于404,我认为您可以做的最好的事情是重定向到不存在的页面。这不是完全相同的事情,但可能会出于您的目的。

<?php header("Location: /i-dont-think-therefore-i-am-not"); ?>

在大多数浏览器中,用户实际上看不到重定向,他们只是静默地快速重定向到不存在的页面,导致常规的Apache 404错误。当然,网址会发生变化,有些用户可能会注意到这一点。如果这是不可接受的,您可以使用Apache mod_rewrite将URL后端重写为不存在的位置,从而获得类似的结果。

要回复几条评论:通过header()(或其他方式)设置响应代码不会产生标准的Apache错误文档。它只会使用您自己的输出返回响应代码。这是故意行为,旨在使您可以拥有自定义错误文档,或者按照HTTP规范对任何请求的指示设置响应代码。如果你想要 Apache 错误文档,你必须要么伪造它们(根据我最初建议的只是将错误文档复制到你的web根目录),或者你必须欺骗Apache返回它们(根据我的备份建议)。

答案 1 :(得分:8)

经过这样的知识全面讨论,我认为没有php代码可以默认显示500内部服务器错误。 解决方案是:
1.在php文件旁边创建一个名为 http500 的文件夹 2.在其中创建.htaccess文件并添加以下代码:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} -d
    RewriteRule ^])(.(*/
    RewriteRule ^])((a-zA
</IfModule>
  1. PHP重定向代码:
  2.   

    标题('location:http500 /');

答案 2 :(得分:6)

function ISE()
{
  header('HTTP/1.1 500 Internal Server Error', true, 500);
  trigger_error('ISE function called.', E_USER_ERROR);//if you are logging errors?
}

但是,在使用任何输出函数header()之后,您将需要输出缓冲ON才能使用php echo函数。

答案 3 :(得分:3)

我可能已经很晚了,但这个解决方案应该可行

header("HTTP/1.0 500 Internal Server Error");
include("/path-to-public-html/errors/500.php");
die();

这将触发500 ISE响应,并显示默认的500错误页面,然后停止脚本。显然,您需要修改包含文件的位置

答案 4 :(得分:2)

你根本无法触发来自php代码的apache错误页面,而不需要ben lee提出的hackery重定向,因为错误文档重定向是由应用程序堆栈的另一层处理的(具体来说,是apache的mod_core)。 当你的脚本运行时,为时已晚。

通过抛出异常来获取错误页面的诡计取决于你的php.ini有关error handling and verbosity的设置。

http_response_code()目前只存在于php的svn中,因此在大多数应该运行正式发布版本的生产环境中都不可用。

我的建议是分别通过set_error_handler()set_exception_handler()正确实现自定义错误和异常处理程序,使用header()向客户端发送正确的http状态信息和(如果需要)生成错误页面。

答案 5 :(得分:1)

我知道这是一个旧线程但是......

您可以在视图中渲染iframe元素,然后在您准备处理的错误中将其高度和宽度设置为100%。

<?php header("HTTP/1.0 500 Internal Server Error"); http_response_code(500); ?>

<iframe src="page_displaying_apache_screenshot_fullscreen.html"></iframe>

这是

我真的认为最好的现代解决方案就是:

<?php
header("HTTP/1.0 500 Internal Server Error");
http_response_code(500);
?>
<div class="panel-body">
    <h1>Error!</h1>
     <p>
         <?php

         // Then, in the view if your in dev env, print exception and stack trace
         if ($env === 'dev') 
         {
             throw new Exception('Uh oh! Something broke while adding a new user the db.');
         }
         else 
         {
             echo "Hold your butts, an error has occured.";
             die();
         }
         ?>
     </p>
   </div>

如果将$ env变量设置为&#39; dev&#39;这将导致所有用户的正确错误代码,以及dev的堆栈跟踪。在您的开发堆栈上。 What the user sees with this, using PHP 5.4 installed with yum using CENTOS7 by default

没有重定向,没有hackery,安全,除非您需要暴露它不会发生的错误。 :)

答案 6 :(得分:0)

显然有一个名为http_response_code的函数可以让你适当地设置响应代码。如果这不起作用(文档中有关于它的说明可能仅在SVN中),则header函数可以采用可选的响应代码参数:

header("HTTP/1.0 ...", true, 404);

这应该正确地告诉Apache。

答案 7 :(得分:0)

在PHP 5.5 =&gt; “标题(” tester.php “真,500);”其中tester.php不存在。它有效并带我到我的500页:)

不幸的是,由于某种原因,这里列出的其他方法都没有。

答案 8 :(得分:0)

我知道这是一个老话题,但是当我在Google上搜索时,它会跳出来作为第一个答案。这些天我试图弄清楚如何做到这一点,所以我想我应该从2018年开始我的解决方法。

众所周知,不,你不能简单地从PHP触发Apache的错误页面。没办法做到这一点。因此,在经过一些研究之后,我能找到的最好的解决方法是使用PHP函数来显示自定义错误页面,这是从您在Apache中指定的内容和您想要的页面调用的。触发500内部服务器错误。

这是我的conf Apache:

ErrorDocument 400 /error.php
ErrorDocument 401 /error.php
ErrorDocument 403 /error.php
ErrorDocument 404 /error.php
ErrorDocument 500 /error.php

如您所见,所有4xx和500错误都被重定向到同一个php文件。为什么我没有为每个代码使用单独的文件是另一个问题,这与你的问题无关,所以让我们忘记它并立即关注error.php

以下是error.php的一些行:

<?php
require_once("error_page.php");

$relative_path = "";
$internal_server_error = FALSE;

if (isset($_SERVER['REDIRECT_URL']) && $_SERVER['REDIRECT_URL'] != "")
{
    $relative_path = $_SERVER['REDIRECT_URL'];
    $internal_server_error = (http_response_code() >= 500);
}
else if (isset($_SERVER['REQUEST_URI']))
{
    $relative_path = $_SERVER['REQUEST_URI'];
}

ErrorPage::GenerateErrorPage($internal_server_error, $relative_path);
?>

简而言之,它通过http_response_code()从Apache接收HTTP状态代码,只需将状态代码分为两类:内部服务器错误和非内部服务器错误。然后它将类别传递给ErrorPage::GenerateErrorPage(),它实际上生成了错误页面的内容。

ErrorPage::GenerateErrorPage()中,我做了类似的事情:

<?php
http_response_code($internal_server_error ? 500 : 404);
?>

在函数的开头,这样就不会有任何烦人的“已发送的标题”。此函数将生成一个功能完整的错误页面,其中包含正确的(或至少我们期望的)HTTP状态代码。在设置HTTP状态代码之后,正如您可能猜到的,将通过以下php代码生成两个准备好的内容之一,一个用于500,另一个用于404。

现在让我们回到你的问题。

您希望触发与Apache完全相同的错误页面,现在您可以从任意位置调用ErrorPage::GenerateErrorPage(),只要您为其提供正确的参数(TRUE为500,在我的情况下,FALSE为404。

显然,由于Apache错误页面是由同一个函数ErrorPage::GenerateErrorPage()生成的,因此我们可以保证您触发的内容与Apache错误页面的预期完全相同。

以下是我的触发页面示例:

<?php
ob_start();

require_once("error_page.php");

try
{
    // Actual contents go here
    phpInfo();
    throw new Exception('test exception');
}
catch (Exception $e)
{
    ob_clean();
    ErrorPage::GenerateErrorPage(TRUE);
    ob_end_flush();
    exit();
}

ob_end_flush();
?>

我使用ob_start()ob_clean()的原因是,通过这种方式,我可以在异常发生之前清除任何输出,并且发送一个看起来完全正确的纯500内部服务器错误页面与Apache相同,触发页面上没有任何内容(在这种情况下为phpInfo())。 ob_start()ob_clean()确保没有“已发送标头”,因为除非您致电ob_end_flush(),否则不会发送任何内容。

上述解决方案是我最近研究的结论。它对我来说是如此的好,但我不确定它是否是正确的方法。欢迎任何评论,问题,想法,建议和改进。

答案 9 :(得分:0)

原因内部服务器错误500。 I open httpd.conf text file and edit it固定我的错误只是改变我的服务器名本地主机81,而不是80。