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

如何在PHP中触发 500 Internal Server Error404 Page Not Found Apache错误?

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

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

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

请指导..

回答(9)

2 years ago

您可以将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"); ?>

在大多数浏览器中,用户赢得了't actually see the redirect, they will just get silently and quickly redirected to a non-existent page, resulting in a regular Apache 404 error. Of course, the url will have changed and some users might notice that. If that'不可接受,您可以使用Apache mod_rewrite将URL后端重写为不存在的位置,从而获得类似的结果 .

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

2 years ago

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

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

header('location:http500 /');

2 years ago

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?
}

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

2 years ago

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

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

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

2 years ago

你根本无法触发来自php代码的apache错误页面而没有像ben lee所提议的hackery重定向,因为错误文档重定向是由应用程序的另一层处理的's stack (specifically, apache' s mod_core) .
当你的脚本运行时,为时已晚 .

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

http_response_code() 目前仅存在于php 's svn thus it'中,在大多数应该运行正式发布版本的 生产环境 环境中不可用 .

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

2 years ago

显然有一个名为http_response_code的函数可以让你适当地设置响应代码 . 如果没有't work (there'在文档中关于它的说明可能仅在SVN中)那么 header 函数可以采用可选的响应代码参数:

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

这应该正确地告诉Apache .

2 years ago

在PHP 5.5 =>“header(”tester.php“,true,500);”其中tester.php不存在 . 它工作,带我到我的500页:)

不幸的是,由于某种原因,这里列出的其他方法都不适用于我 .

2 years ago

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

您可以在视图中渲染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变量设置为'dev',这将导致所有用户的正确错误代码,以及dev的堆栈跟踪 .
What the user sees with this, using PHP 5.4 installed with yum using CENTOS7 by default

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

2 years ago

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

众所周知,不, you cannot simply trigger Apache’s error pages from PHP . 没办法做到这一点 . 因此,在经过一些研究之后,我能找到的最好的解决方法是 to use a PHP function to display the custom error pages ,这是从你的两个方面调用的在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完全相同的错误页面,现在只要你给它正确的参数( 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() 的原因是,通过这种方式,我可以在异常发生之前清除任何输出,并且 send a pure 500 Internal Server Error page that looks exactly the same as Apache gives ,在触发页面上没有任何内容(在这种情况下为 phpInfo() ) . ob_start()ob_clean() 也是 make sure that there won’t be “headers already sent” ,因为除非你打电话给 ob_end_flush() ,否则什么都不会发送 .

上面的解决方案是我最近研究的结论 . 这对我来说是如此的好,但我不确定这是否是正确的方法 . 欢迎提出任何意见,问题,想法,建议和改进 .