【问题标题】:Correct PHP for a 404 redirect?404重定向的正确PHP?
【发布时间】:2011-09-15 09:40:25
【问题描述】:

我必须使用自定义 404 页面进行 url 重定向(.htaccess 不是一个选项)。我正在考虑使用下面的代码。我试图通过在 URL 中添加一个标志来解释有效的重定向,以及找不到页面的真实情况。你怎么看?

<?php

// check GET for the flag - if set we've been here before so do not redirect

if (!isset($_GET['rd'])){
    // send a 200 status message
    header($_SERVER['SERVER_PROTOCOL'] . ' 200 Ok');
    // redirect
    $url = 'new-url/based-on/some-logic.php' . '?rd=1';
    header('Location: ' . $url);
    exit;
}

// no redirection - display the 'not found' page...
?>
<html>
<head>
    <title>404 Not Found</title>
</head>
<body>
<h1>404:</h1>
<h3>Sorry, the page you have requested has not been found.</h3>
</body>
</html>

编辑 - .htaccess 不是一个选项的原因是因为我在没有 apache 的情况下在 IIS6 上运行。

【问题讨论】:

  • @hakre: o.O 正在努力解析,伙计。
  • 您确定要重定向到 404 错误处理程序中的现有文件以获取漂亮的 URL 吗?这不会模仿 URL 重写。 @tomalak:谢谢提示。
  • 您可以使用ISAPI_Rewrite 3,它将通过 .htaccess 为您的 IIS6 服务器带来 mod_rewrite 支持。它有免费的 Light 版本。

标签: php url-rewriting url-routing http-status-code-404


【解决方案1】:

添加404header代:

...
header("HTTP/1.0 404 Not Found");
// for FastCGI: header("Status: 404 Not Found");
// no redirection - display the 'not found' page...
?>
...

并删除 200 代码:

// delete this line
header($_SERVER['SERVER_PROTOCOL'] . ' 200 Ok');
// because code should be 302 for redirect
// and this code will be generated with "Location" header.

【讨论】:

  • 404 标头已由 apache 添加,因为错误处理程序调用了脚本获取。但也许 PHP 会将其转换为 2xx。好的。但是删除 200 状态对我来说似乎是多余的。它将被 PHP 删除,因为位置标头在下一行被触发。然后 PHP 会将状态设为 302。请参阅手册:php.net/manual/en/function.header.php - 那么为什么要删除 200 标头?在我看来这没有意义。
  • @hakre, 添加200 OK 状态 - 那是多余的,因为下一行(带有Location)将覆盖此状态。如果您无法理解答案中的某些内容,请不要告诉我see the manual
  • 只是为了方便而链接,但我发现它已经坏了。
  • 伙计们,我没有运行 apache,我在 IIS6 上,因此使用 404 重定向。 @OZ_ 这个练习是关于尝试模仿 mod_rewrite,所以这就是为什么我想给出 200 而不是 302 或 301。这很糟糕吗?
  • @Owen,如果没有 302 (30x) 代码,重定向就无法存在,因此您的 200 代码将被 PHP 覆盖。另外,如果你真的想模仿 mod_rewrite 行为,你应该重定向到index.php,当你找不到页面时,没有“未找到”消息和 404 代码。
【解决方案2】:

如果我没有误会,您希望为 404 页面显示一个页面,即不再存在的页面。

据我所知(可能不会太多)您不能只将 php 页面设置为没有 .htaccess 或 apache conf 文件的 404 处理程序。

我记得 404.shtml 是正常 apache 设置中 404 处理程序的默认文件,因此您需要将代码放在该页面中,

而且由于您不能使用 .htaccess 并且页面是 SHTML,因此您不能将 php 放入其中,您可以通过 Javascript 重定向从 404.shtml 到您的 404.php 来解决问题,

希望对您有所帮助。

【讨论】:

  • 在某些服务器上,您不能使用 Mod_Rewrite,但您可以设置错误页面并将其指向 PHP 脚本。然后 PHP 脚本会负责“重写”,即映射到漂亮的 URL。
  • 我没有 apache 的奢侈 - 我已经编辑了原始问题 - 很抱歉漏掉了,感谢您的贡献。
【解决方案3】:

您似乎不想重定向但要包含相关页面。重定向不是必需的。事实上,使用 apache 404 错误处理程序来处理漂亮的 url 会破坏它。

以下示例脚本首先将请求解析为(相对)文件名,即模块。在您的代码中为 new-url/based-on/some-logic.php 或类似代码。

接下来,如果找不到模块,则会使用错误页面模板。我已将其命名为 error404.php,因此您还需要创建该文件。

作为最后的手段,即使没有找到错误模板,也会返回标准的 404 错误消息。

<?php

// === resolver ===

// put your logic in here to resolve the PHP file,
// return false if there is no module for the request (404).
function resolveModule() {
  // return false;
  return 'new-url/based-on/some-logic.php';
}

// returns the filename of a module
// or false if things failed.
function resolveFile($module) {
    $status = 200;
    if (false === $module) {
        $status = 404;
        $module = 'error404.php';
    }
    // modules are files relative to current directory
    $path = realpath($module); 
    if (!file_exists($path)) {
        // hard 404 error.
        $status = 404;
        $path = false;
    }
    return array($path, $status);
}

// process the input request and resolve it
// to a file to load.
$module = resolveModule();
list($path, $status) = resolveFile($module);

// === loader ===

// send status message
header($_SERVER['SERVER_PROTOCOL'] . ' ' . $status, true, $status);

if (false !== $path) {
    include($path); // include module file (instead of redirect)
} else {
    // hard 404 error, e.g. the error page is not even found (misconfiguration)
?>
<html>
<head>
    <title>404 Not Found</title>
</head>
<body>
<h1>404:</h1>
<h3>Sorry, the page you have requested has not been found.</h3>
<p>Additionally the good looking error page is not available, so it looks really sad.</p>
</body>
</html>
<?
}

【讨论】:

  • include 无法替换 URL 调用。至少因为 URL 中的路径并不总是可以映射到脚本的路径。另外,应该调用 URL-router(在 MVC 模型中),可以使用 mod-rewrite,可以使用 URL 中的参数......不要这样做,永远不要。
  • @OZ - 我实际上认为这是一个公平的解决方案。我不明白为什么包含文件而不是重定向是一个大问题 - 在这种情况下,我认为 200 状态会很好。我的脚本用于 Wordpress 安装,我在 II6 上看到的大多数没有 apache 的 Wordpress 解决方案都包含而不是重定向。
  • @Owen 不要这样做,这真的是个大问题。再读一次我的评论。 include 永远无法替代对 URL 的重定向。这只是完全不同的事情。
  • @Owen:Wordpress 已经能够作为 404 处理程序工作,您无需添加它 AFAIK。将错误页面设置为 index.php。应该管用。参考:chrisjohnston.org/2009/setting-up-a-wordpress-blog-on-lighttpd(这是 lighttpd,但我认为您也可以使用其他服务器) - 然后您可以使用 wordpress 中的重写 API。
  • @hakre - 感谢您的链接,尽管我看不到 Wordpress index.php 如何处理 404。我会测试一下。
猜你喜欢
  • 2012-08-24
  • 1970-01-01
  • 1970-01-01
  • 2019-09-09
  • 1970-01-01
  • 2013-01-06
  • 1970-01-01
  • 2015-07-17
  • 2015-10-06
相关资源
最近更新 更多