如何使用PHP创建404错误页面?

162

我的文件.htaccess处理所有从/word_here到我的内部端点/page.php?name=word_here的请求。然后,PHP脚本检查请求的页面是否在其页面数组中。

如果没有,我该如何模拟404错误?

我尝试过这样做,但是它没有显示我通过ErrorDocument.htaccess中配置的404页。

header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");

我是否正确地认为将重定向到我的错误404页面是不正确的?


为什么你说它不起作用?你检查了服务器响应头吗? - Gumbo
1
回答您的结论性问题,是的,将所有404重定向到真实页面是一个不好的想法。这违反了HTTP规范,因为它将本不应存在的东西变成了存在的东西。 - Lucas Oman
11个回答

250

生成 404 页面的最新方法(适用于 PHP 5.4 或更高版本)是使用 http_response_code

<?php
http_response_code(404);
include('my_404.php'); // provide your own HTML for the error page
die();

die()不是必需的,但它确保您不会继续正常执行。


2
我应该把这个添加到哪个文件中? - Julfikar
1
@Julfikar 在你想要返回404响应的PHP文件中。例如,你的PHP文件可能有逻辑,试图从数据库中检索指定的ID。没有找到?向用户返回404“抱歉,该ID未找到”的响应。 - Harry Wood

100

你正在做的方式是可行的,浏览器将会收到404状态码。但是它不会显示你所期望的“未找到”页面,例如:

未找到

请求的URL /test.php在该服务器上未找到。

这是因为当PHP返回404状态码时(至少Apache不会),Web服务器不会发送那个页面。PHP需要负责发送所有输出内容。因此,如果您想要一个类似的页面,您需要自己发送HTML,例如:

<?php
header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found", true, 404);
include("notFound.php");
?>

你可以在httpd.conf文件中添加以下内容,让Apache使用同一个页面来显示自己的404错误信息:

ErrorDocument 404 /notFound.php

谢谢。我以为它使用了我的404页面。 - Eric
@JW 上面的代码将在哪里使用?那段代码是用于'.htaccess'文件的吗? - Manohar Kumar
@ManoharKumar 上述代码用于在您想要发送404页面的地方使用。在我的情况下,当有人搜索一个不存在的项目代码时,我会使用它。因此,在发现该项目不可用后,我使用了上述代码,并在此代码的第三行上也使用了exit,以避免在404页面之后加载任何内容。谢谢JW,它对我非常完美地起作用了。 - Harsha

30

试试这个:

<?php
header("HTTP/1.0 404 Not Found");
?>

3
HTTP 1.0和1.1中,404都代表同样的意思。选用1.0没问题。顺便说一下,这个笑话很有趣 :) 加一分。 - Ates Goral
@TheEasyLearnAcademy,那并没有什么意义...这本质上与header("Location: any-url-that-does-not-exist");相同 - 它将触发一个302(临时)重定向到一个不存在的URL,因此在重定向的(第二个)请求上生成404。您需要在当前请求上生成404响应。 - MrWhite

15

通过 .htaccess 文件创建自定义错误页面

1. 404 - 页面未找到

 RewriteEngine On
 ErrorDocument 404 /404.html

2. 500 - 内部服务器错误

RewriteEngine On
ErrorDocument 500 /500.html

3. 403 - 禁止访问

RewriteEngine On
ErrorDocument 403 /403.html

4. 400 - 错误请求

RewriteEngine On
ErrorDocument 400 /400.html

5. 401 - 需要授权

RewriteEngine On
ErrorDocument 401 /401.html

您也可以将所有错误重定向到单个页面。例如:

RewriteEngine On
ErrorDocument 404 /404.html
ErrorDocument 500 /404.html
ErrorDocument 403 /404.html
ErrorDocument 400 /404.html
ErrorDocument 401 /401.html

3
RewriteEngine与此无关;可以安全地省略该行以达到相同的结果。 - WoodrowShigeru

5

在发送头信息后,您是否记得使用die()函数? 404头信息并不会自动停止处理,因此如果有进一步的处理发生,则可能看起来没有执行任何操作。

重定向到您的404页面并不是一个好方法,但是您可以无问题地包含其内容。 这样,您就可以拥有一个正确从正确的URL发送404状态的页面,但它也为人类读者提供了“您在寻找什么?”页面。


2

标准的Apache 404错误如下所示:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
</body></html>  

因此,您可以使用以下PHP代码生成404页面,该页面看起来与标准的Apache 404页面完全相同:

function httpNotFound()
{
    http_response_code(404);
    header('Content-type: text/html');

    // Generate standard apache 404 error page
    echo <<<HTML
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
</body></html>  
HTML;

    exit;
}

0
我最喜欢的是PHP中的这个功能。
如果你需要在JavaScript中使用.statusText,最好使用这个函数。
header("HTTP/1.0 404 Not Found")

0

尝试放置

ErrorDocument 404 /(root directory)/(error file) 

.htaccess文件中。

对于任何错误都要这样做,但将404替换为您的错误。


-1
在Drupal或WordPress CMS(以及可能的其他CMS)中,如果您想让一些自定义的PHP代码不出现(除非满足某些条件),则可以通过使CMS的404处理程序接管来实现以下操作:
<?php
  if(condition){
    do stuff;
  } else {
    include('index.php');
  }
?>

-3

在那行代码之后,尝试使用exitdie()关闭响应。

header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
exit;

或者

header($_SERVER["SERVER_PROTOCOL"]." 404 Not Found");
die();

2
如果您这样做,用户会看到一个空白页面。我的问题是如何从PHP发送与“ErrorDocument”指定的相同的404页面。 - Eric
如果您想使用ErrorDocument,请确保自定义错误文件的路径是相对于服务器根目录的。例如:假设您的虚拟路径是/folder1/folder2/myhtaccess,从服务器根目录开始您的错误文档将类似于以下内容:ErrorDocument 404 /folder1/folder2/my404.html - user5891645
在输入 PHP 代码之后,ErrorDocument 就不再起作用了。这个答案 最好地解释了我9年前遇到的困惑。 - Eric
我希望你的问题现在已经解决了。离题一点,我认为最好不要使用?name=word_here进行重定向。相反,在您的page.php文件中使用 $reqpath = strtok("/".trim(substr($_SERVER["REQUEST_URI"], strlen(APP_ROOT)), "/"), "?"); 因为有一种情况是其中一个页面期望用户提供查询“名称”。 - user5891645

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接